]> gitweb.stoutner.com Git - PrivacyCell.git/blobdiff - app/src/main/java/com/stoutner/privacycell/activities/PrivacyCell.kt
Reregister the listener on every resume.
[PrivacyCell.git] / app / src / main / java / com / stoutner / privacycell / activities / PrivacyCell.kt
index b45701832350f774b513dca3664f393164567380..b30d0fd3f077a1184b6e68acb3a372cb2fde8268 100644 (file)
@@ -24,6 +24,7 @@ import android.content.Context
 import android.content.pm.PackageManager
 import android.os.Bundle
 import android.telephony.PhoneStateListener
+import android.telephony.ServiceState
 import android.telephony.TelephonyDisplayInfo
 import android.telephony.TelephonyManager
 import android.widget.ImageView
@@ -32,58 +33,101 @@ import android.widget.TextView
 import androidx.appcompat.app.AppCompatActivity
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.core.app.ActivityCompat
+import androidx.fragment.app.DialogFragment
 
 import com.stoutner.privacycell.R
+import com.stoutner.privacycell.dialogs.PhonePermissionDialog
+
+class PrivacyCell : AppCompatActivity(), PhonePermissionDialog.StoragePermissionDialogListener {
+    // Declare the class variables.
+    private lateinit var context: Context
+    private lateinit var telephonyManager: TelephonyManager
+
+    // Declare the views.
+    lateinit var secureFromStingrayImageView: ImageView
+    lateinit var secureFromStingrayTextView: TextView
+    lateinit var voiceNetworkTextView: TextView
+    lateinit var voiceNetworkDetailsTextView: TextView
+    lateinit var dataNetworkTextView: TextView
+    lateinit var dataNetworkDetailsTextView: TextView
+    lateinit var additionalNetworkInfoTextView: TextView
+    lateinit var additionalNetworkInfoDetailsTextView: TextView
 
-class PrivacyCell : AppCompatActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         // Run the default commands.
         super.onCreate(savedInstanceState)
 
         // Set the content view.
-        setContentView(R.layout.privacy_cell_linearlayout)
+        setContentView(R.layout.privacy_cell_scrollview)
 
         // Get handles for the views.
-        val secureFromStingrayImageView = findViewById<ImageView>(R.id.secure_from_stingray_imageview)
-        val secureFromStingrayTextView = findViewById<TextView>(R.id.secure_from_stingray_textview)
-        val voiceNetworkTextView = findViewById<TextView>(R.id.voice_network)
-        val voiceNetworkDetailsTextView = findViewById<TextView>(R.id.voice_network_details)
-        val dataNetworkTextView = findViewById<TextView>(R.id.data_network)
-        val dataNetworkDetailsTextView = findViewById<TextView>(R.id.data_network_details)
-        val additionalNetworkInfoTextView = findViewById<TextView>(R.id.additional_network_info)
-        val additionalNetworkInfoDetailsTextView = findViewById<TextView>(R.id.additional_network_info_details)
-
-        // TODO.
-        if (ActivityCompat.checkSelfPermission(
-                this,
-                Manifest.permission.READ_PHONE_STATE
-            ) != PackageManager.PERMISSION_GRANTED
-        ) {
-            // TODO: Consider calling
-            //    ActivityCompat#requestPermissions
-            // here to request the missing permissions, and then overriding
-            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
-            //                                          int[] grantResults)
-            // to handle the case where the user grants the permission. See the documentation
-            // for ActivityCompat#requestPermissions for more details.
-            return
-        }
+        secureFromStingrayImageView = findViewById(R.id.secure_from_stingray_imageview)
+        secureFromStingrayTextView = findViewById(R.id.secure_from_stingray_textview)
+        voiceNetworkTextView = findViewById(R.id.voice_network)
+        voiceNetworkDetailsTextView = findViewById(R.id.voice_network_details)
+        dataNetworkTextView = findViewById(R.id.data_network)
+        dataNetworkDetailsTextView = findViewById(R.id.data_network_details)
+        additionalNetworkInfoTextView = findViewById(R.id.additional_network_info)
+        additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details)
+
+        // Get handles for the context and the telephony manager.
+        context = this
+        telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+    }
 
-        // Get a handle for the the telephone Manager and the context.
-        val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
-        val context: Context = this
+    override fun onResume() {
+        // Run the default commands.
+        super.onResume()
+
+        // Check to see if the read phone state permission has been granted.  These commands need to be run on every resume so that the listener gets reassigned as it is automatically paused.
+        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {  // The storage permission has been granted.
+            // Populate Privacy Cell.
+            populatePrivacyCell()
+        } else {  // The phone permission has not been granted.
+            // Check if the user has previously denied the storage permission.
+            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) {  // Show a dialog explaining the request first.
+                // Check to see if a phone permission dialog is already displayed.  This happens if the app is restarted when the dialog is shown.
+                if (supportFragmentManager.findFragmentByTag(getString(R.string.phone_permission)) == null) {  // No dialog is currently shown.
+                    // Instantiate the phone permission dialog fragment.
+                    val phonePermissionDialogFragment: DialogFragment = PhonePermissionDialog()
+
+                    // Show the phone permission alert dialog.  The permission will be requested when the dialog is closed.
+                    phonePermissionDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission))
+                }
+            } else {  // Show the permission request directly.
+                // Request the read phone state permission.  There is only one permission request in the app, so it has a request code of 0.
+                ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
+            }
+        }
+    }
 
