From 5602d79ab0723eb64800d7021c63df4bab73a9d2 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Wed, 23 Apr 2025 16:31:36 -0700 Subject: [PATCH] Indicate which SIM cards are in use. https://redmine.stoutner.com/issues/1117 --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 17 +- app/src/main/assets/de/permissions.html | 9 +- app/src/main/assets/en/permissions.html | 12 +- app/src/main/assets/es/permissions.html | 10 +- app/src/main/assets/fr/permissions.html | 10 +- app/src/main/assets/it/permissions.html | 10 +- app/src/main/assets/ru/permissions.html | 10 +- .../activities/PrivacyCellActivity.kt | 67 ++++- .../activities/ProtocolsActivity.kt | 4 +- .../dialogs/NotificationPermissionDialog.kt | 26 +- .../dialogs/PhonePermissionDialog.kt | 26 +- .../privacycell/dialogs/WebViewDialog.kt | 32 +-- .../res/layout/privacy_cell_bottom_appbar.xml | 236 ++++++++++------- .../res/layout/privacy_cell_top_appbar.xml | 237 +++++++++++------- app/src/main/res/values/strings.xml | 3 +- build.gradle | 2 +- 17 files changed, 457 insertions(+), 258 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index cda9f4f..3fcd6ef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,12 +64,12 @@ android { dependencies { // Include the following AndroidX libraries. implementation 'androidx.appcompat:appcompat:1.7.0' - implementation 'androidx.core:core-ktx:1.15.0' + implementation 'androidx.core:core-ktx:1.16.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.webkit:webkit:1.13.0' - implementation 'androidx.work:work-runtime-ktx:2.10.0' + implementation 'androidx.work:work-runtime-ktx:2.10.1' // Include the Kotlin standard library. This should be the same version number listed in the project build.gradle. implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a0c5ca..dbdc5dc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + + + @@ -61,7 +64,8 @@ android:label="@string/cell" android:launchMode="singleTask" android:screenOrientation="fullUser" - android:exported="true" > + android:exported="true" + tools:ignore="DiscouragedApi" > @@ -74,21 +78,24 @@ android:name=".activities.SettingsActivity" android:label="@string/settings" android:parentActivityName=".activities.PrivacyCellActivity" - android:screenOrientation="fullUser" /> + android:screenOrientation="fullUser" + tools:ignore="DiscouragedApi" /> + android:screenOrientation="fullUser" + tools:ignore="DiscouragedApi" /> + android:screenOrientation="fullUser" + tools:ignore="DiscouragedApi" /> android.permission.READ_PHONE_STATE

Benötigt, um die vom Mobilfunk-Netzwerk genutzten Protokolle zu ermitteln.

+

Read phone numbers

+

android.permission.READ_PHONE_NUMBERS

+

Required to display the cell network name and phone number of the SIM card.

+

Zeige Benachrichtigungen

android.permission.POST_NOTIFICATIONS

Erlaubt Privacy Cell, ein Benachrichtigungs-Icon für die Echtzeit-Überwachung in der Status-Zeile anzuzeigen.

@@ -55,7 +59,8 @@

android.permission.RECEIVE_BOOT_COMPLETED

Erlaubt Privacy Cell die Echtzeit-Überwachung zu aktivieren, wenn das Smartphone gebootet wird.

-

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

-

Automatisch hinzugefügt für alle Apps mit API >= 33 (Android 13), um zu verhindern, dass sich andere Apps ohne expliziter Erlaubnis mit dynamischen BroadcastReceivern verbinden.

+

Dynamic receiver not exported

+

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

+

Automatisch hinzugefügt für alle Apps mit API >= 33 (Android >= 13), um zu verhindern, dass sich andere Apps ohne expliziter Erlaubnis mit dynamischen BroadcastReceivern verbinden.

\ No newline at end of file diff --git a/app/src/main/assets/en/permissions.html b/app/src/main/assets/en/permissions.html index 53a6548..5a07bab 100644 --- a/app/src/main/assets/en/permissions.html +++ b/app/src/main/assets/en/permissions.html @@ -36,7 +36,11 @@

