Improve logic for turning off realtime monitoring. https://redmine.stoutner.com/issue...
authorSoren Stoutner <soren@stoutner.com>
Mon, 30 May 2022 18:15:26 +0000 (11:15 -0700)
committerSoren Stoutner <soren@stoutner.com>
Mon, 30 May 2022 18:15:26 +0000 (11:15 -0700)
app/build.gradle
app/src/main/AndroidManifest.xml
app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt
app/src/main/java/com/stoutner/privacycell/services/RealtimeMonitoringService.kt
app/src/main/java/com/stoutner/privacycell/workers/RegisterRealtimeListenerWorker.kt
app/src/main/java/com/stoutner/privacycell/workers/RestartServiceWorker.kt
app/src/main/res/layout/webview_dialog.xml
build.gradle
gradle/wrapper/gradle-wrapper.properties

index f697490d1fa9f55a6fa094e03e4bdc1e2e04d2b3..c19642c3435f50388a7279c16dbdee08ce78bb9a 100644 (file)
@@ -23,7 +23,7 @@ plugins {
 }
 
 android {
-    compileSdk 31
+    compileSdk 32
 
     defaultConfig {
         applicationId "com.stoutner.privacycell"
@@ -45,6 +45,8 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
     }
+
+    namespace 'com.stoutner.privacycell'
 }
 
 dependencies {
@@ -57,8 +59,8 @@ dependencies {
     implementation 'androidx.work:work-runtime-ktx:2.7.1'
 
     // Include the Kotlin standard library.  This should be the same version number listed in the project build.gradle.
-    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.10'
+    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21'
 
     // Include the Google material library.
-    implementation 'com.google.android.material:material:1.5.0'
+    implementation 'com.google.android.material:material:1.6.0'
 }
\ No newline at end of file
index 4deb14c892c6e639af9f0ba45986889b08945674..408848dcc8c2697bbb7674ce968d748a9ab6b3d8 100644 (file)
@@ -22,7 +22,6 @@
 <manifest
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    package="com.stoutner.privacycell"
     android:installLocation="auto" >
 
     <!-- Required to read cell network information. -->
index 86e7be51dfdec9270bd4d606cc1ee03053300d77..16772d2a5347092c00310811f435e80b50b8d2d0 100644 (file)
@@ -142,6 +142,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem
 
         // Define the phone state listener.  The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
         phoneStateListener = object : PhoneStateListener() {
+            @Deprecated("Deprecated in Java")
             @SuppressLint("SwitchIntDef")
             override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
                 // Declare the stingray dialog type integer.
@@ -261,6 +262,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem
                 }
             }
 
