- // 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 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 for the secure and insecure networks.
- secureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
- insecureNetworkChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
+ // Get a handle for the shared preferences.
+ val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
+
+ // 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.
+ 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.
+ 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))
+
+ // Prevent swiping to dismiss the notification. This no longer works (except on the lock screen) in API >= 34.
+ notificationBuilder.setOngoing(true)
+
+ // Start the foreground notification.
+ startForeground(NOTIFICATION_ID, notificationBuilder.build())
+
+ // Instantiate the protocol helper.
+ val protocolHelper = ProtocolHelper()
+
+ // Get a handle for the telephony manager.
+ val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+
+ // 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 onServiceStateChanged(serviceState: ServiceState) { // Update the voice network status.
+ // Check to see if realtime monitoring is enabled. Sometimes the system keeps running the service even when it is supposed to shut down.
+ if (sharedPreferences.getBoolean(applicationContext.getString(R.string.realtime_monitoring_key), true)) { // Realtime monitoring is enabled.
+ // 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]
+
+ // Get the consider 3G antiquated preference.
+ val consider3gAntiquated = sharedPreferences.getBoolean(getString(R.string.consider_3g_antiquated_key), false)
+
+ // Update the voice network security status.
+ voiceNetworkSecurityStatus = protocolHelper.checkNetwork(networkRegistrationInfo.accessNetworkTechnology, consider3gAntiquated)
+
+ // Populate the notification.
+ populateNotification()
+ } else { // Realtime monitoring is disabled.
+ // Cancel the current listener if it exists. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
+ telephonyManager.listen(phoneStateListener, LISTEN_NONE)
+ }
+ }