First full Spanish translation.
[PrivacyCell.git] / app / src / main / java / com / stoutner / privacycell / activities / PrivacyCell.kt
index 2bbaa7cf7a77162f19dc873b7dbabb4be6da85e4..acdc97b6757a980dcb2eab2cfc7be47a2471d52b 100644 (file)
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ * along with Privacy Cell.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package com.stoutner.privacycell.activities
 
 import android.Manifest
 import android.content.Context
+import android.content.Intent
 import android.content.pm.PackageManager
+import android.net.Uri
 import android.os.Bundle
 import android.telephony.PhoneStateListener
+import android.telephony.ServiceState
 import android.telephony.TelephonyDisplayInfo
 import android.telephony.TelephonyManager
+import android.view.MenuItem
+import android.view.View
+import android.widget.ImageView
+import android.widget.LinearLayout
 import android.widget.TextView
 
+import androidx.appcompat.app.ActionBar
+import androidx.appcompat.app.ActionBarDrawerToggle
 import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.content.res.AppCompatResources
+import androidx.appcompat.widget.Toolbar
 import androidx.core.app.ActivityCompat
+import androidx.core.view.GravityCompat
+import androidx.drawerlayout.widget.DrawerLayout
+
+import com.google.android.material.navigation.NavigationView
 
 import com.stoutner.privacycell.R
+import com.stoutner.privacycell.dialogs.PhonePermissionDialog
+import com.stoutner.privacycell.dialogs.WebViewDialog
+
+class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
+    // Declare the class variables.
+    private lateinit var context: Context
+    private lateinit var telephonyManager: TelephonyManager
+    private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
+
+    // Declare the views.
+    private lateinit var drawerLayout: DrawerLayout
+    private lateinit var stingrayLinearLayout: LinearLayout
+    private lateinit var stingrayImageView: ImageView
+    private lateinit var stingrayTextView: TextView
+    private lateinit var voiceNetworkLinearLayout: LinearLayout
+    private lateinit var voiceNetworkTextView: TextView
+    private lateinit var voiceNetworkDetailsTextView: TextView
+    private lateinit var dataNetworkLinearLayout: LinearLayout
+    private lateinit var dataNetworkTextView: TextView
+    private lateinit var dataNetworkDetailsTextView: TextView
+    private lateinit var additionalNetworkInfoLinearLayout: LinearLayout
+    private lateinit var additionalNetworkInfoTextView: TextView
+    private 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_drawerlayout)
 
         // Get handles for the views.
-        val voiceNetworkTextView = findViewById<TextView>(R.id.voice_network)
-        val dataNetworkTextView = findViewById<TextView>(R.id.data_network)
-        val additionalNetworkInfoTextView = findViewById<TextView>(R.id.additional_network_info)
-        val secureFromStingrayTextView = findViewById<TextView>(R.id.secure_from_stingray)
-
-        // 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
+        drawerLayout = findViewById(R.id.drawerlayout)
+        val toolbar = findViewById<Toolbar>(R.id.toolbar)
+        stingrayLinearLayout = findViewById(R.id.stingray_linearlayout)
+        stingrayImageView = findViewById(R.id.stingray_imageview)
+        stingrayTextView = findViewById(R.id.stingray_textview)
+        voiceNetworkLinearLayout = findViewById(R.id.voice_network_linearlayout)
+        voiceNetworkTextView = findViewById(R.id.voice_network)
+        voiceNetworkDetailsTextView = findViewById(R.id.voice_network_details)
+        dataNetworkLinearLayout = findViewById(R.id.data_network_linearlayout)
+        dataNetworkTextView = findViewById(R.id.data_network)
+        dataNetworkDetailsTextView = findViewById(R.id.data_network_details)
+        additionalNetworkInfoLinearLayout = findViewById(R.id.additional_network_info_linearlayout)
+        additionalNetworkInfoTextView = findViewById(R.id.additional_network_info)
+        additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details)
+        val navigationView = findViewById<NavigationView>(R.id.navigationview)
+
+        // Get handles for the context and the telephony manager.
+        context = this
+        telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+
+        // Set the support action bar.
+        setSupportActionBar(toolbar)
+
+        // Get a handle for the action bar.
+        val actionBar = supportActionBar!!
+
+        // Set a custom view on the action bar.
+        actionBar.setCustomView(R.layout.app_bar_textview)
+
+        // Display the custom view.
+        actionBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
+
+        // Define a hamburger icon at the start of the app bar.  It will be populated in `onPostCreate()`.
+        actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer)
+
+        // Listen for touches on the navigation menu.
+        navigationView.setNavigationItemSelectedListener(this)
+
+        // Add a drawer listener.
+        drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
+            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
+                // Do nothing.
+            }
+
+            override fun onDrawerOpened(drawerView: View) {
+                // Do nothing.
+            }
+
+            override fun onDrawerClosed(drawerView: View) {
+                // Reset the drawer icon when the drawer is closed.  Otherwise, it is an arrow if the drawer is open when the app is restarted.
+                actionBarDrawerToggle.syncState()
+            }
+
+            override fun onDrawerStateChanged(newState: Int) {
+                // Do nothing.
+            }
+        })
+    }
+
+    override fun onPostCreate(savedInstanceState: Bundle?) {
+        // Run the default commands.
+        super.onPostCreate(savedInstanceState)
+
+        // Sync the state of the DrawerToggle after the default `onRestoreInstanceState()` has finished.  This creates the navigation drawer icon.
+        actionBarDrawerToggle.syncState()
+    }
+
+    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 = 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)
+            }
+        }
+    }
+
+    override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean {
+        // Run the commands that correspond to the selected menu item.
+        when (menuItem.itemId) {
+            R.id.permissions -> {  // Permissions.
+                // Instantiate the permissions dialog fragment.
+                val permissionsDialogFragment = WebViewDialog().type(WebViewDialog.PERMISSIONS)
+
+                // Show the alert dialog.
+                permissionsDialogFragment.show(supportFragmentManager, getString(R.string.permissions))
+            }
+
+            R.id.privacy_policy -> {  // Privacy Policy.
+                // Instantiate the privacy policy dialog fragment.
+                val privacyPolicyDialogFragment = WebViewDialog().type(WebViewDialog.PRIVACY_POLICY)
+
+                // Show the alert dialog.
+                privacyPolicyDialogFragment.show(supportFragmentManager, getString(R.string.privacy_policy))
+            }
+
+            R.id.changelog -> {  // Changelog.
+                // Instantiate the changelog dialog fragment.
+                val changelogDialogFragment = WebViewDialog().type(WebViewDialog.CHANGELOG)
+
+                // Show the alert dialog.
+                changelogDialogFragment.show(supportFragmentManager, getString(R.string.changelog))
+            }
+
+            R.id.licenses -> {  // Licenses.
+                // Instantiate the licenses dialog fragment.
+                val licensesDialogFragment = WebViewDialog().type(WebViewDialog.LICENSES)
+
+                // Show the alert dialog.
+                licensesDialogFragment.show(supportFragmentManager, getString(R.string.licenses))
+            }
+
+            R.id.contributors -> {  // Contributors.
+                // Instantiate the contributors dialog fragment.
+                val contributorsDialogFragment = WebViewDialog().type(WebViewDialog.CONTRIBUTORS)
+
+                // Show the alert dialog.
+                contributorsDialogFragment.show(supportFragmentManager, getString(R.string.contributors))
+            }
+
+            R.id.news -> {  // News.
+                // Create a news URL intent.
+                val newsUrlIntent = Intent(Intent.ACTION_VIEW)
+
+                // Add the URL to the intent.
+                newsUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell/")
+
+                // Make it so.
+                startActivity(newsUrlIntent)
+            }
+
+            R.id.roadmap -> {  // Roadmap.
+                // Create a roadmap URL intent.
+                val roadmapUrlIntent = Intent(Intent.ACTION_VIEW)
+
+                // Add the URL to the intent.
+                roadmapUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell-roadmap/")
+
+                // Make it so.
+                startActivity(roadmapUrlIntent)
+            }
+
+            R.id.bug_tracker -> {  // Bug tracker.
+                // Create a bug tracker URL intent.
+                val bugTrackerUrlIntent = Intent(Intent.ACTION_VIEW)
+
+                // Add the URL to the intent.
+                bugTrackerUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/issues")
+
+                // Make it so.
+                startActivity(bugTrackerUrlIntent)
+            }
+
+            R.id.forum -> {  // Forum.
+                // Create a forum URL intent.
+                val forumUrlIntent = Intent(Intent.ACTION_VIEW)
+
+                // Add the URL to the intent.
+                forumUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/boards")
+
+                // Make it so.
+                startActivity(forumUrlIntent)
+            }
+
+            R.id.donations -> {  // Donations.
+                // Create a donations URL intent.
+                val donationsUrlIntent = Intent(Intent.ACTION_VIEW)
+
+                // Add the URL to the intent.
+                donationsUrlIntent.data = Uri.parse("https://www.stoutner.com/donations/")
+
+                // Make it so.
+                startActivity(donationsUrlIntent)
+            }
         }
 
-        // Get a handle for the the telephone Manager.
-        val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+        // Close the navigation drawer.
+        drawerLayout.closeDrawer(GravityCompat.START)
+
+        // Consume the click.
+        return true
+    }
 
-        // 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 view.
-        voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType)
+    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.
+                stingrayTextView.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 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.
+                    stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.secure_5g_nr_sa))
+
+                    // Set the text.
+                    stingrayTextView.text = getString(R.string.secure_from_stingray)
+
+                    // Set the text color.
+                    stingrayTextView.setTextColor(getColor(R.color.blue_text))
+                } else {  // This is not a secure 5G NR SA network.
+                    // Populate the image view.
+                    stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.not_secure))
+
+                    // Set the text.
+                    stingrayTextView.text = getString(R.string.not_secure_from_stingray)
+
+                    // Set the text color.
+                    stingrayTextView.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)
 
-                // Populate the network text views.
-                dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType)
-                additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo)
+                // 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]
+
+                // Set the stingray click listener.
+                stingrayLinearLayout.setOnClickListener {
+                    // Instantiate the stingray dialog fragment.
+                    val stingrayDialogFragment = WebViewDialog().type(WebViewDialog.STINGRAY)
+
+                    // Show the alert dialog.
+                    stingrayDialogFragment.show(supportFragmentManager, getString(R.string.stingrays))
+                }
+
+                // Set the data network click listener.
+                dataNetworkLinearLayout.setOnClickListener {
+                    // Instantiate the data network dialog fragment according to the network type.
+                    val dataNetworkDialogFragment = when (telephonyDisplayInfo.networkType) {
+                        TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
+                        TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
+                        TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
+                        TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
+                        TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
+                        TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
+                        TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
+                        TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
+                        TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
+                        TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
+                        TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
+                        TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
+                        TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
+                        TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
+                        TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
+                        TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
+                        TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
+                        TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
+                        TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
+                        TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
+                        else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
+                    }
+
+                    // Show the alert dialog.
+                    dataNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
+                }
+
+                // Set the additional network info click listener.
+                additionalNetworkInfoLinearLayout.setOnClickListener {
+                    // Instantiate the initial network info dialog fragment according to the network type.
+                    val additionalNetworkInfoDialogFragment = when (telephonyDisplayInfo.overrideNetworkType) {
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NONE)
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_CA)
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_ADVANCED_PRO)
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA)
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
+                        else -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
+                    }
+
+                    // Show the alert dialog.
+                    additionalNetworkInfoDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
+                }
+            }
+
+            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]
+
+                // Set the voice network click listener.
+                voiceNetworkLinearLayout.setOnClickListener {
+                    // Instantiate the voice network dialog fragment according to the network type.
+                    val voiceNetworkDialogFragment = when (networkRegistrationInfo.accessNetworkTechnology) {
+                        TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
+                        TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
+                        TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
+                        TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
+                        TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
+                        TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
+                        TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
+                        TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
+                        TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
+                        TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
+                        TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
+                        TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
+                        TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
+                        TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
+                        TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
+                        TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
+                        TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
+                        TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
+                        TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
+                        TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
+                        else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
+                    }
 
-                // Populate the secure from stingray text view.  <https://source.android.com/devices/tech/connect/acts-5g-testing>
-                if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) {
-                    secureFromStingrayTextView.text = getString(R.string.secure_from_stingray)
-                } else {
-                    secureFromStingrayTextView.text = getString(R.string.not_secure_from_stingray)
+                    // Show the alert dialog.
+                    voiceNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
                 }
             }
-        }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
+        }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED or PhoneStateListener.LISTEN_SERVICE_STATE)
     }
 
