Skip to content

Commit

Permalink
Dual sim support for Android 5.1+ (fixes #9 and #23)
Browse files Browse the repository at this point in the history
  • Loading branch information
David Vávra committed Feb 1, 2016
1 parent 40aa35e commit 1813109
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 125 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# Settings specified in this file will override any Gradle settings
# configured through the IDE.

VERSION = 3.3.1
VERSION = 3.4.0
MIN_SDK = 10
TARGET_SDK = 22
INITIAL_VERSION_CODE = 300180
Expand Down
Binary file added meta/screenshots/en/6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions mobile/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- only for LG Optimus Black, because of bug:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
-->
<!-- for multi-sim support -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<supports-screens
android:anyDensity="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@
import eu.inmite.apps.smsjizdenka.data.model.City;
import eu.inmite.apps.smsjizdenka.data.model.CityManager;
import eu.inmite.apps.smsjizdenka.data.model.Ticket;
import eu.inmite.apps.smsjizdenka.dialog.*;
import eu.inmite.apps.smsjizdenka.dialog.BuyTicketConfirmationDialogFragment;
import eu.inmite.apps.smsjizdenka.dialog.EulaDialogFragment;
import eu.inmite.apps.smsjizdenka.dialog.IncompatibleDialogFragment;
import eu.inmite.apps.smsjizdenka.dialog.MessageDialogFragment;
import eu.inmite.apps.smsjizdenka.dialog.SimDialogFragment;
import eu.inmite.apps.smsjizdenka.fragment.AboutFragment;
import eu.inmite.apps.smsjizdenka.fragment.SettingsFragment;
import eu.inmite.apps.smsjizdenka.fragment.StatisticsFragment;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public class Preferences {
public static final String PREFILL_SMS = "prefill_sms";
public static final String EULA_CONFIRMED = "eula";
public static final String MESSAGE_READ = "message_read";
public static final String DUALSIM_SIM = "sim";

public static final int VALUE_DEFAULT_SIM = -1;


public static int getInt(Context c, String key, int defaultValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected Builder build(Builder builder) {
builder.setPositiveButton(R.string.cities_buy_ticket, new View.OnClickListener() {
@Override
public void onClick(View view) {
BuyTicketDialogFragment.orderNewTicket(city, getActivity(), "buy-ticket-confirmation-dialog");
BuyTicketDialogFragment.orderNewTicket(city, getActivity());
dismiss();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@

package eu.inmite.apps.smsjizdenka.dialog;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.telephony.SmsManager;
import android.text.format.Time;
import android.view.View;
Expand All @@ -32,7 +36,6 @@
import eu.inmite.apps.smsjizdenka.activity.MainActivity;
import eu.inmite.apps.smsjizdenka.adapter.CityTicketsAdapter;
import eu.inmite.apps.smsjizdenka.core.Constants;
import eu.inmite.apps.smsjizdenka.core.ProjectBaseActivity;
import eu.inmite.apps.smsjizdenka.data.Preferences;
import eu.inmite.apps.smsjizdenka.data.TicketProvider.Tickets;
import eu.inmite.apps.smsjizdenka.data.model.City;
Expand Down Expand Up @@ -62,21 +65,24 @@ public static BuyTicketDialogFragment newInstance(long cityId) {
/**
* Order ticket in new thread.
*/
public static synchronized void orderNewTicket(final City city, final Activity c, String analyticsSource) {
public static synchronized void orderNewTicket(final City city, final Context context) {
if (city == null) {
return;
}
// make sure sms cannot be saved twice
Preferences.set(c, Preferences.LAST_ORDER_TIME, System.currentTimeMillis());
//SL.get(AnalyticsService.class).trackEvent("order-ticket", analyticsSource, "city", city.city, "price", city.price);
Preferences.set(context, Preferences.LAST_ORDER_TIME, System.currentTimeMillis());

if (Preferences.getBoolean(c, Preferences.PREFILL_SMS, false)) {
if (Preferences.getBoolean(context, Preferences.PREFILL_SMS, false)) {
// prefill SMS
final Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + city.number));
i.putExtra("sms_body", city.request);
c.startActivity(i);
if (!(context instanceof Activity)) {
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(i);
} else {
new Thread(new Runnable() {
@SuppressLint("NewApi")
@Override
public void run() {

Expand All @@ -91,29 +97,36 @@ public void run() {
cv.put(Tickets.CITY, city.city);
cv.put(Tickets.CITY_ID, city.id);
cv.put(Tickets.STATUS, Tickets.STATUS_WAITING);
final Uri uri = c.getContentResolver().insert(Tickets.CONTENT_URI, cv);
final Uri uri = context.getContentResolver().insert(Tickets.CONTENT_URI, cv);

// send SMS directly
final SmsManager sm = SmsManager.getDefault();
SmsManager sm;
int simId = Integer.parseInt(Preferences.getString(App.getInstance(), Preferences.DUALSIM_SIM, String.valueOf(Preferences
.VALUE_DEFAULT_SIM)));
if (simId == Preferences.VALUE_DEFAULT_SIM) {
sm = SmsManager.getDefault();
} else {
sm = SmsManager.getSmsManagerForSubscriptionId(simId);
}
final Intent sentIntent = new Intent(SmsSent.INTENT_SMS_SENT);
sentIntent.putExtra("uri", uri);
sentIntent.putExtra("NUMBER", city.number);
sentIntent.putExtra("MESSAGE", city.request);
final PendingIntent sent = PendingIntent.getBroadcast(c, Constants.BROADCAST_SMS_SENT, sentIntent, PendingIntent.FLAG_ONE_SHOT);
final PendingIntent sent = PendingIntent.getBroadcast(context, Constants.BROADCAST_SMS_SENT, sentIntent, PendingIntent.FLAG_ONE_SHOT);

final Intent deliveredIntent = new Intent(SmsDelivered.INTENT_SMS_DELIVERED);
deliveredIntent.putExtra("uri", uri);
final PendingIntent delivered = PendingIntent.getBroadcast(c, Constants.BROADCAST_SMS_DELIVERED, deliveredIntent,
final PendingIntent delivered = PendingIntent.getBroadcast(context, Constants.BROADCAST_SMS_DELIVERED, deliveredIntent,
PendingIntent.FLAG_ONE_SHOT);
try {
// most sensitive line of the entire app:
sm.sendTextMessage(city.number, null, city.request, sent, delivered);
} catch (SecurityException e) {
// LG Optimus Black needs READ_PHONE_STATE permission
((ProjectBaseActivity)c).runOnUiThread(new Runnable() {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(c, R.string.msg_sms_sent_error_generic, Toast.LENGTH_SHORT).show();
Toast.makeText(context, R.string.msg_sms_sent_error_generic, Toast.LENGTH_SHORT).show();
}
});
}
Expand All @@ -135,7 +148,7 @@ public void onClick(View view) {
if (isBoughtRecently()) {
NotificationUtil.notifyVerification(App.getInstance(), city);
} else {
orderNewTicket(city, getActivity(), "buy-ticket-dialog");
orderNewTicket(city, getActivity());
}
if (!Preferences.getBoolean(App.getInstance(), Preferences.PREFILL_SMS, false)) {
startBackActivity(MainActivity.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

package eu.inmite.apps.smsjizdenka.fragment;

import java.util.ArrayList;
import java.util.List;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
Expand All @@ -25,10 +29,13 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
Expand Down Expand Up @@ -56,6 +63,9 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
updateRingtoneSummary(getPreferenceScreen());
} else if (key.equals(Preferences.DATA_VERSION)) {
updateDataVersion(getPreferenceScreen());
} else if (key.equals(Preferences.DUALSIM_SIM)) {
ListPreference preference = (ListPreference) getPreferenceScreen().findPreference(Preferences.DUALSIM_SIM);
preference.setSummary(preference.getEntry());
}
}
};
Expand All @@ -75,7 +85,7 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((ProjectBaseActivity)getActivity()).getSupportActionBar().setTitle(R.string.ab_menu_settings);
((ProjectBaseActivity) getActivity()).getSupportActionBar().setTitle(R.string.ab_menu_settings);
PreferenceManager.getDefaultSharedPreferences(mContext).registerOnSharedPreferenceChangeListener(listener);
}

Expand Down Expand Up @@ -104,9 +114,36 @@ public boolean onPreferenceClick(Preference preference) {
updateDataVersion(preferenceScreen);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
PreferenceCategory pref = (PreferenceCategory)preferenceScreen.findPreference("ticket_category");
PreferenceCategory pref = (PreferenceCategory) preferenceScreen.findPreference("sms_category");
pref.removePreference(pref.findPreference(Preferences.KEEP_IN_MESSAGING));
}
boolean dualSim = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1 && SubscriptionManager.from(getActivity()).getActiveSubscriptionInfoCount() >= 2;
if (!dualSim) {
PreferenceCategory pref = (PreferenceCategory) preferenceScreen.findPreference("sms_category");
pref.removePreference(pref.findPreference(Preferences.DUALSIM_SIM));
} else {
fillDualSimList(preferenceScreen);
}
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
private void fillDualSimList(PreferenceScreen preferenceScreen) {
PreferenceCategory category = (PreferenceCategory) preferenceScreen.findPreference("sms_category");
ListPreference preference = (ListPreference) category.findPreference(Preferences.DUALSIM_SIM);
List<String> simIds = new ArrayList<>();
List<String> simNames = new ArrayList<>();
simIds.add(String.valueOf(Preferences.VALUE_DEFAULT_SIM));
simNames.add(getString(R.string.sim_default));
SubscriptionManager subscriptionManager = SubscriptionManager.from(getActivity());
for (SubscriptionInfo subscriptionInfo : subscriptionManager.getActiveSubscriptionInfoList()) {
simIds.add(String.valueOf(subscriptionInfo.getSubscriptionId()));
simNames.add(getString(R.string.sim_name, subscriptionInfo.getSimSlotIndex() + 1, subscriptionInfo
.getDisplayName()));
}
preference.setEntries(simNames.toArray(new String[simNames.size()]));
preference.setEntryValues(simIds.toArray(new String[simIds.size()]));
preference.setDefaultValue(String.valueOf(Preferences.VALUE_DEFAULT_SIM));
preference.setSummary(preference.getEntry());
}

private void updateRingtoneSummary(PreferenceScreen preferenceScreen) {
Expand All @@ -123,7 +160,7 @@ private void updateRingtoneSummary(PreferenceScreen preferenceScreen) {
preferenceScreen.findPreference(Preferences.NOTIFICATION_RINGTONE).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String v = (String)newValue;
String v = (String) newValue;
preference.setSummary(v);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,27 @@

package eu.inmite.apps.smsjizdenka.service;

import java.util.*;
import java.util.ArrayList;
import java.util.List;

import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.text.format.Time;

import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.mariux.teleport.lib.TeleportService;

import eu.inmite.apps.smsjizdenka.R;
import eu.inmite.apps.smsjizdenka.activity.MainActivity;
import eu.inmite.apps.smsjizdenka.core.Constants;
import eu.inmite.apps.smsjizdenka.data.Preferences;
import eu.inmite.apps.smsjizdenka.data.TicketProvider;
import eu.inmite.apps.smsjizdenka.data.model.City;
import eu.inmite.apps.smsjizdenka.data.model.CityManager;
import eu.inmite.apps.smsjizdenka.data.model.Ticket;
import eu.inmite.apps.smsjizdenka.dialog.BuyTicketDialogFragment;
import eu.inmite.apps.smsjizdenka.framework.DebugLog;
import eu.inmite.apps.smsjizdenka.receiver.SmsDelivered;
import eu.inmite.apps.smsjizdenka.receiver.SmsSent;

/**
* Service for communication with wear device.
Expand Down Expand Up @@ -179,12 +172,9 @@ private void syncTicketsToWear(String path) {

private void sentTicket(String path) {
Uri uri = Uri.parse(path);
final ArrayList<DataMap> dataCities = new ArrayList<DataMap>();
long cityId = Long.parseLong(uri.getLastPathSegment());

City city = CityManager.get(getApplicationContext()).getCity(getApplicationContext(), cityId);
//addTestingTicket();
orderNewTicket(city);
BuyTicketDialogFragment.orderNewTicket(city, getApplicationContext());

}

Expand All @@ -206,91 +196,6 @@ private void sendSmsNotification(Ticket t, int status) {
syncDataItem(data);
}

/**
* Order ticket in new thread.
*/
public synchronized void orderNewTicket(final City city) {
if (city == null) {
return;
}
// make sure sms cannot be saved twice
Preferences.set(getApplication(), Preferences.LAST_ORDER_TIME, System.currentTimeMillis());
//SL.get(AnalyticsService.class).trackEvent("order-ticket", analyticsSource, "city", city.city, "price", city.price);

new Thread(new Runnable() {
@Override
public void run() {

Time now = new Time();
now.setToNow();
now.switchTimezone(Time.getCurrentTimezone());

final ContentValues cv = new ContentValues();
cv.put(TicketProvider.Tickets.ORDERED, now.format3339(false));
cv.put(TicketProvider.Tickets.VALID_TO, now.format3339(false));
cv.put(TicketProvider.Tickets.VALID_TO_DATE, Long.MAX_VALUE);
cv.put(TicketProvider.Tickets.CITY, city.city);
cv.put(TicketProvider.Tickets.CITY_ID, city.id);
cv.put(TicketProvider.Tickets.STATUS, TicketProvider.Tickets.STATUS_WAITING);
final Uri uri = getApplicationContext().getContentResolver().insert(TicketProvider.Tickets.CONTENT_URI, cv);

// send SMS directly
final SmsManager sm = SmsManager.getDefault();
final Intent sentIntent = new Intent(SmsSent.INTENT_SMS_SENT);
sentIntent.putExtra("uri", uri);
sentIntent.putExtra("NUMBER", city.number);
sentIntent.putExtra("MESSAGE", city.request);
final PendingIntent sent = PendingIntent.getBroadcast(getApplicationContext(), Constants.BROADCAST_SMS_SENT,
sentIntent, PendingIntent.FLAG_ONE_SHOT);

final Intent deliveredIntent = new Intent(SmsDelivered.INTENT_SMS_DELIVERED);
deliveredIntent.putExtra("uri", uri);
final PendingIntent delivered = PendingIntent.getBroadcast(getApplicationContext(), Constants.BROADCAST_SMS_DELIVERED,
deliveredIntent,
PendingIntent.FLAG_ONE_SHOT);
try {
// most sensitive line of the entire app:
sm.sendTextMessage(city.number, null, city.request, sent, delivered);
} catch (SecurityException e) {
// LG Optimus Black needs READ_PHONE_STATE permission

}

}
}).start();
}

private void addTestingTicket() {
Ticket ticket = new Ticket();
if (Locale.getDefault().toString().startsWith("en")) {
ticket.setCity("Prague");
} else {
ticket.setCity("Praha");
}
ticket.setCityId(1);
ticket.setHash("bhAJpWP9B / 861418");
ticket.setStatus(TicketProvider.Tickets.STATUS_DELIVERED);
ticket.setText("DP hl.m.Prahy, a.s., Jizdenka prestupni 32,- Kc, Platnost od: 29.8.11 8:09 do: 29.8.11 9:39. Pouze v pasmu P. WzL9n3JuQ /" +
" " +
"169605");
int second = 1000;
int minute = 60 * second;
int hour = 60 * minute;
int day = 24 * hour;
Time time = new Time();
time.setToNow();
ticket.setOrdered(time);
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.SECOND, 0);
long nowFullMinute = calendar.getTimeInMillis();
time.set(nowFullMinute);
ticket.setValidFrom(time);
Time time2 = new Time();
time2.set(nowFullMinute + 12 * minute);
ticket.setValidTo(time2);
SmsReceiverService.call(getApplicationContext(), ticket);
}

private void openTicketInPhone(String path) {
DebugLog.e("test");
Uri uri = Uri.parse(path);
Expand Down
Loading

0 comments on commit 1813109

Please sign in to comment.