diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index ff06f437..88c79b7b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -46,6 +46,10 @@ + + + diff --git a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt index fc6e54dc..dd39a06d 100644 --- a/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt +++ b/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt @@ -1,49 +1,47 @@ package im.cwtch.flwtch import SplashView +import android.annotation.TargetApi import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter -import androidx.annotation.NonNull import android.content.pm.PackageManager +import android.net.Uri +import android.os.PowerManager +import android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS import android.util.Log import android.view.Window +import androidx.annotation.NonNull import androidx.lifecycle.Observer import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.work.* -import io.flutter.embedding.android.SplashScreen +import cwtch.Cwtch import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.android.SplashScreen import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.ErrorLogResult - +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.Result import org.json.JSONObject -import java.util.concurrent.TimeUnit -import java.io.File import java.nio.file.Files import java.nio.file.Paths -import java.nio.file.StandardCopyOption - -import android.net.Uri -import android.provider.DocumentsContract -import android.content.ContentUris -import android.os.Build -import android.os.Environment -import android.database.Cursor -import android.provider.MediaStore - -import cwtch.Cwtch +import java.util.concurrent.TimeUnit class MainActivity: FlutterActivity() { override fun provideSplashScreen(): SplashScreen? = SplashView() + // Channel to get app info private val CHANNEL_APP_INFO = "test.flutter.dev/applicationInfo" private val CALL_APP_INFO = "getNativeLibDir" + private val ANDROID_SETTINGS_CHANNEL_NAME = "androidSettings" + private val ANDROID_SETTINGS_CHANGE_NAME= "androidSettingsChanged" + private var andoidSettingsChangeChannel: MethodChannel? = null + private val CALL_ASK_BATTERY_EXEMPTION = "requestBatteryExemption" + private val CALL_IS_BATTERY_EXEMPT = "isBatteryExempt" // Channel to get cwtch api calls on private val CHANNEL_CWTCH = "cwtch" @@ -67,6 +65,7 @@ class MainActivity: FlutterActivity() { private val FILEPICKER_REQUEST_CODE = 234 private val PREVIEW_EXPORT_REQUEST_CODE = 235 private val PROFILE_EXPORT_REQUEST_CODE = 236 + private val REQUEST_DOZE_WHITELISTING_CODE:Int = 9 private var dlToProfile = "" private var dlToHandle = "" private var dlToFileKey = "" @@ -98,8 +97,16 @@ class MainActivity: FlutterActivity() { override fun onActivityResult(requestCode: Int, result: Int, intent: Intent?) { super.onActivityResult(requestCode, result, intent); + // has null intent and data + if (requestCode == REQUEST_DOZE_WHITELISTING_CODE) { + // 0 == "battery optimized" (still) + // -1 == "no battery optimization" (exempt!) + andoidSettingsChangeChannel!!.invokeMethod("powerExemptionChange", result == -1) + return; + } + if (intent == null || intent!!.getData() == null) { - Log.i("MainActivity:onActivityResult", "user canceled activity"); + Log.i(TAG, "user canceled activity"); return; } @@ -149,8 +156,10 @@ class MainActivity: FlutterActivity() { requestWindowFeature(Window.FEATURE_NO_TITLE) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_APP_INFO).setMethodCallHandler { call, result -> handleAppInfo(call, result) } MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_CWTCH).setMethodCallHandler { call, result -> handleCwtch(call, result) } + MethodChannel(flutterEngine.dartExecutor.binaryMessenger, ANDROID_SETTINGS_CHANNEL_NAME).setMethodCallHandler { call, result -> handleAndroidSettings(call, result) } notificationClickChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NOTIF_CLICK) shutdownClickChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_SHUTDOWN_CLICK) + andoidSettingsChangeChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, ANDROID_SETTINGS_CHANGE_NAME) } // MethodChannel CHANNEL_APP_INFO handler (Flutter Channel for requests for Android environment info) @@ -162,6 +171,30 @@ class MainActivity: FlutterActivity() { } } + // MethodChannel ANDROID_SETTINGS_CHANNEL_NAME handler (Flutter Channel for requests for Android settings) + // Called from lib/view/globalsettingsview.dart + private fun handleAndroidSettings(@NonNull call: MethodCall, @NonNull result: Result) { + when (call.method) { + CALL_IS_BATTERY_EXEMPT -> result.success(checkIgnoreBatteryOpt() ?: false); + CALL_ASK_BATTERY_EXEMPTION -> { requestBatteryExemption(); result.success(null); } + else -> result.notImplemented() + } + } + + @TargetApi(23) + private fun checkIgnoreBatteryOpt(): Boolean { + val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager + return powerManager.isIgnoringBatteryOptimizations(this.packageName) ?: false; + } + + @TargetApi(23) + private fun requestBatteryExemption() { + val i = Intent() + i.action = ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS + i.data = Uri.parse("package:" + this.packageName) + startActivityForResult(i, REQUEST_DOZE_WHITELISTING_CODE); + } + private fun getNativeLibDir(): String { val ainfo = this.applicationContext.packageManager.getApplicationInfo( "im.cwtch.flwtch", // Must be app name @@ -489,9 +522,7 @@ class MainActivity: FlutterActivity() { // We need to do this here because after a "pause" flutter is still running // but we might have lost sync with the background process... Log.i("MainActivity.kt", "Call ReconnectCwtchForeground") - val data: Data = Data.Builder().putString(FlwtchWorker.KEY_METHOD, "ReconnectCwtchForeground").putString(FlwtchWorker.KEY_ARGS, "{}").build() - val workRequest = OneTimeWorkRequestBuilder().setInputData(data).build() - WorkManager.getInstance(applicationContext).enqueue(workRequest) + Cwtch.reconnectCwtchForeground() } override fun onStop() { diff --git a/lib/l10n/intl_cy.arb b/lib/l10n/intl_cy.arb index 77e5a083..9141ef3f 100644 --- a/lib/l10n/intl_cy.arb +++ b/lib/l10n/intl_cy.arb @@ -1,6 +1,10 @@ { "@@locale": "cy", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_da.arb b/lib/l10n/intl_da.arb index a07fca58..9233afea 100644 --- a/lib/l10n/intl_da.arb +++ b/lib/l10n/intl_da.arb @@ -1,6 +1,10 @@ { "@@locale": "da", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index 3deedbba..f8e57bde 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -1,6 +1,10 @@ { "@@locale": "de", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_el.arb b/lib/l10n/intl_el.arb index b6e196f6..76e27a32 100644 --- a/lib/l10n/intl_el.arb +++ b/lib/l10n/intl_el.arb @@ -1,6 +1,10 @@ { "@@locale": "el", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index a924c3b4..f851335a 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1,6 +1,10 @@ { "@@locale": "en", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_es.arb b/lib/l10n/intl_es.arb index 075a16e9..d2265f57 100644 --- a/lib/l10n/intl_es.arb +++ b/lib/l10n/intl_es.arb @@ -1,6 +1,10 @@ { "@@locale": "es", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index 4e134d74..53279427 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -1,7 +1,11 @@ { "@@locale": "fr", - "@@last_modified": "2022-04-12T20:56:53+02:00", - "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "thisFeatureRequiresGroupExpermientsToBeEnabled": "Cette fonctionnalité nécessite que l’expérience Groupes soit activée dans Paramètres", + "settingAndroidPowerExemptionDescription": "Android applique par défaut un profil de gestion de l'énergie \"optimisé\" aux applications, ce qui peut entraîner leur arrêt ou leur suppression. Demandez à Android d'exempter Cwtch de ce profil pour une meilleure stabilité mais une plus grande consommation d'énergie.", + "settingAndroidPowerExemption": "Android ignore les optimisations de la batterie", "messageFormattingDescription": "Activer la mise en forme de texte enrichi dans les messages affichés, par exemple **gras** et *italique*", "formattingExperiment": "Mise en forme des messages", "clickableLinksWarning": "L'ouverture de cette URL lancera une application en dehors de Cwtch et peut révéler des métadonnées ou compromettre la sécurité de Cwtch. N'ouvrez que les URLs de personnes en qui vous avez confiance. Êtes-vous sûr de vouloir continuer ?", diff --git a/lib/l10n/intl_it.arb b/lib/l10n/intl_it.arb index 34fd3fa9..de4e527e 100644 --- a/lib/l10n/intl_it.arb +++ b/lib/l10n/intl_it.arb @@ -1,6 +1,10 @@ { "@@locale": "it", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_lb.arb b/lib/l10n/intl_lb.arb index cf33de01..d6ea7a72 100644 --- a/lib/l10n/intl_lb.arb +++ b/lib/l10n/intl_lb.arb @@ -1,6 +1,10 @@ { "@@locale": "lb", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_no.arb b/lib/l10n/intl_no.arb index 295c2538..5c3afe11 100644 --- a/lib/l10n/intl_no.arb +++ b/lib/l10n/intl_no.arb @@ -1,6 +1,10 @@ { "@@locale": "no", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_pl.arb b/lib/l10n/intl_pl.arb index ce83b136..0c7dc602 100644 --- a/lib/l10n/intl_pl.arb +++ b/lib/l10n/intl_pl.arb @@ -1,6 +1,10 @@ { "@@locale": "pl", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_pt.arb b/lib/l10n/intl_pt.arb index a48754a3..2fa865c7 100644 --- a/lib/l10n/intl_pt.arb +++ b/lib/l10n/intl_pt.arb @@ -1,6 +1,10 @@ { "@@locale": "pt", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_ro.arb b/lib/l10n/intl_ro.arb index 051e69b8..5ec35e92 100644 --- a/lib/l10n/intl_ro.arb +++ b/lib/l10n/intl_ro.arb @@ -1,6 +1,10 @@ { "@@locale": "ro", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb index b7be29a1..a877b4ce 100644 --- a/lib/l10n/intl_ru.arb +++ b/lib/l10n/intl_ru.arb @@ -1,6 +1,10 @@ { "@@locale": "ru", - "@@last_modified": "2022-04-12T20:56:53+02:00", + "@@last_modified": "2022-04-13T22:56:39+02:00", + "okButton": "OK", + "settingsAndroidPowerReenablePopup": "Cannot re-enable Battery Optimization from within Cwtch. Please go to Android \/ Settings \/ Apps \/ Cwtch \/ Battery and set Usage to 'Optimized'", + "settingAndroidPowerExemptionDescription": "Optional: Request Android to exempt Cwtch from optimized power management. This will result in better stability at the cost of greater battery use.", + "settingAndroidPowerExemption": "Android Ignore Battery Optimizations", "thisFeatureRequiresGroupExpermientsToBeEnabled": "This feature requires the Groups Experiment to be enabled in Settings", "messageFormattingDescription": "Enable rich text formatting in displayed messages e.g. **bold** and *italic*", "formattingExperiment": "Message Formatting", diff --git a/lib/settings.dart b/lib/settings.dart index 749a9649..4ca0d341 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -109,8 +109,8 @@ class Settings extends ChangeNotifier { // single pane vs dual pane preferences _uiColumnModePortrait = uiColumnModeFromString(settings["UIColumnModePortrait"]); _uiColumnModeLandscape = uiColumnModeFromString(settings["UIColumnModeLandscape"]); - _notificationPolicy = notificationPolicyFromString(settings["NotificationPolicy"]); + _notificationContent = notificationContentFromString(settings["NotificationContent"]); // auto-download folder @@ -275,7 +275,7 @@ class Settings extends ChangeNotifier { static NotificationPolicy notificationPolicyFromString(String? np) { switch (np) { - case "NotificationPolicy.None": + case "NotificationPolicy.Mute": return NotificationPolicy.Mute; case "NotificationPolicy.OptIn": return NotificationPolicy.OptIn; diff --git a/lib/views/globalsettingsview.dart b/lib/views/globalsettingsview.dart index 806d9486..75ad7187 100644 --- a/lib/views/globalsettingsview.dart +++ b/lib/views/globalsettingsview.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:math'; import 'package:cwtch/cwtch_icons_icons.dart'; import 'package:cwtch/models/servers.dart'; import 'package:cwtch/widgets/folderpicker.dart'; @@ -13,6 +14,7 @@ import 'package:cwtch/themes/opaque.dart'; import 'package:cwtch/themes/pumpkin.dart'; import 'package:cwtch/themes/vampire.dart'; import 'package:cwtch/themes/witch.dart'; +import 'package:flutter/services.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:flutter/material.dart'; import 'package:cwtch/settings.dart'; @@ -29,11 +31,52 @@ class GlobalSettingsView extends StatefulWidget { } class _GlobalSettingsViewState extends State { + static const androidSettingsChannel = const MethodChannel('androidSettings'); + static const androidSettingsChangeChannel = const MethodChannel('androidSettingsChanged'); + bool powerExempt = false; + @override void dispose() { super.dispose(); } + @override + void initState() { + super.initState(); + androidSettingsChangeChannel.setMethodCallHandler(handleSettingsChanged); + + if (Platform.isAndroid) { + isBatteryExempt().then((value) => setState(() { powerExempt = value; }) ); + } else { + powerExempt = false; + } + } + + // Handler on method channel for MainActivity/onActivityResult to report the user choice when we ask for power exemption + Future handleSettingsChanged(MethodCall call) async { + if (call.method == "powerExemptionChange") { + if (call.arguments) { + setState(() { + powerExempt = true; + }); + } + } + } + + //* Android Only Requests + + Future isBatteryExempt() async { + return await androidSettingsChannel.invokeMethod('isBatteryExempt', {}) ?? false; + } + + + Future requestBatteryExemption() async { + await androidSettingsChannel.invokeMethod('requestBatteryExemption', {}); + return Future.value(); + } + + //* End Android Only Requests + @override Widget build(BuildContext context) { return Scaffold( @@ -172,6 +215,29 @@ class _GlobalSettingsViewState extends State { height: 40, ), Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text(AppLocalizations.of(context)!.settingGroupBehaviour, style: TextStyle(fontWeight: FontWeight.bold))]), + Visibility( + visible: Platform.isAndroid, + child: SwitchListTile( + title: Text(AppLocalizations.of(context)!.settingAndroidPowerExemption, style: TextStyle(color: settings + .current() + .mainTextColor)), + subtitle: Text(AppLocalizations.of(context)!.settingAndroidPowerExemptionDescription), + value: powerExempt, + onChanged: (bool value) { + if (value) { + requestBatteryExemption(); + } else { + // We can't ask for it to be turned off, show an informational popup + showBatteryDialog(context); + } + }, + activeTrackColor: settings.theme.defaultButtonColor, + inactiveTrackColor: settings.theme.defaultButtonDisabledColor, + secondary: Icon(Icons.power, color: settings + .current() + .mainTextColor), + ), + ), ListTile( title: Text(AppLocalizations.of(context)!.notificationPolicySettingLabel), subtitle: Text(AppLocalizations.of(context)!.notificationPolicySettingDescription), @@ -402,6 +468,32 @@ class _GlobalSettingsViewState extends State { }); }); } + + showBatteryDialog(BuildContext context) { + Widget okButton = ElevatedButton( + child: Text(AppLocalizations.of(context)!.okButton), + onPressed: () { + Navigator.of(context).pop(); + }, + ); + + + // set up the AlertDialog + AlertDialog alert = AlertDialog( + title: Text(AppLocalizations.of(context)!.settingsAndroidPowerReenablePopup), + actions: [ + okButton, + ], + ); + + // show the dialog + showDialog( + context: context, + builder: (BuildContext context) { + return alert; + }, + ); + } } /// Construct a version string from Package Info