+            @Deprecated("Deprecated in Java")
             override fun onServiceStateChanged(serviceState: ServiceState) {
                 // Get the network registration info for the voice network, which is the second of the three entries (the first appears to be Wi-Fi and the third appears to be the cell data network).
                 val networkRegistrationInfo = serviceState.networkRegistrationInfoList[1]
index a48757f987f6cc4fc45b28e3fae6604d91a17c55..68f92284ac0194557aa22cfa4348fb3a905b6187 100644 (file)
@@ -81,163 +81,171 @@ class RealtimeMonitoringService : Service() {
         // Get a handle for the shared preferences.
         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
 
-        // Get a handle for the notification manager.
-        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+        // Check to see if realtime monitoring is enabled.  Sometimes the shared preferences can't return a value in time, because Android sucks.
+        // So, the default value is set to true, which is the safest value if the shared preferences can't be queried.
+        if (sharedPreferences.getBoolean(applicationContext.getString(R.string.realtime_monitoring_key), true)) {  // Realtime monitoring is enabled.
+            // Get a handle for the notification manager.
+            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+
+            // Create a notification channel group.
+            notificationManager.createNotificationChannelGroup(NotificationChannelGroup(REALTIME_MONITORING, getString(R.string.realtime_monitoring)))
+
+            // Prepare the notification channels.
+            val secureNetworkChannel = NotificationChannel(SECURE_NETWORK, getString(R.string.secure_network_channel), NotificationManager.IMPORTANCE_HIGH)
+            val insecureNetworkChannel = NotificationChannel(INSECURE_NETWORK, getString(R.string.insecure_network_channel), NotificationManager.IMPORTANCE_HIGH)
+            val antiquatedNetworkChannel = NotificationChannel(ANTIQUATED_NETWORK, getString(R.string.antiquated_network_channel), NotificationManager.IMPORTANCE_HIGH)
+            val unknownNetworkChannel = NotificationChannel(UNKNOWN_NETWORK, getString(R.string.unknown_network_channel), NotificationManager.IMPORTANCE_LOW)
+
+            // Set the notification channel group.
+            secureNetworkChannel.group = REALTIME_MONITORING
+            insecureNetworkChannel.group = REALTIME_MONITORING
+            antiquatedNetworkChannel.group = REALTIME_MONITORING
+            unknownNetworkChannel.group = REALTIME_MONITORING
+
+            // Disable the notification dots.
+            secureNetworkChannel.setShowBadge(false)
+            insecureNetworkChannel.setShowBadge(false)
+            antiquatedNetworkChannel.setShowBadge(false)
+            unknownNetworkChannel.setShowBadge(false)
+
+            // Set the primary channel notifications to be public.
+            secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
+            insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
+            antiquatedNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
+
+            // Create the notification channels.
+            notificationManager.createNotificationChannel(secureNetworkChannel)
+            notificationManager.createNotificationChannel(insecureNetworkChannel)
+            notificationManager.createNotificationChannel(antiquatedNetworkChannel)
+            notificationManager.createNotificationChannel(unknownNetworkChannel)
+
+            // Create a notification builder.
+            val notificationBuilder = Notification.Builder(this, UNKNOWN_NETWORK)
+
+            // Create an intent to open Privacy Cell.
+            val privacyCellIntent = Intent(this, PrivacyCellActivity::class.java)
+
+            // Create a pending intent from the Privacy Cell intent.
+            val privacyCellPendingIntent = PendingIntent.getActivity(this, 0, privacyCellIntent, PendingIntent.FLAG_IMMUTABLE)
+
+            // Set the notification to open Privacy Cell.
+            notificationBuilder.setContentIntent(privacyCellPendingIntent)
+
+            // Set the notification text.
+            notificationBuilder.setContentText(getString(R.string.unknown_network))
+
+            // Set the notification icon.
+            notificationBuilder.setSmallIcon(R.drawable.antiquated_notification_enabled)
+
+            // Set the color.
+            notificationBuilder.setColor(getColor(R.color.red_notification_icon))
+
+            // Start the foreground notification.
+            startForeground(NOTIFICATION_ID, notificationBuilder.build())
+
+            // Define the phone state listener.  The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
+            phoneStateListener = object : PhoneStateListener() {
+                @Deprecated("Deprecated in Java")
+                override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
+                    // Get the consider 3G antiquated preference.
+                    val consider3gAntiquated = sharedPreferences.getBoolean(getString(R.string.consider_3g_antiquated_key), false)
+
+                    // Populate the notification according to the network type.
+                    if ((telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_IWLAN) ||
+                        (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN)) {  // This is a secure network.
+                        // Only update the notification if the network status has changed.
+                        if (currentStatus != SECURE_NETWORK) {
+                            // Create a secure network notification builder.
+                            val secureNetworkNotificationBuilder = Notification.Builder(applicationContext, SECURE_NETWORK)
+
+                            // Set the notification to open Privacy Cell.
+                            secureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
+
+                            // Set the notification text.
+                            secureNetworkNotificationBuilder.setContentText(getString(R.string.secure_network))
+
+                            // Set the notification icon.
+                            secureNetworkNotificationBuilder.setSmallIcon(R.drawable.secure_notification_enabled)
+
+                            // Set the color.
+                            secureNetworkNotificationBuilder.setColor(getColor(R.color.blue_icon))
+
+                            // Update the notification.
+                            notificationManager.notify(NOTIFICATION_ID, secureNetworkNotificationBuilder.build())
+
+                            // Store the new network status.
+                            currentStatus = SECURE_NETWORK
+                        }
+                    } else if ((telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_LTE) || (!consider3gAntiquated && (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_1xRTT ||
+                                (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EVDO_0) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
+                                (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EVDO_B) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EHRPD) ||
+                                (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_UMTS) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_TD_SCDMA) ||
+                                (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSDPA) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSUPA) ||
+                                (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSPA) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSPAP)))) {
+                                // This is an insecure network.
+                        // Only update the notification if the network status has changed.
+                        if (currentStatus != INSECURE_NETWORK) {
+                            // Create an insecure network notification builder.
+                            val insecureNetworkNotificationBuilder = Notification.Builder(applicationContext, INSECURE_NETWORK)
+
+                            // Set the notification to open Privacy Cell.
+                            insecureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
+
+                            // Set the notification text.
+                            insecureNetworkNotificationBuilder.setContentText(getString(R.string.insecure_network))
+
+                            // Set the notification icon.
+                            insecureNetworkNotificationBuilder.setSmallIcon(R.drawable.insecure_notification_enabled)
+
+                            // Set the color.
+                            insecureNetworkNotificationBuilder.setColor(getColor(R.color.yellow_notification_icon))
+
+                            // Update the notification.
+                            notificationManager.notify(NOTIFICATION_ID, insecureNetworkNotificationBuilder.build())
+
+                            // Store the new network status.
+                            currentStatus = INSECURE_NETWORK
+                        }
+                    } else {  // This is an antiquated network.
+                        // Only update the notification if the network status has changed.
+                        if (currentStatus != ANTIQUATED_NETWORK) {
+                            // Create an antiquated network notification builder.
+                            val antiquatedNetworkNotificationBuilder = Notification.Builder(applicationContext, ANTIQUATED_NETWORK)
 
-        // Create a notification channel group.
-        notificationManager.createNotificationChannelGroup(NotificationChannelGroup(REALTIME_MONITORING, getString(R.string.realtime_monitoring)))
+                            // Set the notification to open Privacy Cell.
+                            antiquatedNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
+
+                            // Set the notification text.
+                            antiquatedNetworkNotificationBuilder.setContentText(getString(R.string.antiquated_network))
 
-        // Prepare the notification channels.
-        val secureNetworkChannel = NotificationChannel(SECURE_NETWORK, getString(R.string.secure_network_channel), NotificationManager.IMPORTANCE_HIGH)
-        val insecureNetworkChannel = NotificationChannel(INSECURE_NETWORK, getString(R.string.insecure_network_channel), NotificationManager.IMPORTANCE_HIGH)
-        val antiquatedNetworkChannel = NotificationChannel(ANTIQUATED_NETWORK, getString(R.string.antiquated_network_channel), NotificationManager.IMPORTANCE_HIGH)
-        val unknownNetworkChannel = NotificationChannel(UNKNOWN_NETWORK, getString(R.string.unknown_network_channel), NotificationManager.IMPORTANCE_LOW)
+                            // Set the notification icon.
+                            antiquatedNetworkNotificationBuilder.setSmallIcon(R.drawable.antiquated_notification_enabled)
 
-        // Set the notification channel group.
-        secureNetworkChannel.group = REALTIME_MONITORING
-        insecureNetworkChannel.group = REALTIME_MONITORING
-        antiquatedNetworkChannel.group = REALTIME_MONITORING
-        unknownNetworkChannel.group = REALTIME_MONITORING
+                            // Set the color.
+                            antiquatedNetworkNotificationBuilder.setColor(getColor(R.color.red_notification_icon))
 
-        // Disable the notification dots.
-        secureNetworkChannel.setShowBadge(false)
-        insecureNetworkChannel.setShowBadge(false)
-        antiquatedNetworkChannel.setShowBadge(false)
-        unknownNetworkChannel.setShowBadge(false)
-
-        // Set the primary channel notifications to be public.
-        secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
-        insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
-        antiquatedNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
-
-        // Create the notification channels.
-        notificationManager.createNotificationChannel(secureNetworkChannel)
-        notificationManager.createNotificationChannel(insecureNetworkChannel)
-        notificationManager.createNotificationChannel(antiquatedNetworkChannel)
-        notificationManager.createNotificationChannel(unknownNetworkChannel)
-
-        // Create a notification builder.
-        val notificationBuilder = Notification.Builder(this, UNKNOWN_NETWORK)
-
-        // Create an intent to open Privacy Cell.
-        val privacyCellIntent = Intent(this, PrivacyCellActivity::class.java)
-
-        // Create a pending intent from the Privacy Cell intent.
-        val privacyCellPendingIntent = PendingIntent.getActivity(this, 0, privacyCellIntent, PendingIntent.FLAG_IMMUTABLE)
-
-        // Set the notification to open Privacy Cell.
-        notificationBuilder.setContentIntent(privacyCellPendingIntent)
-
-        // Set the notification text.
-        notificationBuilder.setContentText(getString(R.string.unknown_network))
-
-        // Set the notification icon.
-        notificationBuilder.setSmallIcon(R.drawable.antiquated_notification_enabled)
-
-        // Set the color.
-        notificationBuilder.setColor(getColor(R.color.red_notification_icon))
-
-        // Start the foreground notification.
-        startForeground(NOTIFICATION_ID, notificationBuilder.build())
-
-        // Define the phone state listener.  The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
-        phoneStateListener = object : PhoneStateListener() {
-            override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
-                // Get the consider 3G antiquated preference.
-                val consider3gAntiquated = sharedPreferences.getBoolean(getString(R.string.consider_3g_antiquated_key), false)
-
-                // Populate the notification according to the network type.
-                if ((telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_IWLAN) ||
-                    (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN)) {  // This is a secure network.
-                    // Only update the notification if the network status has changed.
-                    if (currentStatus != SECURE_NETWORK) {
-                        // Create a secure network notification builder.
-                        val secureNetworkNotificationBuilder = Notification.Builder(applicationContext, SECURE_NETWORK)
-
-                        // Set the notification to open Privacy Cell.
-                        secureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
-
-                        // Set the notification text.
-                        secureNetworkNotificationBuilder.setContentText(getString(R.string.secure_network))
-
-                        // Set the notification icon.
-                        secureNetworkNotificationBuilder.setSmallIcon(R.drawable.secure_notification_enabled)
-
-                        // Set the color.
-                        secureNetworkNotificationBuilder.setColor(getColor(R.color.blue_icon))
-
-                        // Update the notification.
-                        notificationManager.notify(NOTIFICATION_ID, secureNetworkNotificationBuilder.build())
-
-                        // Store the new network status.
-                        currentStatus = SECURE_NETWORK
-                    }
-                } else if ((telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_LTE) || (!consider3gAntiquated && (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_1xRTT ||
-                            (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EVDO_0) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
-                            (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EVDO_B) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_EHRPD) ||
-                            (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_UMTS) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_TD_SCDMA) ||
-                            (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSDPA) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSUPA) ||
-                            (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSPA) || (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_HSPAP)))) {
-                            // This is an insecure network.
-                    // Only update the notification if the network status has changed.
-                    if (currentStatus != INSECURE_NETWORK) {
-                        // Create an insecure network notification builder.
-                        val insecureNetworkNotificationBuilder = Notification.Builder(applicationContext, INSECURE_NETWORK)
-
-                        // Set the notification to open Privacy Cell.
-                        insecureNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
-
-                        // Set the notification text.
-                        insecureNetworkNotificationBuilder.setContentText(getString(R.string.insecure_network))
-
-                        // Set the notification icon.
-                        insecureNetworkNotificationBuilder.setSmallIcon(R.drawable.insecure_notification_enabled)
-
-                        // Set the color.
-                        insecureNetworkNotificationBuilder.setColor(getColor(R.color.yellow_notification_icon))
-
-                        // Update the notification.
-                        notificationManager.notify(NOTIFICATION_ID, insecureNetworkNotificationBuilder.build())
-
-                        // Store the new network status.
-                        currentStatus = INSECURE_NETWORK
-                    }
-                } else {  // This is an antiquated network.
-                    // Only update the notification if the network status has changed.
-                    if (currentStatus != ANTIQUATED_NETWORK) {
-                        // Create an antiquated network notification builder.
-                        val antiquatedNetworkNotificationBuilder = Notification.Builder(applicationContext, ANTIQUATED_NETWORK)
-
-                        // Set the notification to open Privacy Cell.
-                        antiquatedNetworkNotificationBuilder.setContentIntent(privacyCellPendingIntent)
-
-                        // Set the notification text.
-                        antiquatedNetworkNotificationBuilder.setContentText(getString(R.string.antiquated_network))
-
-                        // Set the notification icon.
-                        antiquatedNetworkNotificationBuilder.setSmallIcon(R.drawable.antiquated_notification_enabled)
-
-                        // Set the color.
-                        antiquatedNetworkNotificationBuilder.setColor(getColor(R.color.red_notification_icon))
-
-                        // Update the notification.
-                        notificationManager.notify(NOTIFICATION_ID, antiquatedNetworkNotificationBuilder.build())
-
-                        // Store the new network status.
-                        currentStatus = ANTIQUATED_NETWORK
+                            // Update the notification.
+                            notificationManager.notify(NOTIFICATION_ID, antiquatedNetworkNotificationBuilder.build())
+
+                            // Store the new network status.
+                            currentStatus = ANTIQUATED_NETWORK
+                        }
                     }
                 }
             }
