From 6b43d4ed60b71663cfea778b38954c334e9e3c16 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Fri, 19 Aug 2022 14:59:00 -0400 Subject: [PATCH] Bugfixes + BG task seems to work --- lib/main.dart | 33 ++++++++++++++++++++++++- lib/services/apps_provider.dart | 44 ++++++++++++++++++++++----------- pubspec.lock | 7 ++++++ pubspec.yaml | 1 + 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 0142de8..d62f6f1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,42 @@ import 'package:flutter/material.dart'; import 'package:obtainium/pages/apps.dart'; import 'package:obtainium/services/apps_provider.dart'; +import 'package:obtainium/services/source_service.dart'; import 'package:provider/provider.dart'; -import 'package:toast/toast.dart'; +import 'package:workmanager/workmanager.dart'; + +void backgroundUpdateCheck() { + Workmanager().executeTask((task, inputData) async { + var appsProvider = AppsProvider(bg: true); + await appsProvider.loadApps(); + List updates = await appsProvider.getUpdates(); + if (updates.isNotEmpty) { + String message = updates.length == 1 + ? '${updates[0].name} has an update.' + : '${(updates.length == 2 ? '${updates[0].name} and ${updates[1].name}' : '${updates[0].name} and ${updates.length - 1} more apps')} have updates.'; + appsProvider.downloaderNotifications.cancel(2); + appsProvider.notify( + 2, + 'Updates Available', + message, + 'UPDATES_AVAILABLE', + 'Updates Available', + 'Notifies the user that updates are available for one or more Apps tracked by Obtainium'); + } + return Future.value(true); + }); +} void main() async { WidgetsFlutterBinding.ensureInitialized(); + Workmanager().initialize( + backgroundUpdateCheck, + ); + await Workmanager().cancelByUniqueName('update-apps-task'); + await Workmanager().registerPeriodicTask( + 'update-apps-task', 'backgroundUpdateCheck', + frequency: const Duration(minutes: 15), + constraints: Constraints(networkType: NetworkType.connected)); runApp(MultiProvider( providers: [ChangeNotifierProvider(create: (context) => AppsProvider())], child: const MyApp(), diff --git a/lib/services/apps_provider.dart b/lib/services/apps_provider.dart index ca34737..32a6558 100644 --- a/lib/services/apps_provider.dart +++ b/lib/services/apps_provider.dart @@ -19,11 +19,14 @@ class AppsProvider with ChangeNotifier { bool loadingApps = false; bool gettingUpdates = false; - AppsProvider() { - initializeDownloader(); + AppsProvider({bool bg = false}) { + initializeNotifs(); loadApps().then((_) { clearDownloadStates(); }); + if (!bg) { + initializeDownloader(); + } } // Notifications plugin for downloads @@ -53,15 +56,19 @@ class AppsProvider with ChangeNotifier { int progress = data[2]; downloadCallbackForeground(id, status, progress); }); - // Initialize the notifications service - await downloaderNotifications.initialize(const InitializationSettings( - android: AndroidInitializationSettings('ic_launcher'))); // Subscribe to changes in the app foreground status foregroundSubscription = FGBGEvents.stream.listen((event) async { isForeground = event == FGBGType.foreground; + if (isForeground) await loadApps(); }); } + Future initializeNotifs() async { + // Initialize the notifications service + await downloaderNotifications.initialize(const InitializationSettings( + android: AndroidInitializationSettings('ic_launcher'))); + } + // Callback that receives FlutterDownloader status and forwards to a foreground function @pragma('vm:entry-point') static void downloadCallbackBackground( @@ -71,24 +78,33 @@ class AppsProvider with ChangeNotifier { send!.send([id, status, progress]); } + Future notify(int id, String title, String message, String channelCode, + String channelName, String channelDescription) { + return downloaderNotifications.show( + id, + title, + message, + NotificationDetails( + android: AndroidNotificationDetails(channelCode, channelName, + channelDescription: channelDescription, + importance: Importance.max, + priority: Priority.max, + groupKey: 'dev.imranr.obtainium.$channelCode'))); + } + // Foreground function to act on FlutterDownloader status updates (install downloaded APK) void downloadCallbackForeground( String id, DownloadTaskStatus status, int progress) async { if (status == DownloadTaskStatus.complete) { // Wait for app to come to the foreground if not already, and notify the user while (!isForeground) { - await downloaderNotifications.show( + await notify( 1, 'Complete App Installation', 'Obtainium must be open to install Apps', - const NotificationDetails( - android: AndroidNotificationDetails( - 'COMPLETE_INSTALL', 'Complete App Installation', - channelDescription: - 'Ask the user to return to Obtanium to finish installing an App', - importance: Importance.max, - priority: Priority.max, - groupKey: 'dev.imranr.obtainium.COMPLETE_INSTALL'))); + 'COMPLETE_INSTALL', + 'Complete App Installation', + 'Asks the user to return to Obtanium to finish installing an App'); if (await FGBGEvents.stream.first == FGBGType.foreground) { break; } diff --git a/pubspec.lock b/pubspec.lock index 751019e..b1c7dfb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -392,6 +392,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.7.0" + workmanager: + dependency: "direct main" + description: + name: workmanager + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.0" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ab670bc..db043d0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: http: ^0.13.5 toast: ^0.3.0 webview_flutter: ^3.0.4 + workmanager: ^0.5.0 dev_dependencies: flutter_test: