diff --git a/android/app/src/main/java/com/vernu/sms/AppConstants.java b/android/app/src/main/java/com/vernu/sms/AppConstants.java
index f7d0d2e..f3f6cb7 100644
--- a/android/app/src/main/java/com/vernu/sms/AppConstants.java
+++ b/android/app/src/main/java/com/vernu/sms/AppConstants.java
@@ -18,4 +18,5 @@ public class AppConstants {
public static final String SHARED_PREFS_TRACK_SENT_SMS_STATUS_KEY = "TRACK_SENT_SMS_STATUS";
public static final String SHARED_PREFS_LAST_VERSION_CODE_KEY = "LAST_VERSION_CODE";
public static final String SHARED_PREFS_LAST_VERSION_NAME_KEY = "LAST_VERSION_NAME";
+ public static final String SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY = "STICKY_NOTIFICATION_ENABLED";
}
diff --git a/android/app/src/main/java/com/vernu/sms/TextBeeUtils.java b/android/app/src/main/java/com/vernu/sms/TextBeeUtils.java
index db6264b..6e708de 100644
--- a/android/app/src/main/java/com/vernu/sms/TextBeeUtils.java
+++ b/android/app/src/main/java/com/vernu/sms/TextBeeUtils.java
@@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat;
import com.google.firebase.crashlytics.FirebaseCrashlytics;
import com.vernu.sms.services.StickyNotificationService;
+import com.vernu.sms.helpers.SharedPreferenceHelper;
import java.util.ArrayList;
import java.util.List;
@@ -38,22 +39,34 @@ public class TextBeeUtils {
}
public static void startStickyNotificationService(Context context) {
-
if(!isPermissionGranted(context, Manifest.permission.RECEIVE_SMS)){
return;
}
-
- Intent notificationIntent = new Intent(context, StickyNotificationService.class);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- context.startForegroundService(notificationIntent);
+
+ // Only start service if user has enabled sticky notification
+ boolean stickyNotificationEnabled = SharedPreferenceHelper.getSharedPreferenceBoolean(
+ context,
+ AppConstants.SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY,
+ false
+ );
+
+ if (stickyNotificationEnabled) {
+ Intent notificationIntent = new Intent(context, StickyNotificationService.class);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ context.startForegroundService(notificationIntent);
+ } else {
+ context.startService(notificationIntent);
+ }
+ Log.i(TAG, "Starting sticky notification service");
} else {
- context.startService(notificationIntent);
+ Log.i(TAG, "Sticky notification disabled by user, not starting service");
}
}
public static void stopStickyNotificationService(Context context) {
Intent notificationIntent = new Intent(context, StickyNotificationService.class);
context.stopService(notificationIntent);
+ Log.i(TAG, "Stopping sticky notification service");
}
/**
diff --git a/android/app/src/main/java/com/vernu/sms/activities/MainActivity.java b/android/app/src/main/java/com/vernu/sms/activities/MainActivity.java
index 6cf93bd..0e43052 100644
--- a/android/app/src/main/java/com/vernu/sms/activities/MainActivity.java
+++ b/android/app/src/main/java/com/vernu/sms/activities/MainActivity.java
@@ -42,7 +42,7 @@ import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
private Context mContext;
- private Switch gatewaySwitch, receiveSMSSwitch;
+ private Switch gatewaySwitch, receiveSMSSwitch, stickyNotificationSwitch;
private EditText apiKeyEditText, fcmTokenEditText, deviceIdEditText;
private Button registerDeviceBtn, grantSMSPermissionBtn, scanQRBtn, checkUpdatesBtn;
private ImageButton copyDeviceIdImgBtn;
@@ -62,6 +62,7 @@ public class MainActivity extends AppCompatActivity {
setContentView(R.layout.activity_main);
gatewaySwitch = findViewById(R.id.gatewaySwitch);
receiveSMSSwitch = findViewById(R.id.receiveSMSSwitch);
+ stickyNotificationSwitch = findViewById(R.id.stickyNotificationSwitch);
apiKeyEditText = findViewById(R.id.apiKeyEditText);
fcmTokenEditText = findViewById(R.id.fcmTokenEditText);
deviceIdEditText = findViewById(R.id.deviceIdEditText);
@@ -98,6 +99,14 @@ public class MainActivity extends AppCompatActivity {
crashlytics.setCustomKey("app_version", versionName);
crashlytics.setCustomKey("app_version_code", BuildConfig.VERSION_CODE);
+ // Start sticky notification service if enabled
+ boolean gatewayEnabled = SharedPreferenceHelper.getSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_GATEWAY_ENABLED_KEY, false);
+ boolean stickyNotificationEnabled = SharedPreferenceHelper.getSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY, false);
+ if (gatewayEnabled && stickyNotificationEnabled) {
+ TextBeeUtils.startStickyNotificationService(mContext);
+ Log.d(TAG, "Starting sticky notification service on app start");
+ }
+
if (deviceId == null || deviceId.isEmpty()) {
registerDeviceBtn.setText("Register");
} else {
@@ -150,11 +159,14 @@ public class MainActivity extends AppCompatActivity {
SharedPreferenceHelper.setSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_GATEWAY_ENABLED_KEY, isCheked);
boolean enabled = Boolean.TRUE.equals(Objects.requireNonNull(response.body()).data.get("enabled"));
compoundButton.setChecked(enabled);
-// if (enabled) {
-// TextBeeUtils.startStickyNotificationService(mContext);
-// } else {
-// TextBeeUtils.stopStickyNotificationService(mContext);
-// }
+ if (enabled) {
+ // Check if sticky notification is enabled
+ if (SharedPreferenceHelper.getSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY, false)) {
+ TextBeeUtils.startStickyNotificationService(mContext);
+ }
+ } else {
+ TextBeeUtils.stopStickyNotificationService(mContext);
+ }
compoundButton.setEnabled(true);
}
@Override
@@ -176,6 +188,21 @@ public class MainActivity extends AppCompatActivity {
Snackbar.make(view, "Receive SMS " + (isCheked ? "enabled" : "disabled"), Snackbar.LENGTH_LONG).show();
});
+ // Setup sticky notification switch
+ stickyNotificationSwitch.setChecked(SharedPreferenceHelper.getSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY, false));
+ stickyNotificationSwitch.setOnCheckedChangeListener((compoundButton, isChecked) -> {
+ View view = compoundButton.getRootView();
+ SharedPreferenceHelper.setSharedPreferenceBoolean(mContext, AppConstants.SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY, isChecked);
+
+ if (isChecked) {
+ TextBeeUtils.startStickyNotificationService(mContext);
+ Snackbar.make(view, "Background service enabled - app will be more reliable", Snackbar.LENGTH_LONG).show();
+ } else {
+ TextBeeUtils.stopStickyNotificationService(mContext);
+ Snackbar.make(view, "Background service disabled - app may be killed when in background", Snackbar.LENGTH_LONG).show();
+ }
+ });
+
// TODO: check gateway status/api key/device validity and update UI accordingly
registerDeviceBtn.setOnClickListener(view -> {
String _deviceId = SharedPreferenceHelper.getSharedPreferenceString(mContext, AppConstants.SHARED_PREFS_DEVICE_ID_KEY, "");
diff --git a/android/app/src/main/java/com/vernu/sms/services/StickyNotificationService.java b/android/app/src/main/java/com/vernu/sms/services/StickyNotificationService.java
index b320563..6a82579 100644
--- a/android/app/src/main/java/com/vernu/sms/services/StickyNotificationService.java
+++ b/android/app/src/main/java/com/vernu/sms/services/StickyNotificationService.java
@@ -15,6 +15,8 @@ import androidx.core.app.NotificationCompat;
import com.vernu.sms.R;
import com.vernu.sms.activities.MainActivity;
import com.vernu.sms.receivers.SMSBroadcastReceiver;
+import com.vernu.sms.AppConstants;
+import com.vernu.sms.helpers.SharedPreferenceHelper;
public class StickyNotificationService extends Service {
@@ -32,15 +34,25 @@ public class StickyNotificationService extends Service {
super.onCreate();
Log.i(TAG, "Service Started");
+ // Only register receiver and show notification if enabled in preferences
+ boolean stickyNotificationEnabled = SharedPreferenceHelper.getSharedPreferenceBoolean(
+ getApplicationContext(),
+ AppConstants.SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY,
+ false
+ );
-// IntentFilter filter = new IntentFilter();
-// filter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
-// filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
-// registerReceiver(receiver, filter);
-//
-// Notification notification = createNotification();
-// startForeground(1, notification);
+ if (stickyNotificationEnabled) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
+ filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
+ registerReceiver(receiver, filter);
+ Notification notification = createNotification();
+ startForeground(1, notification);
+ Log.i(TAG, "Started foreground service with sticky notification");
+ } else {
+ Log.i(TAG, "Sticky notification disabled by user preference");
+ }
}
@Override
@@ -52,9 +64,19 @@ public class StickyNotificationService extends Service {
@Override
public void onDestroy() {
super.onDestroy();
-// unregisterReceiver(receiver);
+
+ // Only unregister if we had registered in the first place
+ boolean stickyNotificationEnabled = SharedPreferenceHelper.getSharedPreferenceBoolean(
+ getApplicationContext(),
+ AppConstants.SHARED_PREFS_STICKY_NOTIFICATION_ENABLED_KEY,
+ false
+ );
+
+ if (stickyNotificationEnabled) {
+ unregisterReceiver(receiver);
+ }
+
Log.i(TAG, "StickyNotificationService destroyed");
-// Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show();
}
private Notification createNotification() {
@@ -72,10 +94,19 @@ public class StickyNotificationService extends Service {
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this, notificationChannelId);
- return builder.setContentTitle("TextBee is running").setContentText("TextBee is running in the background.").setContentIntent(pendingIntent).setOngoing(true).setSmallIcon(R.drawable.ic_launcher_foreground).build();
+ return builder.setContentTitle("TextBee Active")
+ .setContentText("SMS gateway service is active")
+ .setContentIntent(pendingIntent)
+ .setOngoing(true)
+ .setSmallIcon(R.mipmap.ic_launcher)
+ .build();
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, notificationChannelId);
- return builder.setContentTitle("TextBee is running").setContentText("TextBee is running in the background.").setOngoing(true).setSmallIcon(R.drawable.ic_launcher_foreground).build();
+ return builder.setContentTitle("TextBee Active")
+ .setContentText("SMS gateway service is active")
+ .setOngoing(true)
+ .setSmallIcon(R.mipmap.ic_launcher)
+ .build();
}
}
diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml
index 55d25ae..7cd04fb 100644
--- a/android/app/src/main/res/layout/activity_main.xml
+++ b/android/app/src/main/res/layout/activity_main.xml
@@ -371,6 +371,57 @@
android:minHeight="32dp" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+