android.permission.READ_PHONE_STATE

Required to determine which protocols are being used by the cell phone network.

-

Show Notifications

+

Read phone numbers

+

android.permission.READ_PHONE_NUMBERS

+

Required to display the cell network name and phone number of the SIM card.

+ +

Show notifications

android.permission.POST_NOTIFICATIONS

Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.

@@ -44,6 +48,7 @@

android.permission.FOREGROUND_SERVICE

Allows Privacy Cell to update the realtime monitoring notification icon when the app is not in the foreground.

+

Foreground service special use

android.permission.FOREGROUND_SERVICE_SPECIAL_USE

Specifies the type of foreground service. Special Use is for services that don't fit into any of the standard categories.

@@ -52,7 +57,8 @@

android.permission.RECEIVE_BOOT_COMPLETED

Allows Privacy Cell to enable the realtime monitoring service when the phone boots.

-

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

-

Automatically added to all apps targeting API >= 33 (Android 13) to prevent other apps from connecting to dynamic receivers without explicit permission.

+

Dynamic receiver not exported

+

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

+

Automatically added to all apps targeting API >= 33 (Android >= 13) to prevent other apps from connecting to dynamic receivers without explicit permission.

diff --git a/app/src/main/assets/es/permissions.html b/app/src/main/assets/es/permissions.html index 85fe579..21fb1bd 100644 --- a/app/src/main/assets/es/permissions.html +++ b/app/src/main/assets/es/permissions.html @@ -38,6 +38,10 @@

android.permission.READ_PHONE_STATE

Requerido para determinar qué protocolos se están usando por la red del teléfono celular.

+

Read phone numbers

+

android.permission.READ_PHONE_NUMBERS

+

Required to display the cell network name and phone number of the SIM card.

+

Mostrar notificaciones

android.permission.POST_NOTIFICATIONS

Permite a Privacy Cell mostrar un icono de notificación de supervisión en tiempo real en la barrra de estado.

@@ -46,6 +50,7 @@

android.permission.FOREGROUND_SERVICE

Permite a Privacy Cell actualizar el icono de notificación de supervisión cuando la aplicación no está en primer plano.

+

Foreground service special use

android.permission.FOREGROUND_SERVICE_SPECIAL_USE

Especifica el tipo de servicio en primer plano. El uso especial es para servicios que no encajan en ninguna de las categorías estándar.

@@ -54,7 +59,8 @@

android.permission.RECEIVE_BOOT_COMPLETED

Permite a Privacy Cell activar el servicio de monitorización en tiempo real al arrancar el teléfono.

-

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

-

Se añade automáticamente a todas las aplicaciones con API >= 33 (Android 13) para impedir que otras aplicaciones se conecten a receptores dinámicos sin permiso explícito.

+

Dynamic receiver not exported

+

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

+

Se añade automáticamente a todas las aplicaciones con API >= 33 (Android >= 13) para impedir que otras aplicaciones se conecten a receptores dinámicos sin permiso explícito.

diff --git a/app/src/main/assets/fr/permissions.html b/app/src/main/assets/fr/permissions.html index 7b1d762..b3151aa 100644 --- a/app/src/main/assets/fr/permissions.html +++ b/app/src/main/assets/fr/permissions.html @@ -38,6 +38,10 @@

android.permission.READ_PHONE_STATE

Nécessaire pour déterminer quels protocoles sont utilisés par le réseau de téléphonie mobile.

+

Read phone numbers

+

android.permission.READ_PHONE_NUMBERS

+

Required to display the cell network name and phone number of the SIM card.

+

Afficher les Notifications

android.permission.POST_NOTIFICATIONS

Permet à Privacy Cell d'afficher une icône de notification de surveillance en temps réel dans la barre d'état.

@@ -46,6 +50,7 @@

android.permission.FOREGROUND_SERVICE

Permet à Privacy Cell de mettre à jour l'icône de notification de surveillance en temps réel lorsque l'application n'est pas au premier plan.

