import android.telephony.ServiceState
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
+import android.view.MenuItem
+import android.view.View
import android.widget.ImageView
import android.widget.TextView
+import androidx.appcompat.app.ActionBar
+import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.content.res.AppCompatResources
+import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
+import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.DialogFragment
+import com.google.android.material.navigation.NavigationView
+
import com.stoutner.privacycell.R
import com.stoutner.privacycell.dialogs.PhonePermissionDialog
-class PrivacyCell : AppCompatActivity(), PhonePermissionDialog.StoragePermissionDialogListener {
+class PrivacyCell : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
// Declare the class variables.
private lateinit var context: Context
private lateinit var telephonyManager: TelephonyManager
+ private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
// Declare the views.
lateinit var secureFromStingrayImageView: ImageView
super.onCreate(savedInstanceState)
// Set the content view.
- setContentView(R.layout.privacy_cell_scrollview)
+ setContentView(R.layout.privacy_cell_drawerlayout)
// Get handles for the views.
+ val drawerLayout = findViewById<DrawerLayout>(R.id.drawerlayout)
+ val toolbar = findViewById<Toolbar>(R.id.toolbar)
secureFromStingrayImageView = findViewById(R.id.secure_from_stingray_imageview)
secureFromStingrayTextView = findViewById(R.id.secure_from_stingray_textview)
voiceNetworkTextView = findViewById(R.id.voice_network)
dataNetworkDetailsTextView = findViewById(R.id.data_network_details)
additionalNetworkInfoTextView = findViewById(R.id.additional_network_info)
additionalNetworkInfoDetailsTextView = findViewById(R.id.additional_network_info_details)
+ val navigationView = findViewById<NavigationView>(R.id.navigationview)
// Get handles for the context and the telephony manager.
context = this
telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
+
+ // Set the support action bar.
+ setSupportActionBar(toolbar)
+
+ // Get a handle for the action bar.
+ val actionBar = supportActionBar!!
+
+ // Set a custom view on the action bar.
+ actionBar.setCustomView(R.layout.app_bar_textview)
+
+ // Display the custom view.
+ actionBar.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
+
+ // Define a hamburger icon at the start of the app bar. It will be populated in `onPostCreate()`.
+ actionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer)
+
+ // Listen for touches on the navigation menu.
+ navigationView.setNavigationItemSelectedListener(this)
+
+ // Add a drawer listener.
+ drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
+ override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
+ // Do nothing.
+ }
+
+ override fun onDrawerOpened(drawerView: View) {
+ // Do nothing.
+ }
+
+ override fun onDrawerClosed(drawerView: View) {
+ // Reset the drawer icon when the drawer is closed. Otherwise, it is an arrow if the drawer is open when the app is restarted.
+ actionBarDrawerToggle.syncState()
+ }
+
+ override fun onDrawerStateChanged(newState: Int) {
+ // Do nothing.
+ }
+ })
+ }
+
+ override fun onPostCreate(savedInstanceState: Bundle?) {
+ // Run the default commands.
+ super.onPostCreate(savedInstanceState)
+
+ // Sync the state of the DrawerToggle after the default `onRestoreInstanceState()` has finished. This creates the navigation drawer icon.
+ actionBarDrawerToggle.syncState()
}
override fun onResume() {
else -> arrayOf(getString(R.string.error), "")
}
}
+
+ override fun onNavigationItemSelected(menuItem: MenuItem) : Boolean {
+ // TODO.
+ return true
+ }
}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ 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 Browser. If not, see <http://www.gnu.org/licenses/>. -->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/privacy_cell"
+ android:paddingBottom="4dp"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:textColor="?android:textColorPrimary" />
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ 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 Browser. If not, see <http://www.gnu.org/licenses/>. -->
+
+<androidx.drawerlayout.widget.DrawerLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/drawerlayout"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <androidx.coordinatorlayout.widget.CoordinatorLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent" >
+
+ <!-- The linear layout with `orientation="vertical"` moves the main content below the app bar layout. -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="vertical" >
+
+ <!-- The app bar theme must be specified here because the activity uses a `NoActionBar` theme. -->
+ <com.google.android.material.appbar.AppBarLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:background="?android:attr/colorBackground"
+ android:theme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar" >
+
+ <androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent" />
+ </com.google.android.material.appbar.AppBarLayout>
+
+ <!-- The main content is wrapped in a scroll view. -->
+ <ScrollView
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content" >
+
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="vertical"
+ android:padding="15dp" >
+
+ <!-- Secure from stingray. -->
+ <ImageView
+ android:id="@+id/secure_from_stingray_imageview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ tools:ignore="ContentDescription" />
+
+ <!-- The text color primary is only displayed if the read phone state permission is not granted. -->
+ <TextView
+ android:id="@+id/secure_from_stingray_textview"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginTop="10dp"
+ android:textColor="?android:textColorPrimary"
+ android:textSize="20sp"
+ android:textStyle="bold" />
+
+ <!-- Voice network. -->
+ <TextView
+ android:id="@+id/voice_network"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginTop="30dp"
+ android:textColor="@color/blue_text"
+ android:textSize="18sp"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/voice_network_details"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginBottom="10dp" />
+
+ <!-- Data network. -->
+ <TextView
+ android:id="@+id/data_network"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:textColor="@color/blue_text"
+ android:textSize="18sp"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/data_network_details"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:layout_marginBottom="10dp" />
+
+ <!-- Additional network info. -->
+ <TextView
+ android:id="@+id/additional_network_info"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center"
+ android:textColor="@color/blue_text"
+ android:textSize="18sp"
+ android:textStyle="bold" />
+
+ <TextView
+ android:id="@+id/additional_network_info_details"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:textAlignment="center" />
+ </LinearLayout>
+ </ScrollView>
+ </LinearLayout>
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
+
+ <!-- The navigation drawer. -->
+ <com.google.android.material.navigation.NavigationView
+ android:id="@+id/navigationview"
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_gravity="start"
+ app:menu="@menu/navigation_menu_top_appbar"
+ app:itemIconTint="@color/icon" />
+</androidx.drawerlayout.widget.DrawerLayout>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- 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 Browser. If not, see <http://www.gnu.org/licenses/>. -->
-
-<ScrollView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_height="match_parent"
- android:layout_width="wrap_content" >
-
- <LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:orientation="vertical"
- android:padding="15dp" >
-
- <!-- Secure from stingray. -->
- <ImageView
- android:id="@+id/secure_from_stingray_imageview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- tools:ignore="ContentDescription" />
-
- <!-- The text color primary is only displayed if the read phone state permission is not granted. -->
- <TextView
- android:id="@+id/secure_from_stingray_textview"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginTop="10dp"
- android:textColor="?android:textColorPrimary"
- android:textSize="20sp"
- android:textStyle="bold" />
-
- <!-- Voice network. -->
- <TextView
- android:id="@+id/voice_network"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginTop="30dp"
- android:textColor="@color/blue_text"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <TextView
- android:id="@+id/voice_network_details"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginBottom="10dp" />
-
- <!-- Data network. -->
- <TextView
- android:id="@+id/data_network"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:textColor="@color/blue_text"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <TextView
- android:id="@+id/data_network_details"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:layout_marginBottom="10dp" />
-
- <!-- Additional network info. -->
- <TextView
- android:id="@+id/additional_network_info"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center"
- android:textColor="@color/blue_text"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <TextView
- android:id="@+id/additional_network_info_details"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textAlignment="center" />
- </LinearLayout>
-</ScrollView>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ 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 Browser. If not, see <http://www.gnu.org/licenses/>. -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/permissions"
+ android:title="@string/permissions"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="10" />
+
+ <item
+ android:id="@+id/privacy_policy"
+ android:title="@string/privacy_policy"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="20" />
+
+ <item
+ android:id="@+id/changelog"
+ android:title="@string/changelog"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="30" />
+
+ <item
+ android:id="@+id/licenses"
+ android:title="@string/licenses"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="40" />
+
+ <item
+ android:id="@+id/contributors"
+ android:title="@string/contributors"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="50" />
+
+ <!-- If a group has an id, a line is drawn above it in the navigation view. -->
+ <group android:id="@+id/links" >
+ <item
+ android:id="@+id/news"
+ android:title="@string/news"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="60" />
+
+ <item
+ android:id="@+id/roadmap"
+ android:title="@string/roadmap"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="70" />
+
+ <item
+ android:id="@+id/bug_tracker"
+ android:title="@string/bug_tracker"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="80" />
+
+ <item
+ android:id="@+id/forum"
+ android:title="@string/forum"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="90" />
+ </group>
+
+ <!-- If a group has an id, a line is drawn above it in the navigation view. -->
+ <group android:id="@+id/donation_group" >
+ <item
+ android:id="@+id/donations"
+ android:title="@string/donations"
+ android:icon="@drawable/secure_5g_nr_sa"
+ android:orderInCategory="100" />
+ </group>
+</menu>
\ No newline at end of file
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
<resources>
- <style name="Theme.PrivacyCell" parent="Theme.AppCompat.DayNight">
+ <style name="Theme.PrivacyCell" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Main items. -->
<item name="android:navigationBarColor">?android:attr/colorBackground</item>
<item name="android:statusBarColor">?android:attr/colorBackground</item>
<!-- General. -->
<string name="privacy_cell">Privacy Cell</string>
<string name="cell">Cell</string>
+ <string name="open_navigation_drawer">Open navigation drawer</string>
+ <string name="close_navigation_drawer">Close navigation drawer</string>
- <!-- Text views. Android removes double spaces, but extra spaces can be manually specified with the Unicode `\u0020` formatting. -->
+ <!-- Text views. The `\n\n` code inserts a line break and should be preserved in translations.
+ Android removes double spaces, but extra spaces can be manually specified with the Unicode `\u0020` formatting.
+ The `%1$s` code inserts variables into the displayed text and should be preserved in translation. -->
+ <string name="secure_from_stingray">Your device is connected to a standalone 5G network.\n\nIt is secure from stingray IMSI man-in-the-middle attacks.</string>
+ <string name="not_secure_from_stingray">Your device is not connected to a standalone 5G network.\n\nIt is not secure from stingray IMSI man-in-the-middle attacks.</string>
<string name="voice_network">Voice network: \u0020 %1$s</string>
<string name="data_network">Data network: \u0020 %1$s</string>
<string name="additional_network_info">Additional network info: \u0020 %1$s</string>
+ <!-- Navigation menu. -->
+ <string name="permissions">Permissions</string>
+ <string name="privacy_policy">Privacy Policy</string>
+ <string name="changelog">Changelog</string>
+ <string name="licenses">Licenses</string>
+ <string name="contributors">Contributors</string>
+ <string name="news">News</string>
+ <string name="roadmap">Roadmap</string>
+ <string name="bug_tracker">Bug Tracker</string>
+ <string name="forum">Forum</string>
+ <string name="donations">Donations</string>
+
<!-- Network Types. -->
<string name="unknown">Unknown</string>
<string name="gprs">GPRS</string>
<string name="lte_nr_nsa_mmwave">LTE NR NSA mmWave</string>
<string name="lte_nr_nsa_mmwave_detail">Long Term Evolution New Radio Non-Standalone millimeter Wave</string>
- <!-- Stingray. -->
- <!-- The `\n\n` code inserts a line break and should be maintained in translations. -->
- <string name="secure_from_stingray">Your device is connected to a standalone 5G network.\n\nIt is secure from stingray IMSI man-in-the-middle attacks.</string>
- <string name="not_secure_from_stingray">Your device is not connected to a standalone 5G network.\n\nIt is not secure from stingray IMSI man-in-the-middle attacks.</string>
-
<!-- Phone permission dialog. -->
<string name="phone_permission">Phone Permission</string>
<string name="phone_permission_text">Privacy Cell needs the Read Phone State permission to determine the safety level of your cell connection.</string>
along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>. -->
<resources>
- <style name="Theme.PrivacyCell" parent="Theme.AppCompat.DayNight">
+ <style name="Theme.PrivacyCell" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Main items. -->
<item name="android:navigationBarColor">?android:attr/colorBackground</item>
<item name="android:statusBarColor">?android:attr/colorBackground</item>
}
dependencies {
- classpath "com.android.tools.build:gradle:7.0.0"
+ classpath 'com.android.tools.build:gradle:7.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
// NOTE: Do not place your application dependencies here; they belong