}
android {
- compileSdk 30
+ compileSdk 31
defaultConfig {
applicationId "com.stoutner.privacycell"
minSdk 30
- targetSdk 30
+ targetSdk 31
versionCode 5
versionName "1.4"
}
dependencies {
// Include the following AndroidX libraries.
implementation 'androidx.appcompat:appcompat:1.3.1'
- implementation 'androidx.core:core-ktx:1.6.0'
+ implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.webkit:webkit:1.4.0'
- implementation 'androidx.work:work-runtime-ktx:2.6.0'
+ implementation 'androidx.work:work-runtime-ktx:2.7.0'
// Include the Kotlin standard libraries. This should be the same version number listed in project build.gradle.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31'
--- /dev/null
+<!--
+ Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+
+ This file is part of Privacy Cell <https://www.stoutner.com/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.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with Privacy Cell. If not, see <http://www.gnu.org/licenses/>. -->
+
+<html>
+ <head>
+ <meta charset="UTF-8">
+
+ <link rel="stylesheet" href="../../css/theme.css">
+
+ <!-- Setting the color scheme instructs the WebView to respect `prefers-color-scheme` @media CSS. -->
+ <meta name="color-scheme" content="light dark">
+ </head>
+
+ <body>
+ <p><a href="https://developer.android.com/reference/android/telephony/TelephonyDisplayInfo#OVERRIDE_NETWORK_TYPE_NR_ADVANCED">New Radio Advanced</a>
+ is a marketing term that indicates that the carrier has done something beyond the bare minimum to qualify for the 5G logo.
+ It likely indicates that speeds beyond those typically associated with standard 5G are available.
+ For example, the carrier might be using the <a href="https://en.wikipedia.org/wiki/5G_NR#Frequency_bands">mmWave spectrum</a> (24.25–52.6 GHz), which goes really fast but doesn't penetrate walls.
+ Or, they might be using <a href="https://en.wikipedia.org/wiki/Carrier_aggregation">carrier aggregation</a> to increase bandwidth.</p>
+ </body>
+</html>
\ No newline at end of file
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
-import android.telephony.PhoneStateListener
+import android.telephony.PhoneStateListener // This can be replaced by `TelephonyCallback` once the minimum API >= 31.
import android.telephony.ServiceState
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
// Declare the class variables.
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
- private lateinit var phoneStateListener: PhoneStateListener
+ private lateinit var phoneStateListener: PhoneStateListener // The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
// Declare the class views.
private lateinit var drawerLayout: DrawerLayout
}
})
- // Define the phone state listener.
+ // Define the phone state listener. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
phoneStateListener = object : PhoneStateListener() {
override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
// Populate the stingray security information. <https://source.android.com/devices/tech/connect/acts-5g-testing>
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)
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_NSA_MMWAVE) // Can be removed once the minimum API >= 31.
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NR_ADVANCED)
+ else -> WebViewDialog().type(WebViewDialog.OVERRIDE_NETWORK_NONE)
}
// Show the alert dialog.
// Get a handle for the telephony manager.
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
- // Unregister the telephony manager listener.
+ // Unregister the telephony manager listener. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
}
// Get a handle for the telephony manager.
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
- // Listen to changes in the cell network state.
+ // Listen to changes in the cell network state. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED or PhoneStateListener.LISTEN_SERVICE_STATE)
}
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))
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> arrayOf(getString(R.string.nr_nsa_mmwave), getString(R.string.nr_nsa_mmwave_detail)) // Can be removed once the minimum API >= 31.
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED -> arrayOf(getString(R.string.nr_advanced), getString(R.string.nr_advanced_detail))
else -> arrayOf(getString(R.string.error), "")
}
}
const val OVERRIDE_NETWORK_LTE_CA = 27
const val OVERRIDE_NETWORK_LTE_ADVANCED_PRO = 28
const val OVERRIDE_NETWORK_NR_NSA = 29
- const val OVERRIDE_NETWORK_NR_NSA_MMWAVE = 30
+ const val OVERRIDE_NETWORK_NR_NSA_MMWAVE = 30 // Can be removed once the minimum API >= 31.
+ const val OVERRIDE_NETWORK_NR_ADVANCED = 31
}
// Define the class views.
// Set the title.
dialogBuilder.setTitle(R.string.nr_nsa_mmwave)
}
+
+ OVERRIDE_NETWORK_NR_ADVANCED -> {
+ // Set the icon.
+ dialogBuilder.setIcon(R.drawable.privacy_policy)
+
+ // Set the title.
+ dialogBuilder.setTitle(R.string.nr_advanced)
+ }
}
// Set the view.
OVERRIDE_NETWORK_LTE_ADVANCED_PRO -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) +
"/explanations/override_network_lte_advanced_pro.html")
OVERRIDE_NETWORK_NR_NSA -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_nr_nsa.html")
+ // The item below can be removed once the minimum API >= 31.
OVERRIDE_NETWORK_NR_NSA_MMWAVE -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_nr_nsa_mmwave.html")
+ OVERRIDE_NETWORK_NR_ADVANCED -> webView.loadUrl("https://appassets.androidplatform.net/assets/" + getString(R.string.asset_directory) + "/explanations/override_network_nr_advanced.html")
}
// Scroll the WebView if the saved instance state is not null.
import android.content.pm.PackageManager
import android.os.Binder
import android.os.IBinder
-import android.telephony.PhoneStateListener
+import android.telephony.PhoneStateListener // This can be replaced by `TelephonyCallback` once the minimum API >= 31.
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
// Define the class variables.
private var currentStatus = ""
- private lateinit var phoneStateListener: PhoneStateListener
+ private lateinit var phoneStateListener: PhoneStateListener // The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
inner class ServiceBinder : Binder() {
// Get a copy of this service as a binder.
// Start the foreground notification.
startForeground(NOTIFICATION_ID, notificationBuilder.build())
- // Define the phone state listener.
+ // Define the phone state listener. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
phoneStateListener = object : PhoneStateListener() {
override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
// Populate the notification according to the network type.
// Get a handle for the telephony manager.
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
- // Cancel the current listener if it exists.
+ // Cancel the current listener if it exists. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
- // Listen for changes to the phone state.
+ // Listen for changes to the phone state. The `PhoneStateListener` can be replaced by `TelephonyCallback` once the minimum API >= 31.
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
}
}
<string name="nr_nsa_detail">New Radio Non-Standalone</string>
<string name="nr_nsa_mmwave">NR NSA mmWave – 4G/5G</string>
<string name="nr_nsa_mmwave_detail">New Radio Non-Standalone millimeter Wave</string>
+ <string name="nr_advanced">NR Advanced - 5G</string>
+ <string name="nr_advanced_detail">New Radio Advanced</string>
<!-- Phone permission dialog. -->
<string name="phone_permission">Phone Permission</string>