+

Foreground service special use

android.permission.FOREGROUND_SERVICE_SPECIAL_USE

Spécifie le type de service de premier plan. L'utilisation spécifique concerne les services qui n'entrent dans aucune des catégories standard.

@@ -54,7 +59,8 @@

android.permission.RECEIVE_BOOT_COMPLETED

Permet à Privacy Cell d'activer le service de surveillance en temps réel lorsque le téléphone démarre.

-

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

-

Ajout automatique à toutes les applications ciblant l'API >= 33 (Android 13) pour empêcher les autres applications de se connecter aux destinataires dynamiques sans autorisation explicite.

+

Dynamic receiver not exported

+

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

+

Ajout automatique à toutes les applications ciblant l'API >= 33 (Android >= 13) pour empêcher les autres applications de se connecter aux destinataires dynamiques sans autorisation explicite.

diff --git a/app/src/main/assets/it/permissions.html b/app/src/main/assets/it/permissions.html index 1c26499..ff70a25 100644 --- a/app/src/main/assets/it/permissions.html +++ b/app/src/main/assets/it/permissions.html @@ -38,6 +38,10 @@

android.permission.READ_PHONE_STATE

Richiesta per determinare i protocolli utilizzati dalla rete.

+

Read phone numbers

+

android.permission.READ_PHONE_NUMBERS

+

Required to display the cell network name and phone number of the SIM card.

+

Mostra notifiche

android.permission.POST_NOTIFICATIONS

Permette a Privacy Cell di mostrare una icona di notifica di monitoraggio in tempo reale nella barra di stato.

@@ -46,6 +50,7 @@

android.permission.FOREGROUND_SERVICE

Permette a Privacy Cell di aggiornare licona di notifica di monitoraggio in tempo reale anche quando la app non è in primo piano.

+

Foreground service special use

android.permission.FOREGROUND_SERVICE_SPECIAL_USE

Specifica il tipo di servizio in primo piano. L'utilizzo speciale è per i servizi che non ricadono in nessuna delle categorie standard.

@@ -54,7 +59,8 @@

android.permission.RECEIVE_BOOT_COMPLETED

Permette a Privacy Cell di abilitare il servizio di monitoraggio in tempo reale durante l'avvio del dispositivo.

-

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

-

Aggiunta automaticamente a tutte le App che hanno come target API >= 33 (Android 13) per impedire ad altre App di connettersi ai ricevitori dinamici senza una autorizzazione esplicita.

+

Dynamic receiver not exported

+

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

+

Aggiunta automaticamente a tutte le App che hanno come target API >= 33 (Android >= 13) per impedire ad altre App di connettersi ai ricevitori dinamici senza una autorizzazione esplicita.

diff --git a/app/src/main/assets/ru/permissions.html b/app/src/main/assets/ru/permissions.html index 4817965..561ed41 100644 --- a/app/src/main/assets/ru/permissions.html +++ b/app/src/main/assets/ru/permissions.html @@ -36,6 +36,10 @@

android.permission.READ_PHONE_STATE

Необходим для определения используемых протоколов в сети сотовой связи.

+

Read phone numbers

+

android.permission.READ_PHONE_NUMBERS

+

Required to display the cell network name and phone number of the SIM card.

+

Отображение уведомлений

android.permission.POST_NOTIFICATIONS

Разрешает Privacy Cell отображать значок уведомления о мониторинге в реальном времени в строке состояния.

@@ -44,6 +48,7 @@

android.permission.FOREGROUND_SERVICE

Разрешает Privacy Cell обновлять значок уведомления о мониторинге в реальном времени при работе приложения в фоновом режиме.

+

Foreground service special use

android.permission.FOREGROUND_SERVICE_SPECIAL_USE

Определяет тип сервиса фонового режима. Специальное использование предназначено для сервисов, которые не соответствуют ни одной из @@ -53,7 +58,8 @@

android.permission.RECEIVE_BOOT_COMPLETED

Разрешает Privacy Cell включать службу мониторинга в реальном времени при загрузке телефона.