-        // Get the voice network type.
-        val voiceNetworkType = getNetworkType(telephonyManager.voiceNetworkType)
+    override fun onCloseStoragePermissionDialog() {
+        // Request the read phone state permission.  There is only one permission request in the app, so it has a request code of 0.
+        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
+    }
 
-        // Populate the voice network text views.
-        voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType[0])
-        voiceNetworkDetailsTextView.text = voiceNetworkType[1]
+    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+        // Run the default commands.
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+
+        //Only process the results if they exist (this method is triggered when a dialog is presented the first time for an app, but no grant results are included).
+        if (grantResults.isNotEmpty()) {
+            // Check to see if the read phone state permission was granted.  If the dialog was canceled the grant results will be empty.
+            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {  // The read phone state permission was granted.
+                // Populate Privacy Cell.
+                populatePrivacyCell()
+            } else {  // The read phone state permission was denied.
+                // Display the phone permission text on the main activity.
+                secureFromStingrayTextView.text = getString(R.string.phone_permission_text)
+            }
+        }
+    }
 
+    private fun populatePrivacyCell() {
         // Listen to changes in the cell network state.
         telephonyManager.listen(object : PhoneStateListener() {
-            override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {// Populate the secure from stingray text view.  <https://source.android.com/devices/tech/connect/acts-5g-testing>
-                // Populate the stingray security information.
+            override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
+                // Populate the stingray security information.  <https://source.android.com/devices/tech/connect/acts-5g-testing>
                 if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) {  // This is a secure 5G NR SA network.
                     // Populate the image view.
                     secureFromStingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.secure_5g_nr_sa))
@@ -92,7 +136,7 @@ class PrivacyCell : AppCompatActivity() {
                     secureFromStingrayTextView.text = getString(R.string.secure_from_stingray)
 
                     // Set the text color.
-                    secureFromStingrayTextView.setTextColor(getColor(R.color.blue_700))
+                    secureFromStingrayTextView.setTextColor(getColor(R.color.blue_text))
                 } else {  // This is not a secure 5G NR SA network.
                     // Populate the image view.
                     secureFromStingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.not_secure))
@@ -101,26 +145,38 @@ class PrivacyCell : AppCompatActivity() {
                     secureFromStingrayTextView.text = getString(R.string.not_secure_from_stingray)
 
                     // Set the text color.
-                    secureFromStingrayTextView.setTextColor(getColor(R.color.red_700))
+                    secureFromStingrayTextView.setTextColor(getColor(R.color.red_text))
 
-                // Get the strings that correspond to the network information.
-                val dataNetworkType = getNetworkType(telephonyDisplayInfo.networkType)
-                val additionalNetworkInfo = getAdditionalNetworkInfo(telephonyDisplayInfo.overrideNetworkType)
+                    // Get the strings that correspond to the network information.
+                    val dataNetworkType = getNetworkType(telephonyDisplayInfo.networkType)
+                    val additionalNetworkInfo = getAdditionalNetworkInfo(telephonyDisplayInfo.overrideNetworkType)
 
-                // Populate the data network text views.
-                dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType[0])
-                dataNetworkDetailsTextView.text = dataNetworkType[1]
-                additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo[0])
-                additionalNetworkInfoDetailsTextView.text = additionalNetworkInfo[1]
+                    // Populate the data network text views.
+                    dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType[0])
+                    dataNetworkDetailsTextView.text = dataNetworkType[1]
+                    additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo[0])
+                    additionalNetworkInfoDetailsTextView.text = additionalNetworkInfo[1]
                 }
             }
-        }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
+
+            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]
+
+                // Get the voice network type.
+                val voiceNetworkType = getNetworkType(networkRegistrationInfo.accessNetworkTechnology)
+
+                // Populate the voice network text views.
+                voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType[0])
+                voiceNetworkDetailsTextView.text = voiceNetworkType[1]
+            }
+        }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED or PhoneStateListener.LISTEN_SERVICE_STATE)
     }
 
     private fun getNetworkType(networkType: Int) : Array<String> {
         // Return the string that corresponds to the network type.
         return when(networkType) {
-            TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), getString(R.string.unknown))
+            TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), "")
             TelephonyManager.NETWORK_TYPE_GPRS -> arrayOf(getString(R.string.gprs), getString(R.string.gprs_detal))
             TelephonyManager.NETWORK_TYPE_EDGE -> arrayOf(getString(R.string.edge), getString(R.string.edge_detail))
             TelephonyManager.NETWORK_TYPE_UMTS -> arrayOf(getString(R.string.umts), getString(R.string.umts_detail))
@@ -140,7 +196,7 @@ class PrivacyCell : AppCompatActivity() {
             TelephonyManager.NETWORK_TYPE_TD_SCDMA -> arrayOf(getString(R.string.td_scdma), getString(R.string.td_scdma_detail))
             TelephonyManager.NETWORK_TYPE_IWLAN -> arrayOf(getString(R.string.iwlan), getString(R.string.iwlan_detail))
             TelephonyManager.NETWORK_TYPE_NR -> arrayOf(getString(R.string.nr), getString(R.string.nr_detail))
-            else -> arrayOf(getString(R.string.error), getString(R.string.error))
+            else -> arrayOf(getString(R.string.error), "")
         }
     }