-        }
 
-        // Check to see if the read phone state permission has been granted.
-        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
-            // Create a register realtime listener work request that fires every hour.
-            // This periodic request will fire shortly after being created (it fires about every hour near the beginning of the hour) and will reregister the listener if it gets garbage collected.
-            val registerRealtimeListenerWorkRequest = PeriodicWorkRequestBuilder<RegisterRealtimeListenerWorker>(1, TimeUnit.HOURS).build()
+            // Check to see if the read phone state permission has been granted.
+            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
+                // Create a register realtime listener work request that fires every hour.
+                // This periodic request will fire shortly after being created (it fires about every hour near the beginning of the hour) and will reregister the listener if it gets garbage collected.
+                val registerRealtimeListenerWorkRequest = PeriodicWorkRequestBuilder<RegisterRealtimeListenerWorker>(1, TimeUnit.HOURS).build()
 
-            // Register the realtime listener work request.
-            WorkManager.getInstance(this).enqueueUniquePeriodicWork(getString(R.string.register_listener_work_request), ExistingPeriodicWorkPolicy.REPLACE, registerRealtimeListenerWorkRequest)
+                // Register the realtime listener work request.
+                WorkManager.getInstance(this).enqueueUniquePeriodicWork(getString(R.string.register_listener_work_request), ExistingPeriodicWorkPolicy.REPLACE, registerRealtimeListenerWorkRequest)
+            }
+        } else {  // Realtime monitoring is disabled.  This can happen if the restart listener work request fires after realtime monitoring has been disabled.
+            // Cancel the realtime listener work request.
+            WorkManager.getInstance(applicationContext).cancelUniqueWork(applicationContext.getString(R.string.register_listener_work_request))
         }
 
         // Return a sticky service.
