/*
- * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
}
android {
- compileSdk 32
+ compileSdk 33
defaultConfig {
applicationId "com.stoutner.privacycell"
minSdk 30
- targetSdk 32
+ targetSdk 33
versionCode 10
versionName "1.8.1"
}
dependencies {
// Include the following AndroidX libraries.
- implementation 'androidx.appcompat:appcompat:1.4.2'
- implementation 'androidx.core:core-ktx:1.8.0'
+ implementation 'androidx.appcompat:appcompat:1.5.1'
+ implementation 'androidx.core:core-ktx:1.9.0'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
- implementation 'androidx.webkit:webkit:1.4.0'
+ implementation 'androidx.webkit:webkit:1.5.0'
implementation 'androidx.work:work-runtime-ktx:2.7.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:1.7.10'
+ implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20'
// Include the Google material library.
- implementation 'com.google.android.material:material:1.6.1'
-}
\ No newline at end of file
+ implementation 'com.google.android.material:material:1.7.0'
+}
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto" >
- <!-- Required to read cell network information. -->
+ <!-- Required to read cell network information. <Dangerous permission> -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <!-- Required to display a realtime notification icon. -->
+ <!-- Required to display a notification. <Dangerous permission> -->
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+
+ <!-- Required to run a foreground service (which is the only type of service that can display notifications). -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- Required to start the realtime notification icon at boot. -->
</intent-filter>
</receiver>
</application>
-</manifest>
\ No newline at end of file
+</manifest>
</head>
<body>
- <h3>1.8.1 (Version Code 10)</h3>
- <p>8. August 2022 - Mindest-API 30, Ziel-API 32</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-8-1/">1.8.1</a> (Version Code 10)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=ab7601a6d91b6035862bb47b1ac259855e3aba3b">8. August 2022</a> - Mindest-API 30, Ziel-API 32</p>
<ul>
<li>Fehler behoben, durch den nach Änderung der Netzwerk-Verbindung <a href="https://redmine.stoutner.com/issues/864">Benachrichtigungen wieder aktiviert</a> wurden.</li>
<li><a href="https://redmine.stoutner.com/issues/884">Zweifarbig violetten Text</a> zum Nachtmodus (Theme) hinzugefügt.</li>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Bernhard G. Keller. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<body>
<h3>Copyright</h3>
- <p>Privacy Cell ist Copyright © 2021-2022 von <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
+ <p>Privacy Cell ist Copyright 2021-2022 von <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
<h3>Lizenz</h3>
<p>Privacy Cell wird unter der <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+-Lizenz</a> veröffentlicht. Den gesamten Text der Lizenz finden Sie unterhalb.
<p><svg class="icon"><use href="../images/groups_filled.svg#icon"/></svg> groups_filled.</p>
<p><svg class="icon"><use href="../images/list_alt_rounded.svg#icon"/></svg> list_alt_rounded.</p>
<p><svg class="icon"><use href="../images/map_rounded.svg#icon"/></svg> map_rounded.</p>
+ <p><svg class="icon"><use href="../images/notification_important_rounded_filled.svg#icon"/></svg> notification_important_<wbr>rounded_filled.</p>
<p><svg class="icon"><use href="../images/payments_rounded.svg#icon"/></svg> payments_rounded.</p>
<p><svg class="icon"><use href="../images/phone_android_outlined.svg#icon"/></svg> phone_android_outlined.</p>
<p><svg class="icon"><use href="../images/policy_filled.svg#icon"/></svg> policy_filled.</p>
implied. See the License for
the specific language governing
permissions and limitations
-under the License.</pre>
\ No newline at end of file
+under the License.</pre>
+ </body>
+</html>
<p>Privacy Cell verwendet folgende Berechtigungen:</p>
<h3>Telefon-Status und Identität lesen</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission. READ_PHONE_STATE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission.<wbr>READ_PHONE_STATE</a></p>
<p>Benötigt, um die vom Mobilfunk-Netzwerk genutzten Protokolle zu ermitteln.</p>
<h3>Vordergrund-Service ausführen</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission. FOREGROUND_SERVICE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission.<wbr>FOREGROUND_SERVICE</a></p>
<p>Erlaubt Privacy Cell, ein Benachrichtigungs-Icon für die Echtzeit-Überwachung in der Status-Zeile anzuzeigen.</p>
<h3>Ausführung bei Systemstart</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission. RECEIVE_BOOT_COMPLETED</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission.<wbr>RECEIVE_BOOT_COMPLETED</a></p>
<p>Erlaubt Privacy Cell die Echtzeit-Überwachung zu aktivieren, wenn das Smartphone gebootet wird.</p>
</body>
</html>
\ No newline at end of file
</head>
<body>
- <h3>1.8.1 (version code 10)</h3>
- <p>8 August 2022 - minimum API 30, target API 32</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-8-1/">1.8.1</a> (version code 10)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=ab7601a6d91b6035862bb47b1ac259855e3aba3b">8 August 2022</a> - minimum API 30, target API 32</p>
<ul>
<li>Fix a bug that <a href="https://redmine.stoutner.com/issues/864">re-enabled notifications</a> when the network changed.</li>
<li>Add <a href="https://redmine.stoutner.com/issues/884">dual-toned violet text</a> to the Night Theme.</li>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
<body>
<h3>Copyright</h3>
- <p>Privacy Cell copyright © 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
+ <p>Privacy Cell copyright 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
<h3>License</h3>
<p>Privacy Cell is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>. The full text of the license is below.
<p><svg class="icon"><use href="../images/groups_filled.svg#icon"/></svg> groups_filled.</p>
<p><svg class="icon"><use href="../images/list_alt_rounded.svg#icon"/></svg> list_alt_rounded.</p>
<p><svg class="icon"><use href="../images/map_rounded.svg#icon"/></svg> map_rounded.</p>
+ <p><svg class="icon"><use href="../images/notification_important_rounded_filled.svg#icon"/></svg> notification_important_<wbr>rounded_filled.</p>
<p><svg class="icon"><use href="../images/payments_rounded.svg#icon"/></svg> payments_rounded.</p>
<p><svg class="icon"><use href="../images/phone_android_outlined.svg#icon"/></svg> phone_android_outlined.</p>
<p><svg class="icon"><use href="../images/policy_filled.svg#icon"/></svg> policy_filled.</p>
implied. See the License for
the specific language governing
permissions and limitations
-under the License.</pre>
\ No newline at end of file
+under the License.</pre>
+ </body>
+</html>
<p>Privacy Cell uses the following permissions.</p>
<h3>Read phone status and identity</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission. READ_PHONE_STATE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission.<wbr>READ_PHONE_STATE</a></p>
<p>Required to determine which protocols are being used by the cell phone network.</p>
<h3>Run foreground service</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission. FOREGROUND_SERVICE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission.<wbr>FOREGROUND_SERVICE</a></p>
<p>Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.</p>
<h3>Run at startup</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission. RECEIVE_BOOT_COMPLETED</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission.<wbr>RECEIVE_BOOT_COMPLETED</a></p>
<p>Allows Privacy Cell to enable the realtime monitoring service when the phone boots.</p>
</body>
</html>
\ No newline at end of file
</head>
<body>
- <h3>1.8.1 (versión del código 10)</h3>
- <p>8 de agosto de 2022 - API mínimo 30, API objetivo 32</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-8-1/">1.8.1</a> (versión del código 10)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=ab7601a6d91b6035862bb47b1ac259855e3aba3b">8 de agosto de 2022</a> - API mínimo 30, API objetivo 32</p>
<ul>
<li>Corregir un error que <a href="https://redmine.stoutner.com/issues/864">volvía a activar las notificaciones</a> cuando cambiaba la red.</li>
<li>Añadir <a href="https://redmine.stoutner.com/issues/884">un texto violeta de doble tono</a>al Tema Nocturno.</li>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Jose A. León. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<body>
<h3>Copyright</h3>
- <p>Copyright de Privacy Cell © 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
+ <p>Copyright de Privacy Cell 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
<h3>Licencia</h3>
<p>Privacy Cell se libera bajo la <a href="https://www.gnu.org/licenses/gpl-3.0.html">licencia GPLv3+</a>. El texto completo de la licencia se muestra abajo.
<p><svg class="icon"><use href="../images/groups_filled.svg#icon"/></svg> groups_filled.</p>
<p><svg class="icon"><use href="../images/list_alt_rounded.svg#icon"/></svg> list_alt_rounded.</p>
<p><svg class="icon"><use href="../images/map_rounded.svg#icon"/></svg> map_rounded.</p>
+ <p><svg class="icon"><use href="../images/notification_important_rounded_filled.svg#icon"/></svg> notification_important_<wbr>rounded_filled.</p>
<p><svg class="icon"><use href="../images/payments_rounded.svg#icon"/></svg> payments_rounded.</p>
<p><svg class="icon"><use href="../images/phone_android_outlined.svg#icon"/></svg> phone_android_outlined.</p>
<p><svg class="icon"><use href="../images/policy_filled.svg#icon"/></svg> policy_filled.</p>
implied. See the License for
the specific language governing
permissions and limitations
-under the License.</pre>
\ No newline at end of file
+under the License.</pre>
+ </body>
+</html>
<p>Privacy Cell usa los siguientes permisos.</p>
<h3>Leer el estado del teléfono e identidad</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission. READ_PHONE_STATE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission.<wbr>READ_PHONE_STATE</a></p>
<p>Requerido para determinar qué protocolos se están usando por la red del teléfono celular.</p>
<h3>Run foreground service</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission. FOREGROUND_SERVICE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission.<wbr>FOREGROUND_SERVICE</a></p>
<p>Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.</p>
<h3>Run at startup</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission. RECEIVE_BOOT_COMPLETED</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission.<wbr>RECEIVE_BOOT_COMPLETED</a></p>
<p>Allows Privacy Cell to enable the realtime monitoring service when the phone boots.</p>
</body>
</html>
\ No newline at end of file
</head>
<body>
- <h3>1.8.1 (version de code 10)</h3>
- <p>8 Août 2022 - API minimum 30, API cible 32</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-8-1/">1.8.1</a> (version du code 10)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=ab7601a6d91b6035862bb47b1ac259855e3aba3b">8 Août 2022</a> - API minimale : 30, API optimale : 32</p>
<ul>
- <li>Fix a bug that <a href="https://redmine.stoutner.com/issues/864">re-enabled notifications</a> when the network changed.</li>
- <li>Add <a href="https://redmine.stoutner.com/issues/884">dual-toned violet text</a> to the Night Theme.</li>
+ <li>Correction d'un bug qui <a href="https://redmine.stoutner.com/issues/864">réactivait les notifications</a> lorsque le réseau changeait.</li>
+ <li>Ajout <a href="https://redmine.stoutner.com/issues/884">d'un texte violet à deux tons</a> sur le thème de Nuit.</li>
<li>Mise à jour de la traduction française par <a href="mailto:kevinliste@framalistes.org">Kévin L</a>.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-8/">1.8</a> (version de code 9)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=f60b140868c2f0d564657e96d48508b4fbdc546b">14 Juin 2022</a> - API minimum 30, API cible 32</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-8/">1.8</a> (version du code 9)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=f60b140868c2f0d564657e96d48508b4fbdc546b">14 Juin 2022</a> - API minimale : 30, API optimale : 32</p>
<ul>
<li>Inclure l'état <a href="https://redmine.stoutner.com/issues/851">du réseau voix</a> dans la détermination de la sécurité globale du réseau cellulaire.</li>
<li>Correction d'un bogue <a href="https://redmine.stoutner.com/issues/850">qui empêchait parfois la désactivation des notifications</a>.</li>
<li>Mise à jour de la traduction française par <a href="mailto:kevinliste@framalistes.org">Kévin L</a>.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-7/">1.7</a> (version de code 8)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=b11b84b24c660fac3a69f2dbe4bd615d73811219">24 Mars 2022</a> - API minimum 30, API cible 31</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-7/">1.7</a> (version du code 8)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=b11b84b24c660fac3a69f2dbe4bd615d73811219">24 Mars 2022</a> - API minimale : 30, API optimale : 31</p>
<ul>
<li>Ajout d'un ajout d'un avertissement lors de la connexion à <a href="https://redmine.stoutner.com/issues/795">des réseaux anciens et peu sûrs</a>.</li>
<li>Ajout d'une <a href="https://redmine.stoutner.com/issues/774">entrée listant l'ensemble des protocoles</a>.</li>
<li>Mise à jour de la traduction française par <a href="mailto:kevinliste@framalistes.org">Kévin L</a>.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-6/">1.6</a> (version de code 7)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=2be052aa618f414a18d73f5075b3b3776180bee5">21 Décembre 2021</a> - API minimum 30, API cible 31</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-6/">1.6</a> (version du code 7)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=2be052aa618f414a18d73f5075b3b3776180bee5">21 Décembre 2021</a> - API minimale : 30, API optimale : 31</p>
<ul>
<li>Suppression des permissions inutiles ajoutées <a href="https://redmine.stoutner.com/issues/775">androidx.work</a>.</li>
<li>Correction du service de notification ne pouvant pas <a href="https://redmine.stoutner.com/issues/777">se redémarrer en arrière-plan</a> sur Android 12.</li>
<li>Première traduction complète en russe.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-5/">1.5</a> (version de code 6)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=6ee1470b74f7643f50bf7f1ebfdb578dcac829f2">3 Novembre 2021</a> - API minimum 30, API cible 31</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-5/">1.5</a> (version du code 6)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=6ee1470b74f7643f50bf7f1ebfdb578dcac829f2">3 Novembre 2021</a> - API minimale : 30, API optimale : 31</p>
<ul>
<li>Correction d'un <a href="https://redmine.stoutner.com/issues/771">plantage avec la supervision temps-réel </a> si la permission READ_PHONE_STATE était désactivée.</li>
<li>Page de <a href="https://redmine.stoutner.com/issues/772">l'API cible à 31</a> (Android 12).</li>
<li>Première traduction française complète effectuée par <a href="mailto:kevinliste@framalistes.org">Kévin L</a>.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-4/">1.4</a> (version de code 5)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=a1d76c6e3ed465dd14385c5a37416ee30922021f">18 Octobre 2021</a> - API minimum 30, API cible 30.</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-4/">1.4</a> (version du code 5)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=a1d76c6e3ed465dd14385c5a37416ee30922021f">18 Octobre 2021</a> - API minimale : 30, API optimale : 30.</p>
<ul>
<li>Correction de problèmes <a href="https://redmine.stoutner.com/issues/764">de plantage du monitoring en temps réel</a> ou
<a href="https://redmine.stoutner.com/issues/763">lorsque le mauvais son est joué</a>.</li>
<li>Première traduction italienne intégrale réalisée par Francesco Buratti.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-3/">1.3</a> (version de code 4)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=0611c698c5c7163dbe84e4d592fb3bf6150ab1a2">29 Septembre 2021</a> – API minimum 30, API cible 30.</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-3/">1.3</a> (version du code 4)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=0611c698c5c7163dbe84e4d592fb3bf6150ab1a2">29 Septembre 2021</a> – API minimale : 30, API optimale : 30.</p>
<ul>
<li>Ajout d'une <a href="https://redmine.stoutner.com/issues/750">option de vérification en temps réel</a>.</li>
<li>Traduction française mise à jour par <a href="mailto:kevinliste@framalistes.org">Kévin L</a>.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-2/">1.2</a> (version de code 3)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=70a8bdb781941d9f433b18a91befe03137d65a6f">15 Septembre 2021</a> - API minimum 30, API cible 30.</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-2/">1.2</a> (version du code 3)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=70a8bdb781941d9f433b18a91befe03137d65a6f">15 Septembre 2021</a> - API minimale : 30, API optimale : 30.</p>
<ul>
<li>Ajout d'une option permettant d'utiliser un <a href="https://redmine.stoutner.com/issues/749">barre d'application inférieure</a>.</li>
<li>Traduction française partielle réalisée par <a href="mailto:kevinliste@framalistes.org">Kévin L</a>.</li>
<li>Traduction italienne partielle réalisée par Francesco Buratti.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-1/">1.1</a> (version de code 2)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=62586b5aaccbfa0fa265040513f3984264bd0379">30 Août 2021</a> - API minimum 30, API cible 30.</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-1/">1.1</a> (version du code 2)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=62586b5aaccbfa0fa265040513f3984264bd0379">30 Août 2021</a> - API minimale : 30, API optimale : 30.</p>
<ul>
<li>Ajout <a href="https://redmine.stoutner.com/issues/756">de menus d'information</a> pour les types de réseaux.</li>
<li>Traduction espagnole partielle réalisée par Jose A. León.</li>
</ul>
- <h3><a href="https://www.stoutner.com/privacy-cell-1-0/">1.0</a> (version de code 1)</h3>
- <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=13c6fd95ce6986c052fed7918576b77619dc9c2a">25 Août 2021</a> - API minimum 30, API cible 30.</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-0/">1.0</a> (version du code 1)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=13c6fd95ce6986c052fed7918576b77619dc9c2a">25 Août 2021</a> - API minimale : 30, API optimale : 30.</p>
<ul>
<li>Version initiale.</li>
</ul>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Kévin L. <kevinliste@framalistes.org>. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<body>
<h3>Copyright</h3>
- <p>Privacy Cell copyright © 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
+ <p>Privacy Cell copyright 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
<h3>Licence</h3>
<p>Privacy Cell est publiée sous la <a href="https://www.gnu.org/licenses/gpl-3.0.html">licence GPLv3+</a>. Le texte intégral de la licence se trouve ci-dessous.
<p><svg class="icon"><use href="../images/groups_filled.svg#icon"/></svg> groups_filled.</p>
<p><svg class="icon"><use href="../images/list_alt_rounded.svg#icon"/></svg> list_alt_rounded.</p>
<p><svg class="icon"><use href="../images/map_rounded.svg#icon"/></svg> map_rounded.</p>
+ <p><svg class="icon"><use href="../images/notification_important_rounded_filled.svg#icon"/></svg> notification_important_<wbr>rounded_filled.</p>
<p><svg class="icon"><use href="../images/payments_rounded.svg#icon"/></svg> payments_rounded.</p>
<p><svg class="icon"><use href="../images/phone_android_outlined.svg#icon"/></svg> phone_android_outlined.</p>
<p><svg class="icon"><use href="../images/policy_filled.svg#icon"/></svg> policy_filled.</p>
implied. See the License for
the specific language governing
permissions and limitations
-under the License.</pre>
\ No newline at end of file
+under the License.</pre>
+ </body>
+</html>
<p>Privacy Cell utilise l'autorisation suivante.</p>
<h3>Lecture du statut et de l'identité du téléphone</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission. READ_PHONE_STATE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission.<wbr>READ_PHONE_STATE</a></p>
<p>Nécessaire pour déterminer quels protocoles sont utilisés par le réseau de téléphonie mobile.</p>
<h3>Exécuter un service en premier plan</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission. FOREGROUND_SERVICE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission.<wbr>FOREGROUND_SERVICE</a></p>
<p>Permet à Privacy Cell d'afficher une icône de notification de surveillance en temps réel dans la barre d'état.</p>
<h3>Exécution au démarrage</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission. RECEIVE_BOOT_COMPLETED</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission.<wbr>RECEIVE_BOOT_COMPLETED</a></p>
<p>Permet à Privacy Cell d'activer le service de surveillance en temps réel lorsque le téléphone démarre.</p>
</body>
</html>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+
+<!--
+ This file is a modified version of `notification_importang_rounded_filled`, which is part of the Android Material icon set and is released under the Apache License 2.0.
+
+ Changes copyright 2022 Soren Stoutner <soren@stoutner.com>. The resulting file is released under the GPLv3+ license.
+
+ 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/>. -->
+
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ viewBox="0 0 48 48"
+ id="icon">
+
+ <path
+ d="M24 26.6q.65 0 1.075-.425.425-.425.425-1.075v-7.6q0-.65-.425-1.075Q24.65 16 24 16q-.65 0-1.075.425-.425.425-.425 1.075v7.6q0 .65.425 1.075.425.425 1.075.425Zm0 5.4q.7 0 1.175-.475.475-.475.475-1.175 0-.7-.475-1.175Q24.7 28.7 24 28.7q-.7 0-1.175.475-.475.475-.475 1.175 0 .7.475 1.175Q23.3 32 24 32ZM9.5 38q-.65 0-1.075-.425Q8 37.15 8 36.5q0-.65.425-1.075Q8.85 35 9.5 35h2.7V19.7q0-4.1 2.475-7.425T21.2 8.1V6.65q0-1.15.825-1.9T24 4q1.15 0 1.975.75.825.75.825 1.9V8.1q4.05.85 6.55 4.175 2.5 3.325 2.5 7.425V35h2.65q.65 0 1.075.425Q40 35.85 40 36.5q0 .65-.425 1.075Q39.15 38 38.5 38ZM24 44q-1.6 0-2.8-1.175Q20 41.65 20 40h8q0 1.65-1.175 2.825Q25.65 44 24 44Z" />
+</svg>
<!--
This file is a modified version of `payments_rounded`, which is part of the Android Material icon set and is released under the Apache License 2.0.
- Changes copyright © 2021 Soren Stoutner <soren@stoutner.com>. The resulting file is released under the GPLv3+ license.
+ Changes copyright 2021 Soren Stoutner <soren@stoutner.com>. The resulting file is released under the GPLv3+ license.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
<path
d="M23,8v10c0,1.1-0.9,2-2,2H5c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1h16V8c0-0.55,0.45-1,1-1S23,7.45,23,8z M4,16 c-1.66,0-3-1.34-3-3V7c0-1.66,1.34-3,3-3h12c1.66,0,3,1.34,3,3v7c0,1.1-0.9,2-2,2H4z M7,10c0,1.66,1.34,3,3,3s3-1.34,3-3 s-1.34-3-3-3S7,8.34,7,10z" />
-</svg>
\ No newline at end of file
+</svg>
</head>
<body>
- <h3>1.8.1 (versione codice 10)</h3>
- <p>8 Agosto 2022 - minima API 30, target API 32</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-8-1/">1.8.1</a> (versione codice 10)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=ab7601a6d91b6035862bb47b1ac259855e3aba3b">8 Agosto 2022</a> - minima API 30, target API 32</p>
<ul>
<li>Correzione di un baco che <a href="https://redmine.stoutner.com/issues/864">riabilitava le notifiche</a> quando la rete cambiava.</li>
<li>Aggiunta di <a href="https://redmine.stoutner.com/issues/884">un testo con doppio tono di viola</a> al tema scuro.</li>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Francesco Buratti. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<body>
<h3>Copyright</h3>
- <p>Privacy Cell copyright © 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
+ <p>Privacy Cell copyright 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
<h3>Licenza</h3>
<p>Privacy Cell è rilasciato con <a href="https://www.gnu.org/licenses/gpl-3.0.html">Licenza GPLv3+</a>. Il testo completo è riportato di seguito.
<p><svg class="icon"><use href="../images/groups_filled.svg#icon"/></svg> groups_filled.</p>
<p><svg class="icon"><use href="../images/list_alt_rounded.svg#icon"/></svg> list_alt_rounded.</p>
<p><svg class="icon"><use href="../images/map_rounded.svg#icon"/></svg> map_rounded.</p>
+ <p><svg class="icon"><use href="../images/notification_important_rounded_filled.svg#icon"/></svg> notification_important_<wbr>rounded_filled.</p>
<p><svg class="icon"><use href="../images/payments_rounded.svg#icon"/></svg> payments_rounded.</p>
<p><svg class="icon"><use href="../images/phone_android_outlined.svg#icon"/></svg> phone_android_outlined.</p>
<p><svg class="icon"><use href="../images/policy_filled.svg#icon"/></svg> policy_filled.</p>
implied. See the License for
the specific language governing
permissions and limitations
-under the License.</pre>
\ No newline at end of file
+under the License.</pre>
+ </body>
+</html>
<p>Privacy Cell richiede le seguenti autorizzazioni.</p>
<h3>Lettura dello stato e dell'identità del telefono</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission. READ_PHONE_STATE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission.<wbr>READ_PHONE_STATE</a></p>
<p>Richiesta per determinare i protocolli utilizzati dalla rete.</p>
<h3>Run foreground service</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission. FOREGROUND_SERVICE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission.<wbr>FOREGROUND_SERVICE</a></p>
<p>Allows Privacy Cell to display a realtime monitoring notification icon in the status bar.</p>
<h3>Run at startup</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission. RECEIVE_BOOT_COMPLETED</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission.<wbr>RECEIVE_BOOT_COMPLETED</a></p>
<p>Allows Privacy Cell to enable the realtime monitoring service when the phone boots.</p>
</body>
</html>
\ No newline at end of file
</head>
<body>
- <h3>1.8.1 (код версии 10)</h3>
- <p>8 августа 2022 года - минимальный API 30, целевой API 32</p>
+ <h3><a href="https://www.stoutner.com/privacy-cell-1-8-1/">1.8.1</a> (код версии 10)</h3>
+ <p><a href="https://gitweb.stoutner.com/?p=PrivacyCell.git;a=commitdiff;h=ab7601a6d91b6035862bb47b1ac259855e3aba3b">8 августа 2022 года</a> - минимальный API 30, целевой API 32</p>
<ul>
<li>Исправлена ошибка, <a href="https://redmine.stoutner.com/issues/864">из-за которой при изменении сети</a> повторно включались уведомления.</li>
<li>Для ночной темы <a href="https://redmine.stoutner.com/issues/884">добавлен двухтоновый фиолетовый текст</a>.</li>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
<body>
<h3>Авторские права</h3>
- <p>Авторские права Privacy Cell © 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
+ <p>Авторские права Privacy Cell 2021-2022 <a href="mailto:soren@stoutner.com">Soren Stoutner</a>.</p>
<h3>Лицензия</h3>
<p>Privacy Cell выпускается под <a href="https://www.gnu.org/licenses/gpl-3.0.html">лицензией GPLv3+</a>. Полный текст лицензии приведен ниже.
<p><svg class="icon"><use href="../images/groups_filled.svg#icon"/></svg> groups_filled.</p>
<p><svg class="icon"><use href="../images/list_alt_rounded.svg#icon"/></svg> list_alt_rounded.</p>
<p><svg class="icon"><use href="../images/map_rounded.svg#icon"/></svg> map_rounded.</p>
+ <p><svg class="icon"><use href="../images/notification_important_rounded_filled.svg#icon"/></svg> notification_important_<wbr>rounded_filled.</p>
<p><svg class="icon"><use href="../images/payments_rounded.svg#icon"/></svg> payments_rounded.</p>
<p><svg class="icon"><use href="../images/phone_android_outlined.svg#icon"/></svg> phone_android_outlined.</p>
<p><svg class="icon"><use href="../images/policy_filled.svg#icon"/></svg> policy_filled.</p>
implied. See the License for
the specific language governing
permissions and limitations
-under the License.</pre>
\ No newline at end of file
+under the License.</pre>
+ </body>
+</html>
<p>Privacy Cell использует следующие разрешения:</p>
<h3>Чтение статуса и идентификатора телефона</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission. READ_PHONE_STATE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission.html#READ_PHONE_STATE">android.permission.<wbr>READ_PHONE_STATE</a></p>
<p>Необходим для определения используемых протоколов в сети сотовой связи.</p>
<h3>Запуск фоновой службы</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission. FOREGROUND_SERVICE</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#FOREGROUND_SERVICE">android.permission.<wbr>FOREGROUND_SERVICE</a></p>
<p>Разрешает Privacy Cell отображать значок уведомления о мониторинге в реальном времени в строке состояния.</p>
<h3>Запуск при загрузке</h3>
- <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission. RECEIVE_BOOT_COMPLETED</a></p>
+ <p><a href="https://developer.android.com/reference/android/Manifest.permission#RECEIVE_BOOT_COMPLETED">android.permission.<wbr>RECEIVE_BOOT_COMPLETED</a></p>
<p>Разрешает Privacy Cell включать службу мониторинга в реальном времени при загрузке телефона.</p>
</body>
</html>
\ No newline at end of file
/*
- * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
import com.stoutner.privacycell.R
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
private lateinit var logcatTextView: TextView
// Define the save logcat activity result launcher. It must be defined before `onCreate()` is run or the app will crash.
- private val saveLogcatActivityResultLauncher = registerForActivityResult(ActivityResultContracts.CreateDocument()) { fileNameUri: Uri? ->
+ private val saveLogcatActivityResultLauncher = registerForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { fileNameUri: Uri? ->
// Only save the file if the URI is not null, which happens if the user exited the file picker by pressing back.
if (fileNameUri != null) {
try {
// Open an output stream.
val outputStream = contentResolver.openOutputStream(fileNameUri)!!
- // Write the logcat string to the output stream.
- outputStream.write(logcatString.toByteArray(StandardCharsets.UTF_8))
+ // Save the logcat using a coroutine with Dispatchers.IO.
+ CoroutineScope(Dispatchers.Main).launch {
+ withContext(Dispatchers.IO) {
+ // Write the logcat string to the output stream.
+ outputStream.write(logcatString.toByteArray(StandardCharsets.UTF_8))
- // Close the output stream.
- outputStream.close()
+ // Close the output stream.
+ outputStream.close()
+ }
+ }
// Get a cursor from the content resolver.
val contentResolverCursor = contentResolver.query(fileNameUri, null, null, null)!!
// Stop the swipe to refresh animation if it is displayed.
swipeRefreshLayout.isRefreshing = false
}
-}
\ No newline at end of file
+}
/*
- * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
import com.stoutner.privacycell.R
import com.stoutner.privacycell.dialogs.PhonePermissionDialog
+import com.stoutner.privacycell.dialogs.PhonePermissionDialog.StoragePermissionDialogListener
import com.stoutner.privacycell.dialogs.WebViewDialog
import com.stoutner.privacycell.helpers.ProtocolHelper
import com.stoutner.privacycell.services.RealtimeMonitoringService
-class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, PhonePermissionDialog.StoragePermissionDialogListener {
+class PrivacyCellActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener, StoragePermissionDialogListener {
// Define the class variables.
private var voiceNetworkSecurityStatus = ProtocolHelper.UNPOPULATED
private var dataNetworkSecurityStatus = ProtocolHelper.UNPOPULATED
private lateinit var overallStatusImageView: ImageView
private lateinit var overallStatusTextView: TextView
+ companion object {
+ // Define the public constants.
+ const val PHONE_PERMISSION_REQUEST_CODE = 0
+ const val NOTIFICATION_PERMISSION_REQUEST_CODE = 1
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
// Run the default commands.
super.onCreate(savedInstanceState)
} else { // The phone permission has not been granted.
// Check if the user has previously denied the storage permission.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) { // Show a dialog explaining the request first.
- // Check to see if a phone permission dialog is already displayed. This happens if the app is restarted when the dialog is shown.
+ // Check to see if a phone permission dialog is already displayed. This happens if the app is restarted while the dialog is shown.
if (supportFragmentManager.findFragmentByTag(getString(R.string.phone_permission)) == null) { // No dialog is currently shown.
// Instantiate the phone permission dialog fragment.
val phonePermissionDialogFragment = PhonePermissionDialog()
phonePermissionDialogFragment.show(supportFragmentManager, getString(R.string.phone_permission))
}
} else { // Show the permission request directly.
- // Request the read phone state permission. There is only one permission request in the app, so it has a request code of 0.
- ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
+ // Request the read phone state permission.
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), PHONE_PERMISSION_REQUEST_CODE)
}
}
}
}
override fun onCloseStoragePermissionDialog() {
- // Request the read phone state permission. There is only one permission request in the app, so it has a request code of 0.
- ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
+ // Request the read phone state permission.
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), PHONE_PERMISSION_REQUEST_CODE)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
// Run the default commands.
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- //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).
- if (grantResults.isNotEmpty()) {
+ // 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) and the result is for the phone permission.
+ if (grantResults.isNotEmpty() && (requestCode == PHONE_PERMISSION_REQUEST_CODE)) {
// Check to see if the read phone state permission was granted. If the dialog was canceled the grant results will be empty.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // The read phone state permission was granted.
// Populate Privacy Cell.
stingrayDialogFragment.show(supportFragmentManager, getString(R.string.stingrays))
}
}
-}
\ No newline at end of file
+}
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
}?.show(supportFragmentManager, getString(R.string.protocols))
}
}
-}
\ No newline at end of file
+}
/*
- * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
package com.stoutner.privacycell.activities
+import android.Manifest
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
+import androidx.core.app.ActivityCompat
import androidx.preference.PreferenceManager
import com.stoutner.privacycell.R
+import com.stoutner.privacycell.dialogs.NotificationPermissionDialog.NotificationPermissionDialogListener
import com.stoutner.privacycell.fragments.SettingsFragment
+import com.stoutner.privacycell.services.RealtimeMonitoringService
-class SettingsActivity : AppCompatActivity() {
+class SettingsActivity : AppCompatActivity(), NotificationPermissionDialogListener {
override fun onCreate(savedInstanceState: Bundle?) {
// Run the default commands.
super.onCreate(savedInstanceState)
supportFragmentManager.beginTransaction().replace(R.id.preferences_framelayout, SettingsFragment()).commit()
}
+ override fun onCloseNotificationPermissionDialog() {
+ // Request the post notifications permission if the API >= 33.
+ if (Build.VERSION.SDK_INT >= 33) {
+ ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), PrivacyCellActivity.NOTIFICATION_PERMISSION_REQUEST_CODE)
+ }
+ }
+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// As there is only one option, go back.
onBackPressed()
// Consume the event.
return true
}
-}
\ No newline at end of file
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+ // Run the default commands.
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+
+ // 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)
+ // and the result is for the notification permission.
+ if (grantResults.isNotEmpty() && (requestCode == PrivacyCellActivity.NOTIFICATION_PERMISSION_REQUEST_CODE)) {
+ // Check to see if the notification permission was granted. If the dialog was canceled the grant result will be empty.
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // The notification permission was granted.
+ // Start the realtime monitoring service.
+ startService(Intent(this, RealtimeMonitoringService::class.java))
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2021-2022 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/>.
+ */
+
+package com.stoutner.privacycell.dialogs
+
+import android.app.Dialog
+import android.content.Context
+import android.content.DialogInterface
+import android.os.Bundle
+
+import androidx.appcompat.app.AlertDialog
+import androidx.fragment.app.DialogFragment
+
+import com.stoutner.privacycell.R
+
+class NotificationPermissionDialog : DialogFragment() {
+ // Declare the listener.
+ private lateinit var notificationPermissionDialogListener: NotificationPermissionDialogListener
+
+ // The public interface is used to send information back to the parent activity.
+ interface NotificationPermissionDialogListener {
+ fun onCloseNotificationPermissionDialog()
+ }
+
+ override fun onAttach(context: Context) {
+ // Run the default commands.
+ super.onAttach(context)
+
+ // Get a handle for the listener from the launching context.
+ notificationPermissionDialogListener = context as NotificationPermissionDialogListener
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ // Use a builder to create the alert dialog.
+ val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.Theme_PrivacyCellAlertDialog)
+
+ // Set the icon.
+ dialogBuilder.setIcon(R.drawable.notification_permission)
+
+ // Set the title.
+ dialogBuilder.setTitle(R.string.notification_permission)
+
+ // Set the text.
+ dialogBuilder.setMessage(R.string.notification_permission_text)
+
+ // Set the close button listener.
+ dialogBuilder.setNegativeButton(R.string.ok) { _: DialogInterface, _: Int ->
+ // Call the notification permission dialog listener.
+ notificationPermissionDialogListener.onCloseNotificationPermissionDialog()
+ }
+
+ // Return the alert dialog.
+ return dialogBuilder.create()
+ }
+}
/*
- * Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
// Return the alert dialog.
return dialogBuilder.create()
}
-}
\ No newline at end of file
+}
/*
- * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
import android.Manifest
import android.content.Intent
import android.content.SharedPreferences
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.content.pm.PackageManager
+import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.work.WorkManager
import com.stoutner.privacycell.R
+import com.stoutner.privacycell.activities.PrivacyCellActivity
+import com.stoutner.privacycell.dialogs.NotificationPermissionDialog
import com.stoutner.privacycell.services.RealtimeMonitoringService
class SettingsFragment : PreferenceFragmentCompat() {
// Declare the class variables.
- private lateinit var sharedPreferenceChangeListener: SharedPreferences.OnSharedPreferenceChangeListener
+ private lateinit var sharedPreferenceChangeListener: OnSharedPreferenceChangeListener
// Declare the class views.
private lateinit var realtimeMonitoringPreference: Preference
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
}
- private fun getSharedPreferenceChangeListener(): SharedPreferences.OnSharedPreferenceChangeListener {
+ private fun getSharedPreferenceChangeListener(): OnSharedPreferenceChangeListener {
// Return the shared preference change listener.
- return SharedPreferences.OnSharedPreferenceChangeListener {sharedPreferences, key ->
+ return OnSharedPreferenceChangeListener { sharedPreferences: SharedPreferences, key: String? ->
when (key) {
getString(R.string.realtime_monitoring_key) -> {
// Update the icon.
// Start or stop the service.
if (sharedPreferences.getBoolean(getString(R.string.realtime_monitoring_key), false)) { // Realtime monitoring has been enabled.
- // Start the realtime monitoring service.
- requireActivity().startService(Intent(context, RealtimeMonitoringService::class.java))
+ // Start the service according to the API.
+ if (Build.VERSION.SDK_INT >= 33) { // The device API is >= 33.
+ // Check to see if the post notification has been granted.
+ if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { // The permission has been granted.
+ // Start the realtime monitoring service.
+ requireActivity().startService(Intent(context, RealtimeMonitoringService::class.java))
+ } else { // The post notification permission has not been granted.
+ // Check if the user has previously denied the post notifications permission.
+ if (ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), Manifest.permission.POST_NOTIFICATIONS)) { // Show a dialog explaining the request first.
+ // Check to see if a notification permission dialog is already displayed. This happens if the app is restarted while the dialog is shown.
+ if (requireActivity().supportFragmentManager.findFragmentByTag(getString(R.string.notification_permission)) == null) { // No dialog is currently shown.
+ // Instantiate the notification permission dialog fragment.
+ val notificationPermissionDialogFragment = NotificationPermissionDialog()
+
+ // Show the notification permission alert dialog. The permission will be requested when the dialog is closed.
+ notificationPermissionDialogFragment.show(requireActivity().supportFragmentManager, getString(R.string.notification_permission))
+ }
+ } else { // Show the permission request directly.
+ // Request the post notifications permission directly.
+ ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.POST_NOTIFICATIONS), PrivacyCellActivity.NOTIFICATION_PERMISSION_REQUEST_CODE)
+ }
+ }
+ } else { // The device API is < 33.
+ // Start the realtime monitoring service.
+ requireActivity().startService(Intent(context, RealtimeMonitoringService::class.java))
+ }
} else { // Realtime monitoring has been disabled.
// Stop the realtime monitoring service.
requireActivity().stopService(Intent(context, RealtimeMonitoringService::class.java))
// Restart the activity after 400 milliseconds, so that the app has enough time to save the change to the preference.
restartHandler.postDelayed(restartRunnable, 400)
}
-}
\ No newline at end of file
+}
/*
- * Copyright © 2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
}
fun checkAdditionalNetworkInfo(additionalNetworkInfoType: Int): Int {
- if ((additionalNetworkInfoType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) ||
- (additionalNetworkInfoType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED)) {
+ return if ((additionalNetworkInfoType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) ||
+ (additionalNetworkInfoType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED)) {
// The additional network info is secure.
- return SECURE
+ SECURE
} else {
// The additional network info is insecure.
// TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA
// TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO
// TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA
// TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -- Can be removed once the minimum API >= 31.
- return INSECURE
+ INSECURE
}
}
fun getAdditionalNetworkInfoStringArray(overrideNetworkType: Int, context: Context) : Array<String> {
// Return the string array that corresponds to the override network type.
+ @Suppress("DEPRECATION") // OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE can be removed once the minimum API >= 31.
return when(overrideNetworkType) {
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE -> arrayOf(context.getString(R.string.none), "")
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA -> arrayOf(context.getString(R.string.lte_ca), context.getString(R.string.lte_ca_detail))
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> arrayOf(context.getString(R.string.lte_advanced_pro), context.getString(R.string.lte_advanced_pro_detail))
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> arrayOf(context.getString(R.string.nr_nsa), context.getString(R.string.nr_nsa_detail))
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> arrayOf(context.getString(R.string.nr_nsa_mmwave), context.getString(R.string.nr_nsa_mmwave_detail)) // Can be removed once the minimum API >= 31.
+ // OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE can be removed once the minimum API >= 31.
+ TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> arrayOf(context.getString(R.string.nr_nsa_mmwave), context.getString(R.string.nr_nsa_mmwave_detail))
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED -> arrayOf(context.getString(R.string.nr_advanced), context.getString(R.string.nr_advanced_detail))
else -> arrayOf(context.getString(R.string.error), "")
}
}
-}
\ No newline at end of file
+}
/*
- * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
}
}
}
-}
\ No newline at end of file
+}
<path
android:fillColor="@color/blue_icon"
android:pathData="M21,4L3,4c-1.1,0 -2,0.9 -2,2v13c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,6c0,-1.1 -0.9,-2 -2,-2zM21,18c0,0.55 -0.45,1 -1,1h-8L12,6h8c0.55,0 1,0.45 1,1v11zM19.25,9.5h-5.5c-0.41,0 -0.75,0.34 -0.75,0.75s0.34,0.75 0.75,0.75h5.5c0.41,0 0.75,-0.34 0.75,-0.75s-0.34,-0.75 -0.75,-0.75zM19.25,12h-5.5c-0.41,0 -0.75,0.34 -0.75,0.75s0.34,0.75 0.75,0.75h5.5c0.41,0 0.75,-0.34 0.75,-0.75s-0.34,-0.75 -0.75,-0.75zM19.25,14.5h-5.5c-0.41,0 -0.75,0.34 -0.75,0.75s0.34,0.75 0.75,0.75h5.5c0.41,0 0.75,-0.34 0.75,-0.75s-0.34,-0.75 -0.75,-0.75z" />
-</vector>
\ No newline at end of file
+</vector>
--- /dev/null
+<!-- This file comes from the Android Material icon set, where it is called `notification_important_rounded_filled`. It is released under the Apache License 2.0. -->
+
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+
+ <path
+ android:fillColor="@color/blue_icon"
+ android:pathData="M24,26.6q0.65,0 1.075,-0.425 0.425,-0.425 0.425,-1.075v-7.6q0,-0.65 -0.425,-1.075Q24.65,16 24,16q-0.65,0 -1.075,0.425 -0.425,0.425 -0.425,1.075v7.6q0,0.65 0.425,1.075 0.425,0.425 1.075,0.425ZM24,32q0.7,0 1.175,-0.475 0.475,-0.475 0.475,-1.175 0,-0.7 -0.475,-1.175Q24.7,28.7 24,28.7q-0.7,0 -1.175,0.475 -0.475,0.475 -0.475,1.175 0,0.7 0.475,1.175Q23.3,32 24,32ZM9.5,38q-0.65,0 -1.075,-0.425Q8,37.15 8,36.5q0,-0.65 0.425,-1.075Q8.85,35 9.5,35h2.7L12.2,19.7q0,-4.1 2.475,-7.425T21.2,8.1L21.2,6.65q0,-1.15 0.825,-1.9T24,4q1.15,0 1.975,0.75 0.825,0.75 0.825,1.9L26.8,8.1q4.05,0.85 6.55,4.175 2.5,3.325 2.5,7.425L35.85,35h2.65q0.65,0 1.075,0.425Q40,35.85 40,36.5q0,0.65 -0.425,1.075Q39.15,38 38.5,38ZM24,44q-1.6,0 -2.8,-1.175Q20,41.65 20,40h8q0,1.65 -1.175,2.825Q25.65,44 24,44Z" />
+</vector>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
android:layout_width="match_parent"
android:layout_weight="1"/>
-
<!-- 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" />
</com.google.android.material.appbar.AppBarLayout>
</LinearLayout>
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
android:layout_height="match_parent"
android:layout_width="match_parent" />
</LinearLayout>
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Bernhard G. Keller. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<string name="insecure_network_channel">Unsicheres Netzwerk</string>
<string name="antiquated_network_channel">Veraltetes Netzwerk</string>
<string name="unknown_network_channel">Unbekanntes Netzwerk</string>
-</resources>
\ No newline at end of file
+</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Jose A. León. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<string name="insecure_network_channel">Red insegura</string>
<string name="antiquated_network_channel">Red anticuada</string>
<string name="unknown_network_channel">Red desconocida</string>
-</resources>
\ No newline at end of file
+</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Kévin L. <kevinliste@framalistes.org>. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<string name="insecure_network_channel">Réseau non-sécurisé</string>
<string name="antiquated_network_channel">Réseau obsolète</string>
<string name="unknown_network_channel">Réseau inconnu</string>
-</resources>
\ No newline at end of file
+</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
Translation 2021-2022 Francesco Buratti. Copyright assigned to Soren Stoutner <soren@stoutner.com>.
<string name="insecure_network_channel">Rete insicura</string>
<string name="antiquated_network_channel">Rete Antiquata</string>
<string name="unknown_network_channel">Rete sconosciuta</string>
-</resources>
\ No newline at end of file
+</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
<string name="insecure_network_channel">Небезопасная сеть</string>
<string name="antiquated_network_channel">Устаревшая сеть</string>
<string name="unknown_network_channel">Неизвестная сеть</string>
-</resources>
\ No newline at end of file
+</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
<string name="nr_advanced">NR Advanced – 5G</string>
<string name="nr_advanced_detail">New Radio Advanced</string>
- <!-- Phone permission dialog. -->
+ <!-- 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>
+ <string name="notification_permission">Notification Permission</string>
+ <string name="notification_permission_text">Privacy Cell needs the Post Notification permission to display realtime monitoring notifications.</string>
<string name="ok">OK</string>
<!-- Dialogs. -->
<string name="consider_3g_antiquated_key" translatable="false">consider_3g_antiquated</string>
<string name="interface_key" translatable="false">interface</string>
<string name="bottom_app_bar_key" translatable="false">bottom_app_bar</string>
-</resources>
\ No newline at end of file
+</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
app:summary="@string/bottom_app_bar_summary"
app:defaultValue="false" />
</PreferenceCategory>
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
/*
- * Copyright © 2021-2022 Soren Stoutner <soren@stoutner.com>.
+ * Copyright 2021-2022 Soren Stoutner <soren@stoutner.com>.
*
* This file is part of Privacy Cell <https://www.stoutner.com/privacy-cell>.
*
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.2.2'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
+ classpath 'com.android.tools.build:gradle:7.3.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.20"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
task clean(type: Delete) {
delete rootProject.buildDir
-}
\ No newline at end of file
+}
--- /dev/null
+• Correction d'un bug qui réactivait les notifications lorsque le réseau changeait.
+• Ajout d'un texte violet à deux tons sur le thème de Nuit.
+• Mise à jour de la traduction française par Kévin L.
\ No newline at end of file
#Thu Aug 12 09:15:13 MST 2021
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME