diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index d741348c..2e47649f 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -177,6 +177,12 @@ abstract class S { /// **'Backup version is not match.'** String get backupVersionNotMatch; + /// No description provided for @bgRun. + /// + /// In en, this message translates to: + /// **'Run in backgroud'** + String get bgRun; + /// No description provided for @cancel. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index ff2f93cd..aead5bc5 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -46,6 +46,9 @@ class SEn extends S { @override String get backupVersionNotMatch => 'Backup version is not match.'; + @override + String get bgRun => 'Run in backgroud'; + @override String get cancel => 'Cancel'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index bdca2913..4ed3569a 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -46,6 +46,9 @@ class SZh extends S { @override String get backupVersionNotMatch => '备份版本不匹配,无法恢复'; + @override + String get bgRun => '后台运行'; + @override String get cancel => '取消'; diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 8acbf2a3..01a352cf 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -359,7 +359,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 250; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -367,7 +367,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.247; + MARKETING_VERSION = 1.0.250; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -490,7 +490,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 250; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -498,7 +498,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.247; + MARKETING_VERSION = 1.0.250; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -515,7 +515,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 247; + CURRENT_PROJECT_VERSION = 250; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -523,7 +523,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.247; + MARKETING_VERSION = 1.0.250; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/core/utils/platform.dart b/lib/core/utils/platform.dart index e5d8ab88..0527f4a5 100644 --- a/lib/core/utils/platform.dart +++ b/lib/core/utils/platform.dart @@ -9,6 +9,7 @@ enum PlatformType { macos, windows, web, + unknown, } final _p = () { @@ -30,7 +31,7 @@ final _p = () { if (Platform.isWindows) { return PlatformType.windows; } - return PlatformType.web; + return PlatformType.unknown; }(); PlatformType get platform => _p; @@ -41,3 +42,8 @@ bool get isLinux => _p == PlatformType.linux; bool get isMacOS => _p == PlatformType.macos; bool get isWindows => _p == PlatformType.windows; bool get isWeb => _p == PlatformType.web; +bool get isMobile => _p == PlatformType.ios || _p == PlatformType.android; +bool get isDesktop => + _p == PlatformType.linux || + _p == PlatformType.macos || + _p == PlatformType.windows; diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 704eeda2..edce6ae8 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 247; - static const String engine = "Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 2ad6cd72c0 (3 weeks ago) • 2023-03-08 09:41:59 -0800\nEngine • revision 1837b5be5f\nTools • Dart 2.19.4 • DevTools 2.20.1\n"; - static const String buildAt = "2023-03-27 20:08:32.272098"; - static const int modifications = 3; + static const int build = 250; + static const String engine = + "Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 2ad6cd72c0 (3 weeks ago) • 2023-03-08 09:41:59 -0800\nEngine • revision 1837b5be5f\nTools • Dart 2.19.4 • DevTools 2.20.1\n"; + static const String buildAt = "2023-03-28 17:16:16.365127"; + static const int modifications = 2; } diff --git a/lib/data/res/misc.dart b/lib/data/res/misc.dart index 9ba58ccd..5f13d7a3 100644 --- a/lib/data/res/misc.dart +++ b/lib/data/res/misc.dart @@ -1,3 +1,5 @@ +import 'package:flutter/services.dart'; + /// RegExp for number final numReg = RegExp(r'\s{1,}'); @@ -6,3 +8,7 @@ const privateKeyMaxSize = 20 * 1024; /// Max debug log lines const maxDebugLogLines = 100; + +/// Method Channels +const pkgName = 'tech.lolli.toolbox'; +const bgRunChannel = MethodChannel('$pkgName/app_retain'); diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index 29e3750e..8afa0ed4 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -35,4 +35,7 @@ class SettingStore extends PersistentStore { /// Font file path StoreProperty get fontPath => property('fontPath'); + + /// Backgroud running (Android) + StoreProperty get bgRun => property('bgRun', defaultValue: true); } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8f3e1141..674c284e 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -13,6 +13,7 @@ "backupAndRestore": "Backup and Restore", "backupTip": "The exported data is simply encrypted. \nPlease keep it safe.\nRestoring will not overwrite existing data.", "backupVersionNotMatch": "Backup version is not match.", + "bgRun": "Run in backgroud", "cancel": "Cancel", "choose": "Choose", "chooseDestination": "Choose destination", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index fa48b3c5..0e72148d 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -13,6 +13,7 @@ "backupAndRestore": "备份和恢复", "backupTip": "导出的数据仅进行了简单加密,请妥善保管。\n恢复的数据不会覆盖现有数据。", "backupVersionNotMatch": "备份版本不匹配,无法恢复", + "bgRun": "后台运行", "cancel": "取消", "choose": "选择", "chooseDestination": "选择目标", diff --git a/lib/view/page/home.dart b/lib/view/page/home.dart index b5061a91..82eb7a91 100644 --- a/lib/view/page/home.dart +++ b/lib/view/page/home.dart @@ -1,8 +1,8 @@ import 'package:after_layout/after_layout.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:get_it/get_it.dart'; +import 'package:toolbox/data/res/misc.dart'; import '../../core/analysis.dart'; import '../../core/route.dart'; @@ -49,7 +49,6 @@ class _MyHomePageState extends State late int _selectIndex; late double _width; late S _s; - final _channel = const MethodChannel('tech.lolli.toolbox/app_retain'); @override void initState() { @@ -77,16 +76,25 @@ class _MyHomePageState extends State @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); - if (state == AppLifecycleState.paused) { - if (isAndroid) { - _channel.invokeMethod('sendToBackground'); - } else { - _serverProvider.setDisconnected(); - _serverProvider.stopAutoRefresh(); - } - } - if (state == AppLifecycleState.resumed) { - _serverProvider.startAutoRefresh(); + if (isDesktop) return; + + switch (state) { + case AppLifecycleState.resumed: + if (isIOS) { + _serverProvider.startAutoRefresh(); + } + break; + case AppLifecycleState.paused: + if (isAndroid) { + // Keep running in background on Android device + bgRunChannel.invokeMethod('sendToBackground'); + } else { + _serverProvider.setDisconnected(); + _serverProvider.stopAutoRefresh(); + } + break; + default: + break; } } diff --git a/lib/view/page/setting.dart b/lib/view/page/setting.dart index eae1ed6a..fe7db727 100644 --- a/lib/view/page/setting.dart +++ b/lib/view/page/setting.dart @@ -108,6 +108,9 @@ class _SettingPageState extends State { if (isIOS) { children.add(_buildPushToken()); } + if (isAndroid) { + children.add(_buildBgRun()); + } return Column( children: children.map((e) => RoundRectCard(e)).toList(), ); @@ -499,4 +502,11 @@ class _SettingPageState extends State { () => rebuildAll(context), ); } + + Widget _buildBgRun() { + return ListTile( + title: Text(_s.bgRun), + trailing: buildSwitch(context, _setting.bgRun), + ); + } }