-    private fun getNetworkType(networkType: Int) : String {
+    private fun getNetworkType(networkType: Int) : Array<String> {
         // Return the string that corresponds to the network type.
         return when(networkType) {
-            TelephonyManager.NETWORK_TYPE_UNKNOWN -> getString(R.string.unknown)
-            TelephonyManager.NETWORK_TYPE_GPRS -> getString(R.string.gprs)
-            TelephonyManager.NETWORK_TYPE_EDGE -> getString(R.string.edge)
-            TelephonyManager.NETWORK_TYPE_UMTS -> getString(R.string.umts)
-            TelephonyManager.NETWORK_TYPE_CDMA -> getString(R.string.cdma)
-            TelephonyManager.NETWORK_TYPE_EVDO_0 -> getString(R.string.evdo_0)
-            TelephonyManager.NETWORK_TYPE_EVDO_A -> getString(R.string.evdo_a)
-            TelephonyManager.NETWORK_TYPE_1xRTT -> getString(R.string.rtt)
-            TelephonyManager.NETWORK_TYPE_HSDPA -> getString(R.string.hsdpa)
-            TelephonyManager.NETWORK_TYPE_HSUPA -> getString(R.string.hsupa)
-            TelephonyManager.NETWORK_TYPE_HSPA -> getString(R.string.hspa)
-            TelephonyManager.NETWORK_TYPE_IDEN -> getString(R.string.iden)
-            TelephonyManager.NETWORK_TYPE_EVDO_B -> getString(R.string.evdo_b)
-            TelephonyManager.NETWORK_TYPE_LTE -> getString(R.string.lte)
-            TelephonyManager.NETWORK_TYPE_EHRPD -> getString(R.string.ehrpd)
-            TelephonyManager.NETWORK_TYPE_HSPAP -> getString(R.string.hspap)
-            TelephonyManager.NETWORK_TYPE_GSM -> getString(R.string.gsm)
-            TelephonyManager.NETWORK_TYPE_TD_SCDMA -> getString(R.string.td_scdma)
-            TelephonyManager.NETWORK_TYPE_IWLAN -> getString(R.string.iwlan)
-            TelephonyManager.NETWORK_TYPE_NR -> getString(R.string.nr)
-            else -> getString(R.string.error)
+            TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), "")
+            TelephonyManager.NETWORK_TYPE_GPRS -> arrayOf(getString(R.string.gprs), getString(R.string.gprs_detail))
+            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))
+            TelephonyManager.NETWORK_TYPE_CDMA -> arrayOf(getString(R.string.cdma), getString(R.string.cdma_detail))
+            TelephonyManager.NETWORK_TYPE_EVDO_0 -> arrayOf(getString(R.string.evdo_0), getString(R.string.evdo_0_detail))
+            TelephonyManager.NETWORK_TYPE_EVDO_A -> arrayOf(getString(R.string.evdo_a), getString(R.string.evdo_a_detail))
+            TelephonyManager.NETWORK_TYPE_1xRTT -> arrayOf(getString(R.string.rtt), getString(R.string.rtt_detail))
+            TelephonyManager.NETWORK_TYPE_HSDPA -> arrayOf(getString(R.string.hsdpa), getString(R.string.hsdpa_detail))
+            TelephonyManager.NETWORK_TYPE_HSUPA -> arrayOf(getString(R.string.hsupa), getString(R.string.hsupa_detail))
+            TelephonyManager.NETWORK_TYPE_HSPA -> arrayOf(getString(R.string.hspa), getString(R.string.hspa_detail))
+            TelephonyManager.NETWORK_TYPE_IDEN -> arrayOf(getString(R.string.iden), getString(R.string.iden_detail))
+            TelephonyManager.NETWORK_TYPE_EVDO_B -> arrayOf(getString(R.string.evdo_b), getString(R.string.evdo_b_detail))
+            TelephonyManager.NETWORK_TYPE_LTE -> arrayOf(getString(R.string.lte), getString(R.string.lte_detail))
+            TelephonyManager.NETWORK_TYPE_EHRPD -> arrayOf(getString(R.string.ehrpd), getString(R.string.ehrpd_detail))
+            TelephonyManager.NETWORK_TYPE_HSPAP -> arrayOf(getString(R.string.hspap), getString(R.string.hspap_detail))
+            TelephonyManager.NETWORK_TYPE_GSM -> arrayOf(getString(R.string.gsm), getString(R.string.gsm_detail))
+            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), "")
         }
     }
 
-    private fun getAdditionalNetworkInfo(overrideNetworkType: Int) : String {
+    private fun getAdditionalNetworkInfo(overrideNetworkType: Int) : Array<String> {
         // Return the string that corresponds to the override network type.
         return when(overrideNetworkType) {
-            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> getString(R.string.none)
-            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> getString(R.string.lte_ca)
-            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> getString(R.string.lte_advanced_pro)
-            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> getString(R.string.lte_nr_nsa)
-            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> getString(R.string.lte_nr_nsa_mmwave)
-            else -> getString(R.string.error)
+            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> arrayOf(getString(R.string.none), "")
+            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> arrayOf(getString(R.string.lte_ca), getString(R.string.lte_ca_detail))
+            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> arrayOf(getString(R.string.lte_advanced_pro), getString(R.string.lte_advanced_pro_detail))
+            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> arrayOf(getString(R.string.nr_nsa), getString(R.string.nr_nsa_detail))
+            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> arrayOf(getString(R.string.nr_nsa_mmwave), getString(R.string.nr_nsa_mmwave_detail))
+            else -> arrayOf(getString(R.string.error), "")
         }
     }
 }
\ No newline at end of file