mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-14 02:48:10 +02:00
Added foreground service option + other updates
This commit is contained in:
247
lib/main.dart
247
lib/main.dart
@@ -9,7 +9,6 @@ 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';
|
||||
@@ -19,6 +18,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
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'),
|
||||
@@ -51,6 +51,7 @@ List<MapEntry<Locale, String>> supportedLocales = const [
|
||||
MapEntry(Locale('ko'), '한국어'),
|
||||
MapEntry(Locale('ca'), 'Català'),
|
||||
MapEntry(Locale('ar'), 'العربية'),
|
||||
MapEntry(Locale('ml'), 'മലയാളം'),
|
||||
];
|
||||
const fallbackLocale = Locale('en');
|
||||
const localeDir = 'assets/translations';
|
||||
@@ -98,6 +99,34 @@ void backgroundFetchHeadlessTask(HeadlessTask task) async {
|
||||
BackgroundFetch.finish(taskId);
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void startCallback() {
|
||||
FlutterForegroundTask.setTaskHandler(MyTaskHandler());
|
||||
}
|
||||
|
||||
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 {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
try {
|
||||
@@ -119,6 +148,7 @@ void main() async {
|
||||
}
|
||||
final np = NotificationsProvider();
|
||||
await np.initialize();
|
||||
FlutterForegroundTask.initCommunicationPort();
|
||||
runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
@@ -153,6 +183,80 @@ class _ObtainiumState extends State<Obtainium> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
initPlatformState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
requestNonOptionalPermissions();
|
||||
initForegroundService();
|
||||
});
|
||||
}
|
||||
|
||||
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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
Future<void> initPlatformState() async {
|
||||
@@ -186,15 +290,25 @@ 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();
|
||||
BackgroundFetch.stop();
|
||||
} else {
|
||||
if (settingsProvider.useFGService) {
|
||||
BackgroundFetch.stop();
|
||||
startForegroundService(false);
|
||||
} else {
|
||||
stopForegroundService();
|
||||
BackgroundFetch.start();
|
||||
}
|
||||
}
|
||||
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,68 +350,71 @@ class _ObtainiumState extends State<Obtainium> {
|
||||
notifs.checkLaunchByNotif();
|
||||
});
|
||||
|
||||
return DynamicColorBuilder(
|
||||
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
|
||||
// Decide on a colour/brightness scheme based on OS and user settings
|
||||
ColorScheme lightColorScheme;
|
||||
ColorScheme darkColorScheme;
|
||||
if (lightDynamic != null &&
|
||||
darkDynamic != null &&
|
||||
settingsProvider.useMaterialYou) {
|
||||
lightColorScheme = lightDynamic.harmonized();
|
||||
darkColorScheme = darkDynamic.harmonized();
|
||||
} else {
|
||||
lightColorScheme = ColorScheme.fromSeed(
|
||||
seedColor: settingsProvider.themeColor,
|
||||
return WithForegroundTask(
|
||||
child: DynamicColorBuilder(
|
||||
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
|
||||
// Decide on a colour/brightness scheme based on OS and user settings
|
||||
ColorScheme lightColorScheme;
|
||||
ColorScheme darkColorScheme;
|
||||
if (lightDynamic != null &&
|
||||
darkDynamic != null &&
|
||||
settingsProvider.useMaterialYou) {
|
||||
lightColorScheme = lightDynamic.harmonized();
|
||||
darkColorScheme = darkDynamic.harmonized();
|
||||
} else {
|
||||
lightColorScheme = ColorScheme.fromSeed(
|
||||
seedColor: settingsProvider.themeColor,
|
||||
);
|
||||
darkColorScheme = ColorScheme.fromSeed(
|
||||
seedColor: settingsProvider.themeColor,
|
||||
brightness: Brightness.dark,
|
||||
);
|
||||
}
|
||||
|
||||
// set the background and surface colors to pure black in the amoled theme
|
||||
if (settingsProvider.useBlackTheme) {
|
||||
darkColorScheme = darkColorScheme
|
||||
.copyWith(surface: Colors.black)
|
||||
.harmonized();
|
||||
}
|
||||
|
||||
if (settingsProvider.useSystemFont) NativeFeatures.loadSystemFont();
|
||||
|
||||
return MaterialApp(
|
||||
title: 'Obtainium',
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: context.locale,
|
||||
navigatorKey: globalNavigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: settingsProvider.theme == ThemeSettings.dark
|
||||
? darkColorScheme
|
||||
: lightColorScheme,
|
||||
fontFamily: settingsProvider.useSystemFont
|
||||
? 'SystemFont'
|
||||
: 'Montserrat',
|
||||
),
|
||||
darkTheme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: settingsProvider.theme == ThemeSettings.light
|
||||
? lightColorScheme
|
||||
: darkColorScheme,
|
||||
fontFamily: settingsProvider.useSystemFont
|
||||
? 'SystemFont'
|
||||
: 'Montserrat',
|
||||
),
|
||||
home: Shortcuts(
|
||||
shortcuts: <LogicalKeySet, Intent>{
|
||||
LogicalKeySet(LogicalKeyboardKey.select):
|
||||
const ActivateIntent(),
|
||||
},
|
||||
child: const HomePage(),
|
||||
),
|
||||
);
|
||||
darkColorScheme = ColorScheme.fromSeed(
|
||||
seedColor: settingsProvider.themeColor,
|
||||
brightness: Brightness.dark,
|
||||
);
|
||||
}
|
||||
|
||||
// set the background and surface colors to pure black in the amoled theme
|
||||
if (settingsProvider.useBlackTheme) {
|
||||
darkColorScheme = darkColorScheme
|
||||
.copyWith(surface: Colors.black)
|
||||
.harmonized();
|
||||
}
|
||||
|
||||
if (settingsProvider.useSystemFont) NativeFeatures.loadSystemFont();
|
||||
|
||||
return MaterialApp(
|
||||
title: 'Obtainium',
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: context.locale,
|
||||
navigatorKey: globalNavigatorKey,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: settingsProvider.theme == ThemeSettings.dark
|
||||
? darkColorScheme
|
||||
: lightColorScheme,
|
||||
fontFamily: settingsProvider.useSystemFont
|
||||
? 'SystemFont'
|
||||
: 'Montserrat',
|
||||
),
|
||||
darkTheme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: settingsProvider.theme == ThemeSettings.light
|
||||
? lightColorScheme
|
||||
: darkColorScheme,
|
||||
fontFamily: settingsProvider.useSystemFont
|
||||
? 'SystemFont'
|
||||
: 'Montserrat',
|
||||
),
|
||||
home: Shortcuts(
|
||||
shortcuts: <LogicalKeySet, Intent>{
|
||||
LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
|
||||
},
|
||||
child: const HomePage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user