1
0
Fork 0

added Android 13 support

This commit is contained in:
sspanak 2024-04-19 19:09:06 +03:00 committed by Dimo Karaivanov
parent ee63ca384e
commit 7e41800eac
20 changed files with 160 additions and 16 deletions

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
android:versionCode="474"
android:versionName="30.0"
android:versionCode="493"
android:versionName="30.19"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> <!-- required for words exporting on Android < 10 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <!-- allows displaying notifications on Android >= 13 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> <!-- allows words exporting on Android < 10 -->
<application
android:allowBackup="false"

View file

@ -1,10 +1,8 @@
package io.github.sspanak.tt9.db.exporter;
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
@ -19,6 +17,7 @@ import java.io.IOException;
import java.io.OutputStream;
import io.github.sspanak.tt9.util.ConsumerCompat;
import io.github.sspanak.tt9.util.Permissions;
public abstract class AbstractExporter {
protected static String FILE_EXTENSION = ".csv";
@ -67,11 +66,9 @@ public abstract class AbstractExporter {
protected void writeLegacy(Activity activity) throws Exception {
if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
) {
activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
Permissions permissions = new Permissions(activity);
if (permissions.noWriteStorage()) {
permissions.requestWriteStorage();
}
final String exportDir = Environment.getExternalStoragePublicDirectory(getOutputDir()).getAbsolutePath();

View file

@ -0,0 +1,53 @@
package io.github.sspanak.tt9.preferences.screens.languages;
import androidx.preference.Preference;
import androidx.preference.SwitchPreferenceCompat;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.util.Permissions;
public class ItemDictionaryNotifications {
public static final String NAME = "dictionary_notifications";
private final SwitchPreferenceCompat item;
private final Permissions permissions;
public ItemDictionaryNotifications(SwitchPreferenceCompat preference, PreferencesActivity activity) {
this.item = preference;
this.permissions = new Permissions(activity);
}
public ItemDictionaryNotifications populate() {
if (item == null) {
return this;
}
boolean noPermission = permissions.noPostNotifications();
item.setVisible(noPermission);
((SwitchPreferenceCompat) item).setChecked(!noPermission);
return this;
}
public ItemDictionaryNotifications enableClickHandler() {
if (item != null) {
item.setOnPreferenceChangeListener(this::onClick);
}
return this;
}
protected boolean onClick(Preference p, Object value) {
if (value == Boolean.TRUE || permissions.noPostNotifications()) {
permissions.requestPostNotifications();
}
// Switch off the component on user refusal. Android will not allow permission request again.
item.setEnabled(false);
return !permissions.noPostNotifications();
}
}

View file

@ -26,6 +26,7 @@ public class LanguagesScreen extends BaseScreenFragment {
@Override protected int getTitle() { return R.string.pref_choose_languages; }
@Override protected int getXml() { return R.xml.prefs_screen_languages; }
@Override
protected void onCreate() {
ItemSelectLanguage multiSelect = new ItemSelectLanguage(
@ -34,6 +35,10 @@ public class LanguagesScreen extends BaseScreenFragment {
);
multiSelect.populate().enableValidation();
new ItemDictionaryNotifications(findPreference(ItemDictionaryNotifications.NAME), activity)
.populate()
.enableClickHandler();
loadItem = new ItemLoadDictionary(findPreference(ItemLoadDictionary.NAME),
activity,
() -> ItemClickable.disableOthers(clickables, loadItem),
@ -77,6 +82,7 @@ public class LanguagesScreen extends BaseScreenFragment {
refreshItems();
}
@Override
public void onResume() {
super.onResume();

View file

@ -0,0 +1,51 @@
package io.github.sspanak.tt9.util;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
public class Permissions {
private final Activity activity;
public Permissions(Activity activity) {
this.activity = activity;
}
public boolean noPostNotifications() {
return
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
&& activity.shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS);
}
public void requestPostNotifications() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermission(Manifest.permission.POST_NOTIFICATIONS);
}
}
public boolean noWriteStorage() {
return
Build.VERSION.SDK_INT < Build.VERSION_CODES.R
&& isRefused(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
public void requestWriteStorage() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}
private void requestPermission(String permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.requestPermissions(new String[] { permission }, 0);
}
}
private boolean isRefused(String permission) {
return
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED;
}
}

View file

@ -64,6 +64,8 @@
<string name="function_add_word_key">Добавяне на нова дума</string>
<string name="function_backspace_key">Триене на текст</string>
<string name="function_change_keyboard_key">Избор на клавиатура</string>
<string name="dictionary_no_notifications">Речникови известия</string>
<string name="dictionary_no_notifications_summary">Получавайте известия за обновления на речника и за прогреса при зареждане.</string>
<string name="function_filter_clear_key">Изчистване на филтър</string>
<string name="function_filter_suggestions_key">Филтриране на думи</string>
<string name="function_previous_suggestion_key">Предишна дума</string>

View file

@ -101,4 +101,6 @@
<string name="dictionary_export_generating_csv">CSV wird exportiert…</string>
<string name="dictionary_export_generating_csv_for_language">CSV wird exportiert (%1$s)…</string>
<string name="pref_layout">Layout auf dem Bildschirm</string>
<string name="dictionary_no_notifications">Wörterbuchbenachrichtigungen</string>
<string name="dictionary_no_notifications_summary">Benachrichtigen über Wörterbuchaktualisierungen und den Ladevorgang.</string>
</resources>

View file

@ -71,6 +71,8 @@
<string name="pref_category_setup">Configuración inicial</string>
<string name="error">Error</string>
<string name="function_change_keyboard_key">Cambiar el teclado</string>
<string name="dictionary_no_notifications">Notificaciones del diccionario</string>
<string name="dictionary_no_notifications_summary">Recibir notificaciones sobre actualizaciones del diccionario y sobre el progreso de la carga.</string>
<string name="function_filter_clear_key">Limpiar el filtro</string>
<string name="function_filter_suggestions_key">Filtrar sugerencias</string>
<string name="function_previous_suggestion_key">Sugerencia previa</string>

View file

@ -62,6 +62,8 @@
<string name="function_add_word_key">Ajouter un mot</string>
<string name="function_backspace_key">Retour arrière</string>
<string name="function_change_keyboard_key">Changer le clavier</string>
<string name="dictionary_no_notifications">Notifications du dictionnaire</string>
<string name="dictionary_no_notifications_summary">Recevoir des notifications sur les mises à jour du dictionnaire et sur la progression du chargement.</string>
<string name="function_filter_clear_key">Supprimer le filtre</string>
<string name="function_filter_suggestions_key">Filtrer les mots</string>
<string name="function_previous_suggestion_key">Mot précédent</string>

View file

@ -103,5 +103,7 @@
<string name="dictionary_export_generating_csv">CSV in corso…</string>
<string name="dictionary_export_generating_csv_for_language">CSV in corso (%1$s)…</string>
<string name="pref_layout">Layout sullo schermo</string>
<string name="dictionary_no_notifications">Notifiche del dizionario</string>
<string name="dictionary_no_notifications_summary">Ricevere notifiche sugli aggiornamenti del dizionario e sul progresso del caricamento.</string>
</resources>

View file

@ -118,4 +118,6 @@
<string name="dictionary_export_generating_csv">מייצא CSV…</string>
<string name="dictionary_export_generating_csv_for_language">מייצא CSV (%1$s)…</string>
<string name="pref_layout">תצורת המקלדת על המסך</string>
<string name="dictionary_no_notifications">התראות מילון</string>
<string name="dictionary_no_notifications_summary">לקבל התראות על עדכוני המילון ועל התקדמות הטעינה.</string>
</resources>

View file

@ -74,6 +74,8 @@
<string name="function_add_word_key">Pridėti žodį</string>
<string name="function_backspace_key">Trinti</string>
<string name="function_change_keyboard_key">Keisti klaviatūrą</string>
<string name="dictionary_no_notifications">Žodyno pranešimai</string>
<string name="dictionary_no_notifications_summary">Gaukite pranešimus apie žodynų atnaujinimus ir įkėlimo progresą.</string>
<string name="function_filter_clear_key">Panaikinti filtrą</string>
<string name="function_filter_suggestions_key">Filtruoti pasiūlymus</string>
<string name="function_previous_suggestion_key">Ankstesnis pasiūlytas žodis</string>

View file

@ -99,4 +99,6 @@
<string name="dictionary_export_generating_csv">CSV exporteren…</string>
<string name="dictionary_export_generating_csv_for_language">CSV exporteren (%1$s)…</string>
<string name="pref_layout">Indeling op het scherm</string>
<string name="dictionary_no_notifications">Woordenboekmeldingen</string>
<string name="dictionary_no_notifications_summary">Ontvang meldingen over woordenboekupdates en de voortgang van het laden.</string>
</resources>

View file

@ -120,4 +120,6 @@
<string name="dictionary_export_generating_csv">Exportando CSV…</string>
<string name="dictionary_export_generating_csv_for_language">Exportando CSV (%1$s)…</string>
<string name="pref_layout">Layout na tela</string>
<string name="dictionary_no_notifications">Notificações do dicionário</string>
<string name="dictionary_no_notifications_summary">Receber notificações sobre atualizações do dicionário e sobre o progresso do carregamento.</string>
</resources>

View file

@ -63,6 +63,8 @@
<string name="function_add_word_key">Добавить новое слово</string>
<string name="function_backspace_key">Стереть</string>
<string name="function_change_keyboard_key">Выбор клавиатуры</string>
<string name="dictionary_no_notifications">Уведомления словаря</string>
<string name="dictionary_no_notifications_summary">Получать уведомления о обновлениях словаря и о процессе загрузки.</string>
<string name="function_filter_clear_key">Удалить фильтр</string>
<string name="function_filter_suggestions_key">Фильтровать слова</string>
<string name="function_previous_suggestion_key">Предыдущее слово</string>

View file

@ -99,6 +99,8 @@
<string name="function_add_word_key">Додати слово</string>
<string name="function_backspace_key">Стерти</string>
<string name="function_change_keyboard_key">Змінити клавіатуру</string>
<string name="dictionary_no_notifications">Сповіщення словника</string>
<string name="dictionary_no_notifications_summary">Отримувати повідомлення про оновлення словника та процес завантаження.</string>
<string name="function_filter_clear_key">Очистити фільтр</string>
<string name="function_filter_suggestions_key">Фільтрувати пропозиції</string>
<string name="function_previous_suggestion_key">Попередня пропозиція</string>

View file

@ -79,6 +79,8 @@
<string name="dictionary_loading_please_wait">Please wait for the dictionary to load.</string>
<string name="dictionary_load_title">Load Selected</string>
<string name="dictionary_not_found">Loading failed. Dictionary for \"%1$s\" not found.</string>
<string name="dictionary_no_notifications">Dictionary Notifications</string>
<string name="dictionary_no_notifications_summary">Get notified about dictionary updates and see the loading progress.</string>
<string name="dictionary_truncate_title">Delete All</string>
<string name="dictionary_truncate_unselected">Delete Unselected</string>
<string name="dictionary_truncated">Dictionary deleted successfully.</string>

View file

@ -6,6 +6,13 @@
app:layout="@layout/pref_text"
app:title="@string/pref_choose_languages" />
<SwitchPreferenceCompat
app:isPreferenceVisible="false"
app:key="dictionary_notifications"
app:layout="@layout/pref_switch"
app:title="@string/dictionary_no_notifications"
app:summary="@string/dictionary_no_notifications_summary"/>
<Preference
app:key="dictionary_load"
app:layout="@layout/pref_text"