Make some progress on fixing realtime notifications.
[PrivacyCell.git] / app / src / main / java / com / stoutner / privacycell / services / RealtimeMonitoringService.kt
index dc5b49483425cc043c238790452d5d48c4899259..2d3b184abb3f56bad08b6fb3b65091b245ca285f 100644 (file)
@@ -27,28 +27,45 @@ import android.app.PendingIntent
 import android.app.Service
 import android.content.Context
 import android.content.Intent
+import android.os.Binder
 import android.os.IBinder
 import android.telephony.PhoneStateListener
 import android.telephony.TelephonyDisplayInfo
 import android.telephony.TelephonyManager
 
+import androidx.work.ExistingPeriodicWorkPolicy
+import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.WorkManager
+
 import com.stoutner.privacycell.R
 import com.stoutner.privacycell.activities.PrivacyCellActivity
+import com.stoutner.privacycell.workers.RegisterRealtimeListener
+
+import java.util.concurrent.TimeUnit
 
 // Define the class constants.
 const val REALTIME_MONITORING = "realtime_monitoring"
 const val NOTIFICATION_ID = 1
+const val UNKNOWN_NETWORK = "unknown_network"
 
 class RealtimeMonitoringService : Service() {
     companion object {
-        // Define the public constants.
+        // Define the public constants.  These are used in the settings fragment to launch intents to edit the sound that plays for each channel.
         const val SECURE_NETWORK = "secure_network"
         const val INSECURE_NETWORK = "insecure_network"
     }
 
-    override fun onBind(intent: Intent?): IBinder? {
-        // Do nothing.
-        return null
+    // Define the class variables.
+    private var currentStatus = ""
+
+    inner class ServiceBinder : Binder() {
+        // Get a copy of this service as a binder.
+        fun getService(): RealtimeMonitoringService = this@RealtimeMonitoringService
+    }
+
+    override fun onBind(intent: Intent): IBinder {
+        // Return a copy of the service binder.
+        return ServiceBinder()
     }
 
     override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
@@ -59,27 +76,31 @@ class RealtimeMonitoringService : Service() {
         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_DEFAULT)
-        val insecureNetworkChannel = NotificationChannel(INSECURE_NETWORK, getString(R.string.insecure_network_channel), NotificationManager.IMPORTANCE_DEFAULT)
+        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 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
+        unknownNetworkChannel.group = REALTIME_MONITORING
 
         // Disable the notification dots.
         secureNetworkChannel.setShowBadge(false)
         insecureNetworkChannel.setShowBadge(false)
+        unknownNetworkChannel.setShowBadge(false)
 
-        // Set the notifications to be public.
+        // Set the notifications to be public for the secure and insecure networks.
         secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
         insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
 
         // Create the notification channels.
         notificationManager.createNotificationChannel(secureNetworkChannel)
         notificationManager.createNotificationChannel(insecureNetworkChannel)
+        notificationManager.createNotificationChannel(unknownNetworkChannel)
 
         // Create a notification builder.
-        val notificationBuilder = Notification.Builder(this, INSECURE_NETWORK)
+        val notificationBuilder = Notification.Builder(this, UNKNOWN_NETWORK)
 
         // Create an intent to open Privacy Cell.
         val privacyCellIntent = Intent(this, PrivacyCellActivity::class.java)
@@ -102,11 +123,31 @@ class RealtimeMonitoringService : Service() {
         // Start the foreground notification.
         startForeground(NOTIFICATION_ID, notificationBuilder.build())
 
-        // Get a handle for the telephony manager and the context.
+        // Register the telephony manager listener.
+        registerTelephonyManagerListener()
+
+        // Create a register realtime listener work request that fires every 15 minutes with a 1 minute initial delay.
+        val registerRealtimeListenerWorkRequest = PeriodicWorkRequestBuilder<RegisterRealtimeListener>(15, TimeUnit.MINUTES).setInitialDelay(1, TimeUnit.MINUTES).build()
+
+        // Register the realtime listener work request.
+        WorkManager.getInstance(this).enqueueUniquePeriodicWork(getString(R.string.register_listener_work_request), ExistingPeriodicWorkPolicy.REPLACE, registerRealtimeListenerWorkRequest)
+
+        // Return a sticky service.
+        return START_STICKY
+    }
+
+    fun registerTelephonyManagerListener() {
+        // Get a handle for the telephony manager.
         val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
 
-        // Initialize the current status.
-        var currentStatus = ""
+        // Get a handle for the notification manager.
+        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+
+        // 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)
 
         // Listen for changes to the phone state.
         telephonyManager.listen(object : PhoneStateListener() {
@@ -163,8 +204,5 @@ class RealtimeMonitoringService : Service() {
                 }
             }
         }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
-
-        // Return a sticky service.
-        return START_STICKY
     }
 }
\ No newline at end of file