diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt index 3cc105bfa..fd340f7ed 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt @@ -192,7 +192,6 @@ class MainActivity : FlutterActivity() { override fun onResume() { super.onResume() val inputPer = InputService.isOpen - Log.d(logTag, "onResume inputPer:$inputPer") activity.runOnUiThread { flutterMethodChannel.invokeMethod( "on_state_changed", diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt index 3cb3ae581..4bf244a06 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt @@ -57,6 +57,18 @@ fun requestPermission(context: Context, type: String) { } return } + "application_details_settings" -> { + try { + context.startActivity(Intent().apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + action = "android.settings.APPLICATION_DETAILS_SETTINGS" + data = Uri.parse("package:" + context.packageName) + }) + } catch (e:Exception) { + e.printStackTrace() + } + return + } "audio" -> { Permission.RECORD_AUDIO } diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 1b36c548b..a7c5dfea0 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -260,7 +260,12 @@ class PermissionManager { static Timer? _timer; static var _current = ""; - static final permissions = ["audio", "file", "ignore_battery_optimizations"]; + static final permissions = [ + "audio", + "file", + "ignore_battery_optimizations", + "application_details_settings" + ]; static bool isWaitingFile() { if (_completer != null) { diff --git a/flutter/lib/pages/settings_page.dart b/flutter/lib/pages/settings_page.dart index 7506d849f..55a7c8719 100644 --- a/flutter/lib/pages/settings_page.dart +++ b/flutter/lib/pages/settings_page.dart @@ -26,23 +26,42 @@ class SettingsPage extends StatefulWidget implements PageShape { _SettingsState createState() => _SettingsState(); } -class _SettingsState extends State { +class _SettingsState extends State with WidgetsBindingObserver { static const url = 'https://rustdesk.com/'; - var _showIgnoreBattery = false; + final _hasIgnoreBattery = androidVersion >= 26; + var _ignoreBatteryOpt = false; @override void initState() { super.initState(); - if (androidVersion >= 26) { - () async { - final res = - await PermissionManager.check("ignore_battery_optimizations"); - if (_showIgnoreBattery != !res) { - setState(() { - _showIgnoreBattery = !res; - }); - } - }(); + WidgetsBinding.instance.addObserver(this); + if (_hasIgnoreBattery) { + updateIgnoreBatteryStatus(); + } + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.resumed) { + updateIgnoreBatteryStatus(); + } + } + + Future updateIgnoreBatteryStatus() async { + final res = await PermissionManager.check("ignore_battery_optimizations"); + if (_ignoreBatteryOpt != res) { + setState(() { + _ignoreBatteryOpt = res; + }); + return true; + } else { + return false; } } @@ -53,7 +72,6 @@ class _SettingsState extends State { final enableAbr = FFI.getByName("option", "enable-abr") != 'N'; final enhancementsTiles = [ SettingsTile.switchTile( - leading: Icon(Icons.more_horiz), title: Text(translate('Adaptive Bitrate') + '(beta)'), initialValue: enableAbr, onToggle: (v) { @@ -68,32 +86,37 @@ class _SettingsState extends State { }, ) ]; - if (_showIgnoreBattery) { + if (_hasIgnoreBattery) { enhancementsTiles.insert( 0, - SettingsTile.navigation( + SettingsTile.switchTile( + initialValue: _ignoreBatteryOpt, title: Text(translate('Keep RustDesk background service')), description: Text('* ${translate('Ignore Battery Optimizations')}'), - leading: Icon(Icons.battery_saver), - onPressed: (context) { - PermissionManager.request("ignore_battery_optimizations"); - var count = 0; - Timer.periodic(Duration(seconds: 1), (timer) async { - if (count > 5) { - count = 0; - timer.cancel(); + onToggle: (v) async { + if (v) { + PermissionManager.request("ignore_battery_optimizations"); + } else { + final res = await DialogManager.show( + (setState, close) => CustomAlertDialog( + title: Text(translate("Open System Setting")), + content: Text(translate( + "android_open_battery_optimizations_tip")), + actions: [ + TextButton( + onPressed: () => close(), + child: Text(translate("Cancel"))), + ElevatedButton( + onPressed: () => close(true), + child: + Text(translate("Open System Setting"))), + ], + )); + if (res == true) { + PermissionManager.request("application_details_settings"); } - if (await PermissionManager.check( - "ignore_battery_optimizations")) { - count = 0; - timer.cancel(); - setState(() { - _showIgnoreBattery = false; - }); - } - count++; - }); + } })); } @@ -123,7 +146,13 @@ class _SettingsState extends State { leading: Icon(Icons.cloud), onPressed: (context) { showServerSettings(); - }) + }), + SettingsTile.navigation( + title: Text(translate('Language')), + leading: Icon(Icons.translate), + onPressed: (context) { + showLanguageSettings(); + }), ]), SettingsSection( title: Text(translate("Enhancements")), @@ -162,6 +191,13 @@ void showServerSettings() { showServerSettingsWithValue(id, relay, key, api); } +void showLanguageSettings() { + try { + final langs = json.decode(FFI.getByName('langs')) as Map; + debugPrint("langs:$langs"); + } catch (e) {} +} + void showAbout() { DialogManager.show((setState, close) { return CustomAlertDialog( diff --git a/src/lang/cn.rs b/src/lang/cn.rs index ba85d7f39..58a3a6cd7 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -286,5 +286,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Language", "语言"), ("Keep RustDesk background service", "保持RustDesk后台服务"), ("Ignore Battery Optimizations", "忽略电池优化"), + ("android_open_battery_optimizations_tip", "如需关闭此功能,请在接下来的RustDesk应用设置页面中,找到并进入 [电源] 页面,取消勾选 [不受限制]"), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index a4d11d415..1818a619a 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -27,5 +27,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("doc_mac_permission", "https://rustdesk.com/docs/en/manual/mac/#enable-permissions"), ("doc_fix_wayland", "https://rustdesk.com/docs/en/manual/linux/#x11-required"), ("server_not_support", "Not yet supported by the server"), + ("android_open_battery_optimizations_tip", "If you want to disable this feature, please go to the next RustDesk application settings page, find and enter [Battery] ,Uncheck [Unrestricted]"), ].iter().cloned().collect(); } diff --git a/src/mobile_ffi.rs b/src/mobile_ffi.rs index 6a0b71a5e..a0f0490e2 100644 --- a/src/mobile_ffi.rs +++ b/src/mobile_ffi.rs @@ -130,6 +130,9 @@ unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *co .clone() .to_string(); } + "langs" => { + res = crate::lang::LANGS.to_string(); + } // File Action "get_home_dir" => { res = fs::get_home_as_string();