2 * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
6 * Privacy Cell is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Cell is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Cell. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacycell.activities
22 import android.Manifest
23 import android.app.ActivityManager
24 import android.content.Context
25 import android.content.Intent
26 import android.content.pm.PackageManager
27 import android.net.Uri
28 import android.os.Bundle
29 import android.telephony.PhoneStateListener
30 import android.telephony.ServiceState
31 import android.telephony.TelephonyDisplayInfo
32 import android.telephony.TelephonyManager
33 import android.view.MenuItem
34 import android.view.View
35 import android.widget.ImageView
36 import android.widget.LinearLayout
37 import android.widget.TextView
39 import androidx.appcompat.app.ActionBar
40 import androidx.appcompat.app.ActionBarDrawerToggle
41 import androidx.appcompat.app.AppCompatActivity
42 import androidx.appcompat.content.res.AppCompatResources
43 import androidx.appcompat.widget.Toolbar
44 import androidx.core.app.ActivityCompat
45 import androidx.core.view.GravityCompat
46 import androidx.drawerlayout.widget.DrawerLayout
47 import androidx.preference.PreferenceManager
49 import com.google.android.material.navigation.NavigationView
51 import com.stoutner.privacycell.R
52 import com.stoutner.privacycell.dialogs.PhonePermissionDialog
53 import com.stoutner.privacycell.dialogs.WebViewDialog
54 import com.stoutner.privacycell.services.RealtimeMonitoringService
56 class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
57 // Declare the class variables.
58 private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
61 private lateinit var drawerLayout: DrawerLayout
62 private lateinit var stingrayLinearLayout: LinearLayout
63 private lateinit var stingrayImageView: ImageView
64 private lateinit var stingrayTextView: TextView
65 private lateinit var voiceNetworkLinearLayout: LinearLayout
66 private lateinit var voiceNetworkTextView: TextView
67 private lateinit var voiceNetworkDetailsTextView: TextView
68 private lateinit var dataNetworkLinearLayout: LinearLayout
69 private lateinit var dataNetworkTextView: TextView
70 private lateinit var dataNetworkDetailsTextView: TextView
71 private lateinit var additionalNetworkInfoLinearLayout: LinearLayout
72 private lateinit var additionalNetworkInfoTextView: TextView
73 private lateinit var additionalNetworkInfoDetailsTextView: TextView
75 override fun onCreate(savedInstanceState: Bundle?) {
76 // Run the default commands.
77 super.onCreate(savedInstanceState)
79 // Get a handle for the shared preferences.
80 val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
82 // Get the preferences.
83 val realtimeMonitoring = sharedPreferences.getBoolean(getString(R.string.realtime_monitoring_key), false)
84 val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
86 // Set the content view.
88 setContentView(R.layout.privacy_cell_bottom_appbar)
90 setContentView(R.layout.privacy_cell_top_appbar)
93 // Get handles for the views.
94 drawerLayout = findViewById(R.id.drawerlayout)
95 val toolbar = findViewById<Toolbar>(R.id.toolbar)
96 stingrayLinearLayout = findViewById(R.id.stingray_linearlayout)
97 stingrayImageView = findViewById(R.id.stingray_imageview)
98 stingrayTextView = findViewById(R.id.stingray_textview)
99 voiceNetworkLinearLayout = findViewById(R.id.voice_network_linearlayout)
100 voiceNetworkTextView = findViewById(R.id.voice_network)
101 voiceNetworkDetailsTextView = findViewById(R.id.voice_network_details)
102 dataNetworkLinearLayout = findViewById(R.id.data_network_linearlayout)
103 dataNetworkTextView = findViewById(R.id.data_network)
104 dataNetworkDetailsTextView = findViewById(R.id.data_network_details)
105 additionalNetworkInfoLinearLayout = findViewById(R.id.additional_network_info_linearlayout)
106 additionalNetworkInfoTextView = findViewById(R.id.additional_network_info)
107 additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details)
108 val navigationView = findViewById<NavigationView>(R.id.navigationview)
110 // Set the support action bar.
111 setSupportActionBar(toolbar)
113 // Get a handle for the action bar.
114 val actionBar = supportActionBar!!
116 // Set a custom view on the action bar.
117 actionBar.setCustomView(R.layout.app_bar_textview)
119 // Display the custom view.
120 actionBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
122 // Define a hamburger icon at the start of the app bar. It will be populated in `onPostCreate()`.
123 actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer)
125 // Listen for touches on the navigation menu.
126 navigationView.setNavigationItemSelectedListener(this)
128 // Add a drawer listener.
129 drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
130 override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
134 override fun onDrawerOpened(drawerView: View) {
138 override fun onDrawerClosed(drawerView: View) {
139 // Reset the drawer icon when the drawer is closed. Otherwise, it is an arrow if the drawer is open when the app is restarted.
140 actionBarDrawerToggle.syncState()
143 override fun onDrawerStateChanged(newState: Int) {
148 // Start the realtime monitoring service if it is enabled.
149 if (realtimeMonitoring) {
150 // Get a handle for the activity manager.
151 val activityManager: ActivityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
153 // 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.
154 val runningServiceInfoList: List<ActivityManager.RunningServiceInfo> = activityManager.getRunningServices(1)
156 // Start the service if it is not already running.
157 if (runningServiceInfoList.isEmpty()) {
158 startService(Intent(this, RealtimeMonitoringService::class.java))
163 override fun onPostCreate(savedInstanceState: Bundle?) {
164 // Run the default commands.
165 super.onPostCreate(savedInstanceState)
167 // Sync the state of the DrawerToggle after the default `onRestoreInstanceState()` has finished. This creates the navigation drawer icon.
168 actionBarDrawerToggle.syncState()
171 override fun onResume() {
172 // Run the default commands.
175 // 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.
176 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
177 // Populate Privacy Cell.
178 populatePrivacyCell(this)
179 } else { // The phone permission has not been granted.
180 // Check if the user has previously denied the storage permission.
181 if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) { // Show a dialog explaining the request first.
182 // Check to see if a phone permission dialog is already displayed. This happens if the app is restarted when the dialog is shown.
183 if (supportFragmentManager.findFragmentByTag(getString(R.string.phone_permission)) == null) { // No dialog is currently shown.
184 // Instantiate the phone permission dialog fragment.
185 val phonePermissionDialogFragment = PhonePermissionDialog()
187 // Show the phone permission alert dialog. The permission will be requested when the dialog is closed.
188 phonePermissionDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission))
190 } else { // Show the permission request directly.
191 // Request the read phone state permission. There is only one permission request in the app, so it has a request code of 0.
192 ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
197 override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean {
198 // Run the commands that correspond to the selected menu item.
199 when (menuItem.itemId) {
200 R.id.settings -> { // Settings.
201 // Create an intent to load the Settings activity.
202 val settingsIntent = Intent(this, SettingsActivity::class.java)
205 startActivity(settingsIntent)
208 R.id.logcat -> { // Logcat.
209 // Create an intent to load the Logcat activity.
210 val logcatIntent = Intent(this, LogcatActivity::class.java)
213 startActivity(logcatIntent)
216 R.id.permissions -> { // Permissions.
217 // Instantiate the permissions dialog fragment.
218 val permissionsDialogFragment = WebViewDialog().type(WebViewDialog.PERMISSIONS)
220 // Show the alert dialog.
221 permissionsDialogFragment.show(supportFragmentManager, getString(R.string.permissions))
224 R.id.privacy_policy -> { // Privacy Policy.
225 // Instantiate the privacy policy dialog fragment.
226 val privacyPolicyDialogFragment = WebViewDialog().type(WebViewDialog.PRIVACY_POLICY)
228 // Show the alert dialog.
229 privacyPolicyDialogFragment.show(supportFragmentManager, getString(R.string.privacy_policy))
232 R.id.changelog -> { // Changelog.
233 // Instantiate the changelog dialog fragment.
234 val changelogDialogFragment = WebViewDialog().type(WebViewDialog.CHANGELOG)
236 // Show the alert dialog.
237 changelogDialogFragment.show(supportFragmentManager, getString(R.string.changelog))
240 R.id.licenses -> { // Licenses.
241 // Instantiate the licenses dialog fragment.
242 val licensesDialogFragment = WebViewDialog().type(WebViewDialog.LICENSES)
244 // Show the alert dialog.
245 licensesDialogFragment.show(supportFragmentManager, getString(R.string.licenses))
248 R.id.contributors -> { // Contributors.
249 // Instantiate the contributors dialog fragment.
250 val contributorsDialogFragment = WebViewDialog().type(WebViewDialog.CONTRIBUTORS)
252 // Show the alert dialog.
253 contributorsDialogFragment.show(supportFragmentManager, getString(R.string.contributors))
256 R.id.news -> { // News.
257 // Create a news URL intent.
258 val newsUrlIntent = Intent(Intent.ACTION_VIEW)
260 // Add the URL to the intent.
261 newsUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell/")
264 startActivity(newsUrlIntent)
267 R.id.roadmap -> { // Roadmap.
268 // Create a roadmap URL intent.
269 val roadmapUrlIntent = Intent(Intent.ACTION_VIEW)
271 // Add the URL to the intent.
272 roadmapUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell-roadmap/")
275 startActivity(roadmapUrlIntent)
278 R.id.bug_tracker -> { // Bug tracker.
279 // Create a bug tracker URL intent.
280 val bugTrackerUrlIntent = Intent(Intent.ACTION_VIEW)
282 // Add the URL to the intent.
283 bugTrackerUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/issues")
286 startActivity(bugTrackerUrlIntent)
289 R.id.forum -> { // Forum.
290 // Create a forum URL intent.
291 val forumUrlIntent = Intent(Intent.ACTION_VIEW)
293 // Add the URL to the intent.
294 forumUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/boards")
297 startActivity(forumUrlIntent)
300 R.id.donations -> { // Donations.
301 // Create a donations URL intent.
302 val donationsUrlIntent = Intent(Intent.ACTION_VIEW)
304 // Add the URL to the intent.
305 donationsUrlIntent.data = Uri.parse("https://www.stoutner.com/donations/")
308 startActivity(donationsUrlIntent)
312 // Close the navigation drawer.
313 drawerLayout.closeDrawer(GravityCompat.START)
315 // Consume the click.
319 override fun onCloseStoragePermissionDialog() {
320 // Request the read phone state permission. There is only one permission request in the app, so it has a request code of 0.
321 ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
324 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
325 // Run the default commands.
326 super.onRequestPermissionsResult(requestCode, permissions, grantResults)
328 //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).
329 if (grantResults.isNotEmpty()) {
330 // Check to see if the read phone state permission was granted. If the dialog was canceled the grant results will be empty.
331 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // The read phone state permission was granted.
332 // Populate Privacy Cell.
333 populatePrivacyCell(this)
334 } else { // The read phone state permission was denied.
335 // Display the phone permission text on the main activity.
336 stingrayTextView.text = getString(R.string.phone_permission_text)
341 private fun populatePrivacyCell(context: Context) {
342 // Get a handle for the telephony manager.
343 val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
345 // Listen to changes in the cell network state.
346 telephonyManager.listen(object : PhoneStateListener() {
347 override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
348 // Populate the stingray security information. <https://source.android.com/devices/tech/connect/acts-5g-testing>
349 if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) { // This is a secure 5G NR SA network.
350 // Populate the image view.
351 stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.secure_5g_nr_sa))
354 stingrayTextView.text = getString(R.string.secure_from_stingray)
356 // Set the text color.
357 stingrayTextView.setTextColor(getColor(R.color.blue_text))
358 } else { // This is not a secure 5G NR SA network.
359 // Populate the image view.
360 stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.not_secure))
363 stingrayTextView.text = getString(R.string.not_secure_from_stingray)
365 // Set the text color.
366 stingrayTextView.setTextColor(getColor(R.color.red_text))
369 // Get the strings that correspond to the network information.
370 val dataNetworkType = getNetworkType(telephonyDisplayInfo.networkType)
371 val additionalNetworkInfo = getAdditionalNetworkInfo(telephonyDisplayInfo.overrideNetworkType)
373 // Populate the data network text views.
374 dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType[0])
375 dataNetworkDetailsTextView.text = dataNetworkType[1]
376 additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo[0])
377 additionalNetworkInfoDetailsTextView.text = additionalNetworkInfo[1]
379 // Set the stingray click listener.
380 stingrayLinearLayout.setOnClickListener {
381 // Instantiate the stingray dialog fragment.
382 val stingrayDialogFragment = WebViewDialog().type(WebViewDialog.STINGRAY)
384 // Show the alert dialog.
385 stingrayDialogFragment.show(supportFragmentManager, getString(R.string.stingrays))
388 // Set the data network click listener.
389 dataNetworkLinearLayout.setOnClickListener {
390 // Instantiate the data network dialog fragment according to the network type.
391 val dataNetworkDialogFragment = when (telephonyDisplayInfo.networkType) {
392 TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
393 TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
394 TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
395 TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
396 TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
397 TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
398 TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
399 TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
400 TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
401 TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
402 TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
403 TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
404 TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
405 TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
406 TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
407 TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
408 TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
409 TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
410 TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
411 TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
412 else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
415 // Show the alert dialog.
416 dataNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
419 // Set the additional network info click listener.
420 additionalNetworkInfoLinearLayout.setOnClickListener {
421 // Instantiate the initial network info dialog fragment according to the network type.
422 val additionalNetworkInfoDialogFragment = when (telephonyDisplayInfo.overrideNetworkType) {
423 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NONE)
424 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_CA)
425 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_ADVANCED_PRO)
426 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA)
427 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
428 else -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
431 // Show the alert dialog.
432 additionalNetworkInfoDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
436 override fun onServiceStateChanged(serviceState: ServiceState) {
437 // 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).
438 val networkRegistrationInfo = serviceState.networkRegistrationInfoList[1]
440 // Get the voice network type.
441 val voiceNetworkType = getNetworkType(networkRegistrationInfo.accessNetworkTechnology)
443 // Populate the voice network text views.
444 voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType[0])
445 voiceNetworkDetailsTextView.text = voiceNetworkType[1]
447 // Set the voice network click listener.
448 voiceNetworkLinearLayout.setOnClickListener {
449 // Instantiate the voice network dialog fragment according to the network type.
450 val voiceNetworkDialogFragment = when (networkRegistrationInfo.accessNetworkTechnology) {
451 TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
452 TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
453 TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
454 TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
455 TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
456 TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
457 TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
458 TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
459 TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
460 TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
461 TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
462 TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
463 TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
464 TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
465 TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
466 TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
467 TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
468 TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
469 TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
470 TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
471 else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
474 // Show the alert dialog.
475 voiceNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
478 }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED or PhoneStateListener.LISTEN_SERVICE_STATE)
481 private fun getNetworkType(networkType: Int) : Array<String> {
482 // Return the string that corresponds to the network type.
483 return when(networkType) {
484 TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), "")
485 TelephonyManager.NETWORK_TYPE_GPRS -> arrayOf(getString(R.string.gprs), getString(R.string.gprs_detail))
486 TelephonyManager.NETWORK_TYPE_EDGE -> arrayOf(getString(R.string.edge), getString(R.string.edge_detail))
487 TelephonyManager.NETWORK_TYPE_UMTS -> arrayOf(getString(R.string.umts), getString(R.string.umts_detail))
488 TelephonyManager.NETWORK_TYPE_CDMA -> arrayOf(getString(R.string.cdma), getString(R.string.cdma_detail))
489 TelephonyManager.NETWORK_TYPE_EVDO_0 -> arrayOf(getString(R.string.evdo_0), getString(R.string.evdo_0_detail))
490 TelephonyManager.NETWORK_TYPE_EVDO_A -> arrayOf(getString(R.string.evdo_a), getString(R.string.evdo_a_detail))
491 TelephonyManager.NETWORK_TYPE_1xRTT -> arrayOf(getString(R.string.rtt), getString(R.string.rtt_detail))
492 TelephonyManager.NETWORK_TYPE_HSDPA -> arrayOf(getString(R.string.hsdpa), getString(R.string.hsdpa_detail))
493 TelephonyManager.NETWORK_TYPE_HSUPA -> arrayOf(getString(R.string.hsupa), getString(R.string.hsupa_detail))
494 TelephonyManager.NETWORK_TYPE_HSPA -> arrayOf(getString(R.string.hspa), getString(R.string.hspa_detail))
495 TelephonyManager.NETWORK_TYPE_IDEN -> arrayOf(getString(R.string.iden), getString(R.string.iden_detail))
496 TelephonyManager.NETWORK_TYPE_EVDO_B -> arrayOf(getString(R.string.evdo_b), getString(R.string.evdo_b_detail))
497 TelephonyManager.NETWORK_TYPE_LTE -> arrayOf(getString(R.string.lte), getString(R.string.lte_detail))
498 TelephonyManager.NETWORK_TYPE_EHRPD -> arrayOf(getString(R.string.ehrpd), getString(R.string.ehrpd_detail))
499 TelephonyManager.NETWORK_TYPE_HSPAP -> arrayOf(getString(R.string.hspap), getString(R.string.hspap_detail))
500 TelephonyManager.NETWORK_TYPE_GSM -> arrayOf(getString(R.string.gsm), getString(R.string.gsm_detail))
501 TelephonyManager.NETWORK_TYPE_TD_SCDMA -> arrayOf(getString(R.string.td_scdma), getString(R.string.td_scdma_detail))
502 TelephonyManager.NETWORK_TYPE_IWLAN -> arrayOf(getString(R.string.iwlan), getString(R.string.iwlan_detail))
503 TelephonyManager.NETWORK_TYPE_NR -> arrayOf(getString(R.string.nr), getString(R.string.nr_detail))
504 else -> arrayOf(getString(R.string.error), "")
508 private fun getAdditionalNetworkInfo(overrideNetworkType: Int) : Array<String> {
509 // Return the string that corresponds to the override network type.
510 return when(overrideNetworkType) {
511 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> arrayOf(getString(R.string.none), "")
512 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> arrayOf(getString(R.string.lte_ca), getString(R.string.lte_ca_detail))
513 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> arrayOf(getString(R.string.lte_advanced_pro), getString(R.string.lte_advanced_pro_detail))
514 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> arrayOf(getString(R.string.nr_nsa), getString(R.string.nr_nsa_detail))
515 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> arrayOf(getString(R.string.nr_nsa_mmwave), getString(R.string.nr_nsa_mmwave_detail))
516 else -> arrayOf(getString(R.string.error), "")