-

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

-

Автоматически добавляется во все приложения, использующие API >= 33 (Android 13) для предотвращения подключения других приложений к динамическим приемникам без явного разрешения.

+

Dynamic receiver not exported

+

com.stoutner.privacycell.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION

+

Автоматически добавляется во все приложения, использующие API >= 33 (Android >= 13) для предотвращения подключения других приложений к динамическим приемникам без явного разрешения.

diff --git a/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt b/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt index f450d86..3b89b88 100644 --- a/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt +++ b/app/src/main/java/com/stoutner/privacycell/activities/PrivacyCellActivity.kt @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * SPDX-FileCopyrightText: 2021-2022 Soren Stoutner + * SPDX-FileCopyrightText: 2021-2022, 2025 Soren Stoutner * * This file is part of Privacy Cell . * @@ -28,9 +28,11 @@ import android.app.ActivityManager import android.content.Context import android.content.Intent import android.content.pm.PackageManager +import android.os.Build import android.os.Bundle import android.telephony.PhoneStateListener // This can be replaced by `TelephonyCallback` once the minimum API >= 31. import android.telephony.ServiceState +import android.telephony.SubscriptionManager import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyManager import android.view.MenuItem @@ -44,6 +46,7 @@ import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.Toolbar +import androidx.cardview.widget.CardView import androidx.core.app.ActivityCompat import androidx.core.net.toUri import androidx.core.view.GravityCompat @@ -70,7 +73,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Declare the class views. private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle private lateinit var drawerLayout: DrawerLayout - private lateinit var overallStatusLinearLayout: LinearLayout + private lateinit var overallStatusCardView: CardView private lateinit var overallStatusImageView: ImageView private lateinit var overallStatusTextView: TextView @@ -102,15 +105,17 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Get handles for the views. drawerLayout = findViewById(R.id.drawerlayout) val toolbar = findViewById(R.id.toolbar) - overallStatusLinearLayout = findViewById(R.id.overall_status_linearlayout) + overallStatusCardView = findViewById(R.id.overall_status_cardview) overallStatusImageView = findViewById(R.id.overall_status_imageview) overallStatusTextView = findViewById(R.id.overall_status_textview) - val voiceNetworkLinearLayout = findViewById(R.id.voice_network_linearlayout) + val voiceNetworkCardView = findViewById(R.id.voice_network_cardview) val voiceNetworkTextView = findViewById(R.id.voice_network) val voiceNetworkDetailsTextView = findViewById(R.id.voice_network_details) + val voiceNetworkSubscriptionInfoTextView = findViewById(R.id.voice_network_subscription_info) val dataNetworkLinearLayout = findViewById(R.id.data_network_linearlayout) val dataNetworkTextView = findViewById(R.id.data_network) val dataNetworkDetailsTextView = findViewById(R.id.data_network_details) + val dataNetworkSubscriptionInfoTextView = findViewById(R.id.data_network_subscription_info) val additionalNetworkInfoLinearLayout = findViewById(R.id.additional_network_info_linearlayout) val additionalNetworkInfoTextView = findViewById(R.id.additional_network_info) val additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details) @@ -157,6 +162,9 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Instantiate the protocol helper. val protocolHelper = ProtocolHelper() + // Get a handle for the subscription manager. + val subscriptionManager = getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager + // Define the phone state listener. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31. phoneStateListener = object : PhoneStateListener() { @Deprecated("Deprecated in Java") @@ -173,9 +181,31 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem // Get the voice network type. val voiceNetworkStringArray = protocolHelper.getNetworkTypeStringArray(voiceNetworkTypeInt, applicationContext) + // Get the default voice subscription id. + val voiceSubscriptionId = SubscriptionManager.getDefaultVoiceSubscriptionId() + + // Create the voice subscription info string. + var voiceSubscriptionInfoString = "" + + // Populate the voice carrier info string if the appropriate permission has been granted. + if (ActivityCompat.checkSelfPermission(applicationContext, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED) { + // Populate the voice carrier info string. The deprecated command must be used until the API >= 33. + voiceSubscriptionInfoString = if (Build.VERSION.SDK_INT <= 32) + "${subscriptionManager.getActiveSubscriptionInfo(voiceSubscriptionId).carrierName} – ${subscriptionManager.getActiveSubscriptionInfo(voiceSubscriptionId).number}" + else + "${subscriptionManager.getActiveSubscriptionInfo(voiceSubscriptionId).carrierName} – ${subscriptionManager.getPhoneNumber(voiceSubscriptionId)}" + } + // Populate the voice network text views. voiceNetworkTextView.text = getString(R.string.voice_network, voiceNetworkStringArray[0]) voiceNetworkDetailsTextView.text = voiceNetworkStringArray[1] + voiceNetworkSubscriptionInfoTextView.text = voiceSubscriptionInfoString + + // Hide the voice network details text view if it is empty, which happens with Wi-Fi calling. + if (voiceNetworkDetailsTextView.text.isNullOrBlank()) + voiceNetworkDetailsTextView.visibility = View.GONE + else + voiceNetworkDetailsTextView.visibility = View.VISIBLE // Set the color of the voice network. when (voiceNetworkSecurityStatus) { @@ -185,7 +215,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem } // Set the voice network click listener. - voiceNetworkLinearLayout.setOnClickListener { + voiceNetworkCardView.setOnClickListener { // Instantiate the voice network dialog fragment according to the network type. val voiceNetworkDialogFragment = when (voiceNetworkTypeInt) { TelephonyManager.NETWORK_TYPE_UNKNOWN -> WebViewDialog().type(WebViewDialog.NETWORK_UNKNOWN) @@ -195,7 +225,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem 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_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) @@ -233,9 +263,25 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem val dataNetworkStringArray = protocolHelper.getNetworkTypeStringArray(dataNetworkTypeInt, applicationContext) val additionalNetworkInfoStringArray = protocolHelper.getAdditionalNetworkInfoStringArray(additionalNetworkInfoTypeInt, applicationContext) + // Get the active data subscription id. + val dataSubscriptionId = SubscriptionManager.getActiveDataSubscriptionId() + + // Create the data carrier info string. + var dataSubscriptionInfoString = "" + + // Populate the data carrier info string if the appropriate permission has been granted. + if (ActivityCompat.checkSelfPermission(applicationContext, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED) { + // Populate the data carrier info string. The deprecated command must be used until the API >= 33. + dataSubscriptionInfoString = if (Build.VERSION.SDK_INT <= 32) + "${subscriptionManager.getActiveSubscriptionInfo(dataSubscriptionId).carrierName} – ${subscriptionManager.getActiveSubscriptionInfo(dataSubscriptionId).number}" + else + "${subscriptionManager.getActiveSubscriptionInfo(dataSubscriptionId).carrierName} – ${subscriptionManager.getPhoneNumber(dataSubscriptionId)}" + } + // Populate the data network text views. dataNetworkTextView.text = getString(R.string.data_network, dataNetworkStringArray[0]) dataNetworkDetailsTextView.text = dataNetworkStringArray[1] + dataNetworkSubscriptionInfoTextView.text = dataSubscriptionInfoString additionalNetworkInfoTextView.text = getString(R.string.additional_network_info, additionalNetworkInfoStringArray[0]) additionalNetworkInfoDetailsTextView.text = additionalNetworkInfoStringArray[1] @@ -264,7 +310,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem 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_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) @@ -334,7 +380,8 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem super.onStart() // Check to see if the read phone state permission has been granted. These commands need to be run on every start so that the listener is reregistered. - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. + if ((ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) && + (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED)) { // The phone permissions have been granted. // Register the telephony manager listener. registerTelephonyManagerListener() } else { // The phone permission has not been granted. @@ -350,7 +397,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem } } else { // Show the permission request directly. // Request the read phone state permission. - ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), PHONE_PERMISSION_REQUEST_CODE) + ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS), PHONE_PERMISSION_REQUEST_CODE) } } } @@ -570,7 +617,7 @@ class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItem } // Set the overall status click listener. - overallStatusLinearLayout.setOnClickListener { + overallStatusCardView.setOnClickListener { // Instantiate the stingray dialog fragment. val stingrayDialogFragment = WebViewDialog().type(overallStatusDialogTypeInt) diff --git a/app/src/main/java/com/stoutner/privacycell/activities/ProtocolsActivity.kt b/app/src/main/java/com/stoutner/privacycell/activities/ProtocolsActivity.kt index c189c24..63a55a8 100644 --- a/app/src/main/java/com/stoutner/privacycell/activities/ProtocolsActivity.kt +++ b/app/src/main/java/com/stoutner/privacycell/activities/ProtocolsActivity.kt @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-3.0-or-later - * SPDX-FileCopyrightText: 2022 Soren Stoutner + * SPDX-FileCopyrightText: 2022, 2025 Soren Stoutner * * This file is part of Privacy Cell . * @@ -122,7 +122,7 @@ class ProtocolsActivity : AppCompatActivity() { getString(R.string.cdma_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_CDMA) getString(R.string.evdo_0_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_0) getString(R.string.evdo_a_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_EVDO_A) - getString(R.string.rtt_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_1xRTT) + getString(R.string.rtt_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_1XRTT) getString(R.string.hsdpa_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_HSDPA) getString(R.string.hsupa_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_HSUPA) getString(R.string.hspa_detail) -> WebViewDialog().type(WebViewDialog.NETWORK_HSPA) diff --git a/app/src/main/java/com/stoutner/privacycell/dialogs/NotificationPermissionDialog.kt b/app/src/main/java/com/stoutner/privacycell/dialogs/NotificationPermissionDialog.kt index 9989945..63a4591 100644 --- a/app/src/main/java/com/stoutner/privacycell/dialogs/NotificationPermissionDialog.kt +++ b/app/src/main/java/com/stoutner/privacycell/dialogs/NotificationPermissionDialog.kt @@ -1,20 +1,20 @@ -/* - * Copyright 2021-2022 Soren Stoutner . +/* SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2021-2022 Soren Stoutner * - * This file is part of Privacy Cell . + * This file is part of Privacy Cell . * - * Privacy Cell is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. * - * Privacy Cell is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. * - * You should have received a copy of the GNU General Public License - * along with Privacy Cell. If not, see . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ package com.stoutner.privacycell.dialogs diff --git a/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt b/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt index 745c7a7..d8b880c 100644 --- a/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt +++ b/app/src/main/java/com/stoutner/privacycell/dialogs/PhonePermissionDialog.kt @@ -1,20 +1,20 @@ -/* - * Copyright 2021-2022 Soren Stoutner . +/* SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2021-2022 Soren Stoutner * - * This file is part of Privacy Cell . + * This file is part of Privacy Cell . * - * Privacy Cell is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. * - * Privacy Cell is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. * - * You should have received a copy of the GNU General Public License - * along with Privacy Cell. If not, see . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ package com.stoutner.privacycell.dialogs diff --git a/app/src/main/java/com/stoutner/privacycell/dialogs/WebViewDialog.kt b/app/src/main/java/com/stoutner/privacycell/dialogs/WebViewDialog.kt index aa7d296..071f17c 100644 --- a/app/src/main/java/com/stoutner/privacycell/dialogs/WebViewDialog.kt +++ b/app/src/main/java/com/stoutner/privacycell/dialogs/WebViewDialog.kt @@ -1,20 +1,20 @@ -/* - * Copyright 2021-2022 Soren Stoutner . +/* SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2021-2022, 2025 Soren Stoutner * - * This file is part of Privacy Cell . + * This file is part of Privacy Cell . * - * Privacy Cell is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. * - * Privacy Cell is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. * - * You should have received a copy of the GNU General Public License - * along with Privacy Cell. If not, see . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ package com.stoutner.privacycell.dialogs @@ -54,7 +54,7 @@ class WebViewDialog : DialogFragment() { const val NETWORK_CDMA = 11 const val NETWORK_EVDO_0 = 12 const val NETWORK_EVDO_A = 13 - const val NETWORK_1xRTT = 14 + const val NETWORK_1XRTT = 14 const val NETWORK_HSDPA = 15 const val NETWORK_HSUPA = 16 const val NETWORK_HSPA = 17 @@ -217,7 +217,7 @@ class WebViewDialog : DialogFragment() { dialogBuilder.setTitle(R.string.evdo_a) } - NETWORK_1xRTT -> { + NETWORK_1XRTT -> { // Set the icon. dialogBuilder.setIcon(R.drawable.protocols) @@ -428,7 +428,7 @@ class WebViewDialog : DialogFragment() { NETWORK_CDMA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_cdma.html") NETWORK_EVDO_0 -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_evdo_0.html") NETWORK_EVDO_A -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_evdo_a.html") - NETWORK_1xRTT -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_1xrtt.html") + NETWORK_1XRTT -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_1xrtt.html") NETWORK_HSDPA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_hsdpa.html") NETWORK_HSUPA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_hsupa.html") NETWORK_HSPA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/network_hspa.html") diff --git a/app/src/main/res/layout/privacy_cell_bottom_appbar.xml b/app/src/main/res/layout/privacy_cell_bottom_appbar.xml index e2fe4f1..9f0f033 100644 --- a/app/src/main/res/layout/privacy_cell_bottom_appbar.xml +++ b/app/src/main/res/layout/privacy_cell_bottom_appbar.xml @@ -52,117 +52,171 @@ + android:orientation="vertical" > - - - - - - + + - + android:orientation="vertical" + android:layout_margin="20dp" + tools:ignore="UseCompoundDrawables" > + + + + + + + - - - + android:layout_width="match_parent" + android:layout_marginTop="10dp" + android:layout_marginStart="20dp" + android:layout_marginEnd="20dp" + android:layout_marginBottom="10dp" > - - + android:orientation="vertical" + android:layout_margin="15dp" > + + + + + + + + - - - - - - - - - - - + android:layout_width="match_parent" + android:layout_marginTop="10dp" + android:layout_marginStart="20dp" + android:layout_marginEnd="20dp" + android:layout_marginBottom="10dp" > - - + android:orientation="vertical" + android:layout_margin="15dp" > + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/privacy_cell_top_appbar.xml b/app/src/main/res/layout/privacy_cell_top_appbar.xml index 614c2e3..1f22959 100644 --- a/app/src/main/res/layout/privacy_cell_top_appbar.xml +++ b/app/src/main/res/layout/privacy_cell_top_appbar.xml @@ -64,117 +64,172 @@ + android:orientation="vertical" > - - - - - - + + - + android:orientation="vertical" + android:layout_margin="20dp" + tools:ignore="UseCompoundDrawables" > + + + + + + + - - - + android:layout_width="match_parent" + android:layout_marginTop="10dp" + android:layout_marginStart="20dp" + android:layout_marginEnd="20dp" + android:layout_marginBottom="10dp" > - - + android:orientation="vertical" + android:layout_margin="15dp" > + + + + + + + + - - - - - - - - - - - + android:layout_width="match_parent" + android:layout_marginTop="10dp" + android:layout_marginStart="20dp" + android:layout_marginEnd="20dp" + android:layout_marginBottom="10dp" > - - + android:orientation="vertical" + android:layout_margin="15dp" > + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4a18d0c..28bf741 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -121,7 +121,8 @@ Phone Permission - Privacy Cell needs the Read Phone State permission to determine the safety level of your cell connection. + Privacy Cell needs the Read Phone State and Read Phone Numbers permissions to determine the safety level of your cell connection and display the phone number of the + active SIM card. Notification Permission Privacy Cell needs the Post Notification permission to display realtime monitoring notifications. OK diff --git a/build.gradle b/build.gradle index 081b389..7bad566 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.9.1' + classpath 'com.android.tools.build:gradle:8.9.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.0" // NOTE: Do not place your application dependencies here; they belong -- 2.47.2