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.content.Context
24 import android.content.Intent
25 import android.content.pm.PackageManager
26 import android.net.Uri
27 import android.os.Bundle
28 import android.telephony.PhoneStateListener
29 import android.telephony.ServiceState
30 import android.telephony.TelephonyDisplayInfo
31 import android.telephony.TelephonyManager
32 import android.view.MenuItem
33 import android.view.View
34 import android.widget.ImageView
35 import android.widget.LinearLayout
36 import android.widget.TextView
38 import androidx.appcompat.app.ActionBar
39 import androidx.appcompat.app.ActionBarDrawerToggle
40 import androidx.appcompat.app.AppCompatActivity
41 import androidx.appcompat.content.res.AppCompatResources
42 import androidx.appcompat.widget.Toolbar
43 import androidx.core.app.ActivityCompat
44 import androidx.core.view.GravityCompat
45 import androidx.drawerlayout.widget.DrawerLayout
46 import androidx.preference.PreferenceManager
48 import com.google.android.material.navigation.NavigationView
50 import com.stoutner.privacycell.R
51 import com.stoutner.privacycell.dialogs.PhonePermissionDialog
52 import com.stoutner.privacycell.dialogs.WebViewDialog
54 class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
55 // Declare the class variables.
56 private lateinit var context: Context
57 private lateinit var telephonyManager: TelephonyManager
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 bottom app bar preference.
83 val bottomAppBar = sharedPreferences.getBoolean(getString(R.string.bottom_app_bar_key), false)
85 // Set the content view.
87 setContentView(R.layout.privacy_cell_bottom_appbar)
89 setContentView(R.layout.privacy_cell_top_appbar)
92 // Get handles for the views.
93 drawerLayout = findViewById(R.id.drawerlayout)
94 val toolbar = findViewById<Toolbar>(R.id.toolbar)
95 stingrayLinearLayout = findViewById(R.id.stingray_linearlayout)
96 stingrayImageView = findViewById(R.id.stingray_imageview)
97 stingrayTextView = findViewById(R.id.stingray_textview)
98 voiceNetworkLinearLayout = findViewById(R.id.voice_network_linearlayout)
99 voiceNetworkTextView = findViewById(R.id.voice_network)
100 voiceNetworkDetailsTextView = findViewById(R.id.voice_network_details)
101 dataNetworkLinearLayout = findViewById(R.id.data_network_linearlayout)
102 dataNetworkTextView = findViewById(R.id.data_network)
103 dataNetworkDetailsTextView = findViewById(R.id.data_network_details)
104 additionalNetworkInfoLinearLayout = findViewById(R.id.additional_network_info_linearlayout)
105 additionalNetworkInfoTextView = findViewById(R.id.additional_network_info)
106 additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details)
107 val navigationView = findViewById<NavigationView>(R.id.navigationview)
109 // Get handles for the context and the telephony manager.
111 telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
113 // Set the support action bar.
114 setSupportActionBar(toolbar)
116 // Get a handle for the action bar.
117 val actionBar = supportActionBar!!
119 // Set a custom view on the action bar.
120 actionBar.setCustomView(R.layout.app_bar_textview)
122 // Display the custom view.
123 actionBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
125 // Define a hamburger icon at the start of the app bar. It will be populated in `onPostCreate()`.
126 actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer)
128 // Listen for touches on the navigation menu.
129 navigationView.setNavigationItemSelectedListener(this)
131 // Add a drawer listener.
132 drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
133 override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
137 override fun onDrawerOpened(drawerView: View) {
141 override fun onDrawerClosed(drawerView: View) {
142 // Reset the drawer icon when the drawer is closed. Otherwise, it is an arrow if the drawer is open when the app is restarted.
143 actionBarDrawerToggle.syncState()
146 override fun onDrawerStateChanged(newState: Int) {
152 override fun onPostCreate(savedInstanceState: Bundle?) {
153 // Run the default commands.
154 super.onPostCreate(savedInstanceState)
156 // Sync the state of the DrawerToggle after the default `onRestoreInstanceState()` has finished. This creates the navigation drawer icon.
157 actionBarDrawerToggle.syncState()
160 override fun onResume() {
161 // Run the default commands.
164 // 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.
165 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted.
166 // Populate Privacy Cell.
167 populatePrivacyCell()
168 } else { // The phone permission has not been granted.
169 // Check if the user has previously denied the storage permission.
170 if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) { // Show a dialog explaining the request first.
171 // Check to see if a phone permission dialog is already displayed. This happens if the app is restarted when the dialog is shown.
172 if (supportFragmentManager.findFragmentByTag(getString(R.string.phone_permission)) == null) { // No dialog is currently shown.
173 // Instantiate the phone permission dialog fragment.
174 val phonePermissionDialogFragment = PhonePermissionDialog()
176 // Show the phone permission alert dialog. The permission will be requested when the dialog is closed.
177 phonePermissionDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission))
179 } else { // Show the permission request directly.
180 // Request the read phone state permission. There is only one permission request in the app, so it has a request code of 0.
181 ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
186 override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean {
187 // Run the commands that correspond to the selected menu item.
188 when (menuItem.itemId) {
189 R.id.settings -> { // Settings.
190 // Create an intent to load the Settings activity.
191 val settingsIntent = Intent(this, SettingsActivity::class.java)
194 startActivity(settingsIntent)
197 R.id.permissions -> { // Permissions.
198 // Instantiate the permissions dialog fragment.
199 val permissionsDialogFragment = WebViewDialog().type(WebViewDialog.PERMISSIONS)
201 // Show the alert dialog.
202 permissionsDialogFragment.show(supportFragmentManager, getString(R.string.permissions))
205 R.id.privacy_policy -> { // Privacy Policy.
206 // Instantiate the privacy policy dialog fragment.
207 val privacyPolicyDialogFragment = WebViewDialog().type(WebViewDialog.PRIVACY_POLICY)
209 // Show the alert dialog.
210 privacyPolicyDialogFragment.show(supportFragmentManager, getString(R.string.privacy_policy))
213 R.id.changelog -> { // Changelog.
214 // Instantiate the changelog dialog fragment.
215 val changelogDialogFragment = WebViewDialog().type(WebViewDialog.CHANGELOG)
217 // Show the alert dialog.
218 changelogDialogFragment.show(supportFragmentManager, getString(R.string.changelog))
221 R.id.licenses -> { // Licenses.
222 // Instantiate the licenses dialog fragment.
223 val licensesDialogFragment = WebViewDialog().type(WebViewDialog.LICENSES)
225 // Show the alert dialog.
226 licensesDialogFragment.show(supportFragmentManager, getString(R.string.licenses))
229 R.id.contributors -> { // Contributors.
230 // Instantiate the contributors dialog fragment.
231 val contributorsDialogFragment = WebViewDialog().type(WebViewDialog.CONTRIBUTORS)
233 // Show the alert dialog.
234 contributorsDialogFragment.show(supportFragmentManager, getString(R.string.contributors))
237 R.id.news -> { // News.
238 // Create a news URL intent.
239 val newsUrlIntent = Intent(Intent.ACTION_VIEW)
241 // Add the URL to the intent.
242 newsUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell/")
245 startActivity(newsUrlIntent)
248 R.id.roadmap -> { // Roadmap.
249 // Create a roadmap URL intent.
250 val roadmapUrlIntent = Intent(Intent.ACTION_VIEW)
252 // Add the URL to the intent.
253 roadmapUrlIntent.data = Uri.parse("https://www.stoutner.com/category/privacy-cell-roadmap/")
256 startActivity(roadmapUrlIntent)
259 R.id.bug_tracker -> { // Bug tracker.
260 // Create a bug tracker URL intent.
261 val bugTrackerUrlIntent = Intent(Intent.ACTION_VIEW)
263 // Add the URL to the intent.
264 bugTrackerUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/issues")
267 startActivity(bugTrackerUrlIntent)
270 R.id.forum -> { // Forum.
271 // Create a forum URL intent.
272 val forumUrlIntent = Intent(Intent.ACTION_VIEW)
274 // Add the URL to the intent.
275 forumUrlIntent.data = Uri.parse("https://redmine.stoutner.com/projects/privacy-cell/boards")
278 startActivity(forumUrlIntent)
281 R.id.donations -> { // Donations.
282 // Create a donations URL intent.
283 val donationsUrlIntent = Intent(Intent.ACTION_VIEW)
285 // Add the URL to the intent.
286 donationsUrlIntent.data = Uri.parse("https://www.stoutner.com/donations/")
289 startActivity(donationsUrlIntent)
293 // Close the navigation drawer.
294 drawerLayout.closeDrawer(GravityCompat.START)
296 // Consume the click.
300 override fun onCloseStoragePermissionDialog() {
301 // Request the read phone state permission. There is only one permission request in the app, so it has a request code of 0.
302 ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
305 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
306 // Run the default commands.
307 super.onRequestPermissionsResult(requestCode, permissions, grantResults)
309 //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).
310 if (grantResults.isNotEmpty()) {
311 // Check to see if the read phone state permission was granted. If the dialog was canceled the grant results will be empty.
312 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // The read phone state permission was granted.
313 // Populate Privacy Cell.
314 populatePrivacyCell()
315 } else { // The read phone state permission was denied.
316 // Display the phone permission text on the main activity.
317 stingrayTextView.text = getString(R.string.phone_permission_text)
322 private fun populatePrivacyCell() {
323 // Listen to changes in the cell network state.
324 telephonyManager.listen(object : PhoneStateListener() {
325 override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
326 // Populate the stingray security information. <https://source.android.com/devices/tech/connect/acts-5g-testing>
327 if (telephonyDisplayInfo.networkType == TelephonyManager.NETWORK_TYPE_NR) { // This is a secure 5G NR SA network.
328 // Populate the image view.
329 stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.secure_5g_nr_sa))
332 stingrayTextView.text = getString(R.string.secure_from_stingray)
334 // Set the text color.
335 stingrayTextView.setTextColor(getColor(R.color.blue_text))
336 } else { // This is not a secure 5G NR SA network.
337 // Populate the image view.
338 stingrayImageView.setImageDrawable(AppCompatResources.getDrawable(context, R.drawable.not_secure))
341 stingrayTextView.text = getString(R.string.not_secure_from_stingray)
343 // Set the text color.
344 stingrayTextView.setTextColor(getColor(R.color.red_text))
347 // Get the strings that correspond to the network information.
348 val dataNetworkType = getNetworkType(telephonyDisplayInfo.networkType)
349 val additionalNetworkInfo = getAdditionalNetworkInfo(telephonyDisplayInfo.overrideNetworkType)
351 // Populate the data network text views.
352 dataNetworkTextView.text = getString(R.string.data_network, dataNetworkType[0])
353 dataNetworkDetailsTextView.text = dataNetworkType[1]
354 additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfo[0])
355 additionalNetworkInfoDetailsTextView.text = additionalNetworkInfo[1]
357 // Set the stingray click listener.
358 stingrayLinearLayout.setOnClickListener {
359 // Instantiate the stingray dialog fragment.
360 val stingrayDialogFragment = WebViewDialog().type(WebViewDialog.STINGRAY)
362 // Show the alert dialog.
363 stingrayDialogFragment.show(supportFragmentManager, getString(R.string.stingrays))
366 // Set the data network click listener.
367 dataNetworkLinearLayout.setOnClickListener {
368 // Instantiate the data network dialog fragment according to the network type.
369 val dataNetworkDialogFragment = when (telephonyDisplayInfo.networkType) {
370 TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
371 TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
372 TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
373 TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
374 TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
375 TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
376 TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
377 TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
378 TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
379 TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
380 TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
381 TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
382 TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
383 TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
384 TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
385 TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
386 TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
387 TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
388 TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
389 TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
390 else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
393 // Show the alert dialog.
394 dataNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
397 // Set the additional network info click listener.
398 additionalNetworkInfoLinearLayout.setOnClickListener {
399 // Instantiate the initial network info dialog fragment according to the network type.
400 val additionalNetworkInfoDialogFragment = when (telephonyDisplayInfo.overrideNetworkType) {
401 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NONE)
402 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_CA)
403 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_LTE_ADVANCED_PRO)
404 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA)
405 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
406 else -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE)
409 // Show the alert dialog.
410 additionalNetworkInfoDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
414 override fun onServiceStateChanged(serviceState: ServiceState) {
415 // 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).
416 val networkRegistrationInfo = serviceState.networkRegistrationInfoList[1]
418 // Get the voice network type.
419 val voiceNetworkType = getNetworkType(networkRegistrationInfo.accessNetworkTechnology)
421 // Populate the voice network text views.
422 voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkType[0])
423 voiceNetworkDetailsTextView.text = voiceNetworkType[1]
425 // Set the voice network click listener.
426 voiceNetworkLinearLayout.setOnClickListener {
427 // Instantiate the voice network dialog fragment according to the network type.
428 val voiceNetworkDialogFragment = when (networkRegistrationInfo.accessNetworkTechnology) {
429 TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
430 TelephonyManager.NETWORK_TYPE_GPRS -> WebViewDialog().type(WebViewDialog.NETWORK_GPRS)
431 TelephonyManager.NETWORK_TYPE_EDGE -> WebViewDialog().type(WebViewDialog.NETWORK_EDGE)
432 TelephonyManager.NETWORK_TYPE_UMTS -> WebViewDialog().type(WebViewDialog.NETWORK_UMTS)
433 TelephonyManager.NETWORK_TYPE_CDMA -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA)
434 TelephonyManager.NETWORK_TYPE_EVDO_0 -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0)
435 TelephonyManager.NETWORK_TYPE_EVDO_A -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A)
436 TelephonyManager.NETWORK_TYPE_1xRTT -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT)
437 TelephonyManager.NETWORK_TYPE_HSDPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA)
438 TelephonyManager.NETWORK_TYPE_HSUPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA)
439 TelephonyManager.NETWORK_TYPE_HSPA -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA)
440 TelephonyManager.NETWORK_TYPE_IDEN -> WebViewDialog().type(WebViewDialog.NETWORK_IDEN)
441 TelephonyManager.NETWORK_TYPE_EVDO_B -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_B)
442 TelephonyManager.NETWORK_TYPE_LTE -> WebViewDialog().type(WebViewDialog.NETWORK_LTE)
443 TelephonyManager.NETWORK_TYPE_EHRPD -> WebViewDialog().type(WebViewDialog.NETWORK_EHRPD)
444 TelephonyManager.NETWORK_TYPE_HSPAP -> WebViewDialog().type(WebViewDialog.NETWORK_HSPAP)
445 TelephonyManager.NETWORK_TYPE_GSM -> WebViewDialog().type(WebViewDialog.NETWORK_GSM)
446 TelephonyManager.NETWORK_TYPE_TD_SCDMA -> WebViewDialog().type(WebViewDialog.NETWORK_TD_SCDMA)
447 TelephonyManager.NETWORK_TYPE_IWLAN -> WebViewDialog().type(WebViewDialog.NETWORK_IWLAN)
448 TelephonyManager.NETWORK_TYPE_NR -> WebViewDialog().type(WebViewDialog.NETWORK_NR)
449 else -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN)
452 // Show the alert dialog.
453 voiceNetworkDialogFragment.show(supportFragmentManager, getString(R.string.voice_network))
456 }, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED or PhoneStateListener.LISTEN_SERVICE_STATE)
459 private fun getNetworkType(networkType: Int) : Array<String> {
460 // Return the string that corresponds to the network type.
461 return when(networkType) {
462 TelephonyManager.NETWORK_TYPE_UNKNOWN -> arrayOf(getString(R.string.unknown), "")
463 TelephonyManager.NETWORK_TYPE_GPRS -> arrayOf(getString(R.string.gprs), getString(R.string.gprs_detail))
464 TelephonyManager.NETWORK_TYPE_EDGE -> arrayOf(getString(R.string.edge), getString(R.string.edge_detail))
465 TelephonyManager.NETWORK_TYPE_UMTS -> arrayOf(getString(R.string.umts), getString(R.string.umts_detail))
466 TelephonyManager.NETWORK_TYPE_CDMA -> arrayOf(getString(R.string.cdma), getString(R.string.cdma_detail))
467 TelephonyManager.NETWORK_TYPE_EVDO_0 -> arrayOf(getString(R.string.evdo_0), getString(R.string.evdo_0_detail))
468 TelephonyManager.NETWORK_TYPE_EVDO_A -> arrayOf(getString(R.string.evdo_a), getString(R.string.evdo_a_detail))
469 TelephonyManager.NETWORK_TYPE_1xRTT -> arrayOf(getString(R.string.rtt), getString(R.string.rtt_detail))
470 TelephonyManager.NETWORK_TYPE_HSDPA -> arrayOf(getString(R.string.hsdpa), getString(R.string.hsdpa_detail))
471 TelephonyManager.NETWORK_TYPE_HSUPA -> arrayOf(getString(R.string.hsupa), getString(R.string.hsupa_detail))
472 TelephonyManager.NETWORK_TYPE_HSPA -> arrayOf(getString(R.string.hspa), getString(R.string.hspa_detail))
473 TelephonyManager.NETWORK_TYPE_IDEN -> arrayOf(getString(R.string.iden), getString(R.string.iden_detail))
474 TelephonyManager.NETWORK_TYPE_EVDO_B -> arrayOf(getString(R.string.evdo_b), getString(R.string.evdo_b_detail))
475 TelephonyManager.NETWORK_TYPE_LTE -> arrayOf(getString(R.string.lte), getString(R.string.lte_detail))
476 TelephonyManager.NETWORK_TYPE_EHRPD -> arrayOf(getString(R.string.ehrpd), getString(R.string.ehrpd_detail))
477 TelephonyManager.NETWORK_TYPE_HSPAP -> arrayOf(getString(R.string.hspap), getString(R.string.hspap_detail))
478 TelephonyManager.NETWORK_TYPE_GSM -> arrayOf(getString(R.string.gsm), getString(R.string.gsm_detail))
479 TelephonyManager.NETWORK_TYPE_TD_SCDMA -> arrayOf(getString(R.string.td_scdma), getString(R.string.td_scdma_detail))
480 TelephonyManager.NETWORK_TYPE_IWLAN -> arrayOf(getString(R.string.iwlan), getString(R.string.iwlan_detail))
481 TelephonyManager.NETWORK_TYPE_NR -> arrayOf(getString(R.string.nr), getString(R.string.nr_detail))
482 else -> arrayOf(getString(R.string.error), "")
486 private fun getAdditionalNetworkInfo(overrideNetworkType: Int) : Array<String> {
487 // Return the string that corresponds to the override network type.
488 return when(overrideNetworkType) {
489 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> arrayOf(getString(R.string.none), "")
490 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> arrayOf(getString(R.string.lte_ca), getString(R.string.lte_ca_detail))
491 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> arrayOf(getString(R.string.lte_advanced_pro), getString(R.string.lte_advanced_pro_detail))
492 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> arrayOf(getString(R.string.nr_nsa), getString(R.string.nr_nsa_detail))
493 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> arrayOf(getString(R.string.nr_nsa_mmwave), getString(R.string.nr_nsa_mmwave_detail))
494 else -> arrayOf(getString(R.string.error), "")