mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-29 20:43:28 +01:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			09d729261c
			...
			foreground
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 2c6e95f902 | ||
|  | 7dbf3ac102 | 
							
								
								
									
										2
									
								
								.flutter
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								.flutter
									
									
									
									
									
								
							 Submodule .flutter updated: 6fba2447e9...fcf2c11572
									
								
							| @@ -61,6 +61,13 @@ | ||||
|             android:enabled="true" | ||||
|             android:exported="true" | ||||
|             android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" /> | ||||
|         <service  | ||||
|             android:name="com.pravera.flutter_foreground_task.service.ForegroundService" | ||||
|             android:foregroundServiceType="specialUse" | ||||
|             android:exported="false" /> | ||||
|         <meta-data | ||||
|             android:name="dev.imranr.obtainium.service.NOTIFICATION_ICON" | ||||
|             android:resource="@drawable/ic_notification" /> | ||||
|     </application> | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> | ||||
| @@ -74,6 +81,8 @@ | ||||
|         android:name="android.permission.WRITE_EXTERNAL_STORAGE" | ||||
|         android:maxSdkVersion="29" /> | ||||
|     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> | ||||
|     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> | ||||
|     <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" /> | ||||
|     <!-- Required to query activities that can process text, see: | ||||
|          https://developer.android.com/training/package-visibility and | ||||
|          https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT. | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-hdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-hdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 965 B | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-mdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-mdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 843 B | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-xhdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-xhdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-xxhdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-xxhdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.7 KiB | 
							
								
								
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-xxxhdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								android/app/src/main/res/drawable-xxxhdpi/ic_notification.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 4.0 KiB | 
| @@ -330,6 +330,8 @@ | ||||
|     "documentationLinksNote": "The Obtainium GitHub page linked below contains links to videos, articles, discussions and other resources that will help you understand how to use the app.", | ||||
|     "batteryOptimizationNote": "Note that background downloads may work more reliably if you disable OS battery optimizations for Obtainium.", | ||||
|     "fileDeletionError": "Failed to delete file (try deleting it manually then try again): \"{}\"", | ||||
|     "foregroundService": "Obtainium foreground service", | ||||
|     "fgServiceNotice": "This notification is required for background update checking (it can be hidden in the OS settings)", | ||||
|     "removeAppQuestion": { | ||||
|         "one": "Remove app?", | ||||
|         "other": "Remove apps?" | ||||
|   | ||||
							
								
								
									
										147
									
								
								lib/main.dart
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								lib/main.dart
									
									
									
									
									
								
							| @@ -9,16 +9,15 @@ import 'package:obtainium/providers/native_provider.dart'; | ||||
| import 'package:obtainium/providers/notifications_provider.dart'; | ||||
| import 'package:obtainium/providers/settings_provider.dart'; | ||||
| import 'package:obtainium/providers/source_provider.dart'; | ||||
| import 'package:permission_handler/permission_handler.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:dynamic_color/dynamic_color.dart'; | ||||
| import 'package:device_info_plus/device_info_plus.dart'; | ||||
| import 'package:background_fetch/background_fetch.dart'; | ||||
| import 'package:easy_localization/easy_localization.dart'; | ||||
| // ignore: implementation_imports | ||||
| import 'package:easy_localization/src/easy_localization_controller.dart'; | ||||
| // ignore: implementation_imports | ||||
| import 'package:easy_localization/src/localization.dart'; | ||||
| import 'package:flutter_foreground_task/flutter_foreground_task.dart'; | ||||
|  | ||||
| List<MapEntry<Locale, String>> supportedLocales = const [ | ||||
|   MapEntry(Locale('en'), 'English'), | ||||
| @@ -86,16 +85,31 @@ Future<void> loadTranslations() async { | ||||
| } | ||||
|  | ||||
| @pragma('vm:entry-point') | ||||
| void backgroundFetchHeadlessTask(HeadlessTask task) async { | ||||
|   String taskId = task.taskId; | ||||
|   bool isTimeout = task.timeout; | ||||
|   if (isTimeout) { | ||||
|     print('BG update task timed out.'); | ||||
|     BackgroundFetch.finish(taskId); | ||||
|     return; | ||||
| void startCallback() { | ||||
|   FlutterForegroundTask.setTaskHandler(MyTaskHandler()); | ||||
| } | ||||
|   await bgUpdateCheck(taskId, null); | ||||
|   BackgroundFetch.finish(taskId); | ||||
|  | ||||
| class MyTaskHandler extends TaskHandler { | ||||
|   static const String incrementCountCommand = 'incrementCount'; | ||||
|  | ||||
|   @override | ||||
|   Future<void> onStart(DateTime timestamp, TaskStarter starter) async { | ||||
|     print('onStart(starter: ${starter.name})'); | ||||
|     bgUpdateCheck('bg_check', null); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void onRepeatEvent(DateTime timestamp) { | ||||
|     bgUpdateCheck('bg_check', null); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Future<void> onDestroy(DateTime timestamp, bool isTimeout) async { | ||||
|     print('Foreground service onDestroy(isTimeout: $isTimeout)'); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   void onReceiveData(Object data) {} | ||||
| } | ||||
|  | ||||
| void main() async { | ||||
| @@ -119,6 +133,7 @@ void main() async { | ||||
|   } | ||||
|   final np = NotificationsProvider(); | ||||
|   await np.initialize(); | ||||
|   FlutterForegroundTask.initCommunicationPort(); | ||||
|   runApp( | ||||
|     MultiProvider( | ||||
|       providers: [ | ||||
| @@ -136,7 +151,6 @@ void main() async { | ||||
|       ), | ||||
|     ), | ||||
|   ); | ||||
|   BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask); | ||||
| } | ||||
|  | ||||
| class Obtainium extends StatefulWidget { | ||||
| @@ -152,32 +166,81 @@ class _ObtainiumState extends State<Obtainium> { | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     initPlatformState(); | ||||
|     // FlutterForegroundTask.addTaskDataCallback(onReceiveForegroundServiceData); | ||||
|     WidgetsBinding.instance.addPostFrameCallback((_) { | ||||
|       requestNonOptionalPermissions(); | ||||
|       initForegroundService(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   Future<void> initPlatformState() async { | ||||
|     await BackgroundFetch.configure( | ||||
|       BackgroundFetchConfig( | ||||
|         minimumFetchInterval: 15, | ||||
|         stopOnTerminate: false, | ||||
|         startOnBoot: true, | ||||
|         enableHeadless: true, | ||||
|         requiresBatteryNotLow: false, | ||||
|         requiresCharging: false, | ||||
|         requiresStorageNotLow: false, | ||||
|         requiresDeviceIdle: false, | ||||
|         requiredNetworkType: NetworkType.ANY, | ||||
|   Future<void> requestNonOptionalPermissions() async { | ||||
|     final NotificationPermission notificationPermission = | ||||
|         await FlutterForegroundTask.checkNotificationPermission(); | ||||
|     if (notificationPermission != NotificationPermission.granted) { | ||||
|       await FlutterForegroundTask.requestNotificationPermission(); | ||||
|     } | ||||
|     if (!await FlutterForegroundTask.isIgnoringBatteryOptimizations) { | ||||
|       await FlutterForegroundTask.requestIgnoreBatteryOptimization(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void initForegroundService() { | ||||
|     FlutterForegroundTask.init( | ||||
|       androidNotificationOptions: AndroidNotificationOptions( | ||||
|         channelId: 'bg_update', | ||||
|         channelName: tr('foregroundService'), | ||||
|         channelDescription: tr('foregroundService'), | ||||
|         onlyAlertOnce: true, | ||||
|       ), | ||||
|       iosNotificationOptions: const IOSNotificationOptions( | ||||
|         showNotification: false, | ||||
|         playSound: false, | ||||
|       ), | ||||
|       foregroundTaskOptions: ForegroundTaskOptions( | ||||
|         eventAction: ForegroundTaskEventAction.repeat(900000), | ||||
|         autoRunOnBoot: true, | ||||
|         autoRunOnMyPackageReplaced: true, | ||||
|         allowWakeLock: true, | ||||
|         allowWifiLock: true, | ||||
|       ), | ||||
|       (String taskId) async { | ||||
|         await bgUpdateCheck(taskId, null); | ||||
|         BackgroundFetch.finish(taskId); | ||||
|       }, | ||||
|       (String taskId) async { | ||||
|         context.read<LogsProvider>().add('BG update task timed out.'); | ||||
|         BackgroundFetch.finish(taskId); | ||||
|       }, | ||||
|     ); | ||||
|     if (!mounted) return; | ||||
|   } | ||||
|  | ||||
|   Future<ServiceRequestResult?> startForegroundService(bool restart) async { | ||||
|     if (await FlutterForegroundTask.isRunningService) { | ||||
|       if (restart) { | ||||
|         return FlutterForegroundTask.restartService(); | ||||
|       } | ||||
|     } else { | ||||
|       return FlutterForegroundTask.startService( | ||||
|         serviceTypes: [ForegroundServiceTypes.specialUse], | ||||
|         serviceId: 666, | ||||
|         notificationTitle: tr('foregroundService'), | ||||
|         notificationText: tr('fgServiceNotice'), | ||||
|         notificationIcon: NotificationIcon( | ||||
|           metaDataName: 'dev.imranr.obtainium.service.NOTIFICATION_ICON', | ||||
|         ), | ||||
|         callback: startCallback, | ||||
|       ); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   stopForegroundService() async { | ||||
|     if (await FlutterForegroundTask.isRunningService) { | ||||
|       return FlutterForegroundTask.stopService(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // void onReceiveForegroundServiceData(Object data) { | ||||
|   //   print('onReceiveTaskData: $data'); | ||||
|   // } | ||||
|  | ||||
|   @override | ||||
|   void dispose() { | ||||
|     // Remove a callback to receive data sent from the TaskHandler. | ||||
|     // FlutterForegroundTask.removeTaskDataCallback(onReceiveForegroundServiceData); | ||||
|     super.dispose(); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
| @@ -186,15 +249,18 @@ class _ObtainiumState extends State<Obtainium> { | ||||
|     AppsProvider appsProvider = context.read<AppsProvider>(); | ||||
|     LogsProvider logs = context.read<LogsProvider>(); | ||||
|     NotificationsProvider notifs = context.read<NotificationsProvider>(); | ||||
|  | ||||
|     if (settingsProvider.updateInterval == 0) { | ||||
|       stopForegroundService(); | ||||
|     } else { | ||||
|       startForegroundService(false); | ||||
|     } | ||||
|     if (settingsProvider.prefs == null) { | ||||
|       settingsProvider.initializeSettings(); | ||||
|     } else { | ||||
|       bool isFirstRun = settingsProvider.checkAndFlipFirstRun(); | ||||
|       if (isFirstRun) { | ||||
|         logs.add('This is the first ever run of Obtainium.'); | ||||
|         // If this is the first run, ask for notification permissions and add Obtainium to the Apps list | ||||
|         Permission.notification.request(); | ||||
|         // If this is the first run, add Obtainium to the Apps list | ||||
|         if (!fdroid) { | ||||
|           getInstalledInfo(obtainiumId) | ||||
|               .then((value) { | ||||
| @@ -236,7 +302,8 @@ class _ObtainiumState extends State<Obtainium> { | ||||
|       notifs.checkLaunchByNotif(); | ||||
|     }); | ||||
|  | ||||
|     return DynamicColorBuilder( | ||||
|     return WithForegroundTask( | ||||
|       child: DynamicColorBuilder( | ||||
|         builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) { | ||||
|           // Decide on a colour/brightness scheme based on OS and user settings | ||||
|           ColorScheme lightColorScheme; | ||||
| @@ -292,12 +359,14 @@ class _ObtainiumState extends State<Obtainium> { | ||||
|             ), | ||||
|             home: Shortcuts( | ||||
|               shortcuts: <LogicalKeySet, Intent>{ | ||||
|               LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), | ||||
|                 LogicalKeySet(LogicalKeyboardKey.select): | ||||
|                     const ActivateIntent(), | ||||
|               }, | ||||
|               child: const HomePage(), | ||||
|             ), | ||||
|           ); | ||||
|         }, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										26
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -104,10 +104,10 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: battery_plus | ||||
|       sha256: a0409fe7d21905987eb1348ad57c634f913166f14f0c8936b73d3f5940fac551 | ||||
|       sha256: fb794c34cee2e4ea31005fb17ff15e1d904951ec7f15eedead741021870ee834 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.2.1" | ||||
|     version: "6.2.2" | ||||
|   battery_plus_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -216,18 +216,18 @@ packages: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: device_info_plus | ||||
|       sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53" | ||||
|       sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "11.4.0" | ||||
|     version: "11.5.0" | ||||
|   device_info_plus_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: device_info_plus_platform_interface | ||||
|       sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2" | ||||
|       sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "7.0.2" | ||||
|     version: "7.0.3" | ||||
|   dynamic_color: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
| @@ -377,6 +377,14 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "0.7.1" | ||||
|   flutter_foreground_task: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: flutter_foreground_task | ||||
|       sha256: "9f1b25a81db95d7119d2c5cffc654048cbdd49d4056183e1beadc1a6a38f3e29" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "9.1.0" | ||||
|   flutter_keyboard_visibility: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -995,10 +1003,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: synchronized | ||||
|       sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" | ||||
|       sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.3.1" | ||||
|     version: "3.4.0" | ||||
|   term_glyph: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -1201,4 +1209,4 @@ packages: | ||||
|     version: "6.3.0" | ||||
| sdks: | ||||
|   dart: ">=3.8.1 <4.0.0" | ||||
|   flutter: ">=3.27.0" | ||||
|   flutter: ">=3.29.0" | ||||
|   | ||||
| @@ -94,6 +94,7 @@ dependencies: | ||||
|   # package. See that file for information about deactivating specific lint | ||||
|   # rules and activating additional ones. | ||||
|   flutter_lints: ^6.0.0 | ||||
|   flutter_foreground_task: ^9.1.0 | ||||
|  | ||||
| flutter_launcher_icons: | ||||
|   android: "ic_launcher" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user