index 7fe86d028b06ede04598f9bff6f24642cb06b851..6bb76add73692863138dcc4930427af3a1af7239 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
  *
@@ -46,11 +46,12 @@ class RegisterRealtimeListenerWorker(appContext: Context, workerParameters: Work
         val realtimeMonitoring = sharedPreferences.getBoolean(applicationContext.getString(R.string.realtime_monitoring_key), true)
 
         // Perform the functions according to the realtime monitoring status.
+        @Suppress("DEPRECATION")  // The deprecated `getRunningServices()` now only returns services started by Privacy Cell, but that is all we want to know anyway.
         if (realtimeMonitoring) {  // Realtime monitoring is enabled.
             // Get a handle for the activity manager.
             val activityManager: ActivityManager = applicationContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
 
-            // Get a list of the running service info.  The deprecated `getRunningServices()` now only returns services stared by Privacy Cell, but that is all we want to know anyway.
+            // Get a list of the running service info.  The deprecated `getRunningServices()` now only returns services started by Privacy Cell, but that is all we want to know anyway.
             val runningServiceInfoList: List<ActivityManager.RunningServiceInfo> = activityManager.getRunningServices(1)
 
             // Check to see if the service is currently running.
@@ -89,6 +90,9 @@ class RegisterRealtimeListenerWorker(appContext: Context, workerParameters: Work
                 applicationContext.bindService(Intent(applicationContext, RealtimeMonitoringService::class.java), serviceConnection, 0)
             }
         } else {  // Realtime monitoring is disabled.
+            // Stop the realtime monitoring service.
+            applicationContext.stopService(Intent(applicationContext, RealtimeMonitoringService::class.java))
+
             // Cancel the realtime listener work request.
             WorkManager.getInstance(applicationContext).cancelUniqueWork(applicationContext.getString(R.string.register_listener_work_request))
         }
index 64b4eca93811a434e1e2d55349b18b1b2af16805..720ca7a937353ac758216d94250cc559904be230 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
  *
@@ -22,14 +22,31 @@ package com.stoutner.privacycell.workers
 import android.content.Context
 import android.content.Intent
 
+import androidx.preference.PreferenceManager
+import androidx.work.WorkManager
 import androidx.work.Worker
 import androidx.work.WorkerParameters
+
+import com.stoutner.privacycell.R
 import com.stoutner.privacycell.services.RealtimeMonitoringService
 
 class RestartServiceWorker(appContext: Context, workerParameters: WorkerParameters) : Worker(appContext, workerParameters) {
     override fun doWork(): Result {
-        // Start the realtime monitoring service as a foreground service, which is required because the worker is running in the background.
-        applicationContext.startForegroundService(Intent(applicationContext, RealtimeMonitoringService::class.java))
+        // Get a handle for the shared preferences.
+        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
+
+        // Check to see if realtime monitoring is enabled.  Sometimes the shared preferences can't return a value in time, because Android sucks.
+        // So, the default value is set to true, which is the safest value if the shared preferences can't be queried.
+        if (sharedPreferences.getBoolean(applicationContext.getString(R.string.realtime_monitoring_key), true)) {  // Realtime monitoring is enabled.
+            // Start the realtime monitoring service as a foreground service, which is required because the worker is running in the background.
+            applicationContext.startForegroundService(Intent(applicationContext, RealtimeMonitoringService::class.java))
+        } else {  // Realtime monitoring is disabled.
+            // Stop the realtime monitoring service.
+            applicationContext.stopService(Intent(applicationContext, RealtimeMonitoringService::class.java))
+
+            // Cancel the realtime listener work request.
+            WorkManager.getInstance(applicationContext).cancelUniqueWork(applicationContext.getString(R.string.register_listener_work_request))
+        }
 
         // Return a success.
         return Result.success()
index d585bb031261cb96077f84e7cd05ebe0dc37c20f..aeb1f4f070211b40f7b15cf1aa2d8fd00786d532 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
 
@@ -29,6 +29,6 @@
 
     <WebView
         android:id="@+id/webview"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content" />
+        android:layout_height="match_parent"
+        android:layout_width="match_parent" />
 </LinearLayout>
\ No newline at end of file
index 9c60970b2b7001c29967ea71e685f3c44609e353..a994e46b72bdbe4886483096427077c47d6fab2a 100644 (file)
@@ -25,8 +25,8 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:7.1.2'
-        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
+        classpath 'com.android.tools.build:gradle:7.2.1'
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
index 7d897f9222026aa4b3bdb80c397c341d1c2d2242..6f4d99208b8e21d06da0e9f4c25276a023cda0dc 100644 (file)
@@ -1,6 +1,6 @@
 #Thu Aug 12 09:15:13 MST 2021
 distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
 distributionPath=wrapper/dists
 zipStorePath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME