saywut / flutter_foreground_service_plugin Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Hi,
first of all, great work, awesome package!
I am getting the following error occasionally. This is happening to some of my users, not all, mostly HUAWEI devices, some SAMSUNG.
Context.startForegroundService() did not then call Service.startForeground():
android.app.ActivityThread$H.handleMessage (ActivityThread.java:2240) android.os.Handler.dispatchMessage (Handler.java:106) android.os.Looper.loop (Looper.java:246) android.app.ActivityThread.main (ActivityThread.java:8512) java.lang.reflect.Method.invoke (Method.java) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:602) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1130)
I have read that Android gives the application 5 seconds to call "startForeground", but from the code i do not see any issues which could cause a delay greater than 5 secs.
Never had this issue while testing, any ideas how to handle the crashes?
KR,
Andreas
It would be nice if we could specify the importance of the notification channel. This would allow a silent notification (one that doesn't appear continuously)
NotificationChannel chan1 = new NotificationChannel("default", "default", NotificationManager.IMPORTANCE_LOW);
Is there any way to use other plugins inside foreground service?
I'm trying to save how many times the service ran, but unfortunately get_storage
plugin doesn't work.
I've also tried foreground_service
plugin. Same issue with that one.
Is there some kind of limitations?
import 'package:flutter/material.dart';
import 'package:flutter_foreground_service_plugin/flutter_foreground_service_plugin.dart';
import 'package:get_storage/get_storage.dart';
void main() async {
await GetStorage.init();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Builder(
builder: (context) {
return Center(
child: Column(
children: [
TextButton(
child: Text('Start service'),
onPressed: () async {
await FlutterForegroundServicePlugin
.startForegroundService(
notificationContent: NotificationContent(
iconName: 'ic_launcher',
titleText: 'Title Text',
color: Colors.green,
priority: NotificationPriority.high,
),
notificationChannelContent: NotificationChannelContent(
id: 'some_id',
nameText: 'settings title',
descriptionText: 'settings description text',
),
isStartOnBoot: false,
);
},
),
TextButton(
child: Text('Stop service'),
onPressed: () async {
await FlutterForegroundServicePlugin
.stopForegroundService();
},
),
TextButton(
child: Text('Is service running'),
onPressed: () async {
var isRunning = await FlutterForegroundServicePlugin
.isForegroundServiceRunning();
print(isRunning);
var snackbar = SnackBar(
content: Text('$isRunning'),
duration: Duration(milliseconds: 500),
);
Scaffold.of(context).showSnackBar(snackbar);
},
),
TextButton(
child: Text('Start task'),
onPressed: () async {
await FlutterForegroundServicePlugin.startPeriodicTask(
periodicTaskFun: periodicTaskFun,
period: const Duration(seconds: 5),
);
},
),
TextButton(
child: Text('Stop task'),
onPressed: () async {
await FlutterForegroundServicePlugin.stopPeriodicTask();
},
),
],
),
);
},
),
),
);
}
}
void periodicTaskFun() {
int ran = GetStorage().read('ran') ?? 0;
GetStorage().write('ran', ran + 1);
FlutterForegroundServicePlugin.executeTask(() async {
// this will refresh the notification content each time the task is fire
// if you want to refresh the notification content too each time
// so don't set a low period duretion because android isn't handling it very well
await FlutterForegroundServicePlugin.refreshForegroundServiceContent(
notificationContent: NotificationContent(
iconName: 'ic_launcher',
titleText: 'Task ran',
bodyText: '${DateTime.now()}',
subText: '${ran.toString()} times',
color: Colors.blue,
),
);
print('Task ran: ${ran.toString()} times');
});
}
how can i send a state to foreground service and get same state from it? May be you can update your plugin about it.
Please check it: fluttercommunity/get_it#145
and i made an example for this problem: https://github.com/yakupbaser/demogetit
When i try to use the example to change notification content. I get this error.
E/flutter (21734): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'toRawHandle' was called on null.
E/flutter (21734): Tried calling: toRawHandle()
E/flutter (21734): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
E/flutter (21734): #1 FlutterForegroundServicePlugin.startPeriodicTask (package:flutter_foreground_service_plugin/flutter_foreground_service_plugin.dart:162:60)
I created a new project and integrated this plugin and it worked fine . But i inserted it into an existing project with some plugins which include firebase plugins....When ever i try to run periodicTaskFun i get the error below:
D/EGL_emulation( 9082): eglCreateContext: 0x8941c020: maj 2 min 0 rcv 2
D/EGL_emulation( 9082): eglCreateContext: 0x8941c5c0: maj 2 min 0 rcv 2
D/ ( 9082): HostConnection::get() New Host Connection established 0x8e28ecc0, tid 9153
D/EGL_emulation( 9082): eglMakeCurrent: 0x8941c5c0: ver 2 0 (tinfo 0x862ff6e0)
E/BluetoothAdapter( 9082): Bluetooth binder is null
W/FlutterEnginePluginRegistry( 9082): Attempted to register plugin (io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry$ShimRegistrarAggregate@be7922c) but it was already registered with this FlutterEngine (io.flutter.embedding.engine.FlutterEngine@a2ad4f5).
E/MethodChannel#( 9082): Parameter messenger must not be null.
D/AndroidRuntime( 9082): Shutting down VM
E/AndroidRuntime( 9082): FATAL EXCEPTION: main
E/AndroidRuntime( 9082): Process: com.couriax.driver, PID: 9082
E/AndroidRuntime( 9082): java.lang.RuntimeException: Unable to start service com.saywut.flutter_foreground_service_plugin.FlutterForegroundService@92d0fb with Intent { act=START_FOREGROUND_TASK cmp=com.couriax.driver/com.saywut.flutter_foreground_service_plugin.FlutterForegroundService }: java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.BinaryMessenger.setMessageHandler(java.lang.String, io.flutter.plugin.common.BinaryMessenger$BinaryMessageHandler)' on a null object reference
E/AndroidRuntime( 9082): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3491)
E/AndroidRuntime( 9082): at android.app.ActivityThread.-wrap20(Unknown Source:0)
E/AndroidRuntime( 9082): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
E/AndroidRuntime( 9082): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 9082): at android.os.Looper.loop(Looper.java:164)
E/AndroidRuntime( 9082): at android.app.ActivityThread.main(ActivityThread.java:6494)
E/AndroidRuntime( 9082): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 9082): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
E/AndroidRuntime( 9082): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
E/AndroidRuntime( 9082): Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.BinaryMessenger.setMessageHandler(java.lang.String, io.flutter.plugin.common.BinaryMessenger$BinaryMessageHandler)' on a null object reference
E/AndroidRuntime( 9082): at io.flutter.plugin.common.MethodChannel.setMethodCallHandler(MethodChannel.java:119)
E/AndroidRuntime( 9082): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundServicePlugin.setupChannels(FlutterForegroundServicePlugin.java:42)
E/AndroidRuntime( 9082): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundServicePlugin.registerWith(FlutterForegroundServicePlugin.java:22)
E/AndroidRuntime( 9082): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundService.createFlutterEngineAndBackgroundChannel(FlutterForegroundService.java:220)
E/AndroidRuntime( 9082): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundService.onStartCommand(FlutterForegroundService.java:95)
E/AndroidRuntime( 9082): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3474)
E/AndroidRuntime( 9082): ... 8 more
will be glad if i could get help.
MY FLUTTER DOCTOR
[√] Flutter (Channel stable, 1.22.5, on Microsoft Windows [Version 10.0.19042.804], locale en-US)
• Flutter version 1.22.5 at C:\src\flutter
• Framework revision 7891006299 (2 months ago), 2020-12-10 11:54:40 -0800
• Engine revision ae90085a84
• Dart version 2.10.4
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at C:\Users\Jo\AppData\Local\Android\Sdk
• Platform android-30, build-tools 30.0.3
• ANDROID_SDK_ROOT = C:\Users\Jo\AppData\Local\Android\Sdk
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.
[!] Android Studio (version 4.1.0)
• Android Studio at C:\Program Files\Android\Android Studio
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
[!] VS Code (version 1.52.1)
• VS Code at C:\Users\Jo\AppData\Local\Programs\Microsoft VS Code
X Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[√] Connected device (1 available)
• Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 8.1.0 (API 27) (emulator)
! Doctor found issues in 2 categories.
EDIT
after further testing trying to find the problem.. i discovered the conflicting plugin was flutter_geofire: ^1.0.3
when ever the both of them are on the app the service
wil start but the task
will not.
Is it possible to start the foreground service when the devices boots?
Hi dear,
I have a problem with enableSound and enableVibration. These flags seem are not working if I set both to true.
void periodicTaskFun() {
FlutterForegroundServicePlugin.executeTask(() async {
// this will refresh the notification content each time the task is fire
// if you want to refresh the notification content too each time
// so don't set a low period duretion because android isn't handling it very well
await FlutterForegroundServicePlugin.refreshForegroundServiceContent(
notificationContent: NotificationContent(
iconName: 'ic_launcher',
titleText: 'Title Text',
bodyText: '${DateTime.now()}',
subText: 'subText',
color: Colors.red,
enableSound: true,
enableVibration: true),
);
print(DateTime.now());
});
}
I have also tried to change the NotificationContent priority and the NotificationChannelContent importance, but nothing..
P.S. I have already set the android permission to the AndroidManifest
<uses-permission android:name="android.permission.VIBRATE" />
Could you help me?
hi, i tested your plugin and its great but i worked your example, it uses 65 mb ram in normally but when i clicked to "start service" and "start task" over and over, The memory usage increased exponentially with each click. and it reached to 250 mb. So it seems a bug. Service should only work once.
how can i handle this? i started foreground service. And i terminated the app with sliding sideways. (app is still running in memory). When i clicked to notification, the app is openning. But how do I know if I opened the application via notification?
i need to learn that the app opened first or opened via notification. So i need two answers as like that messages:
the app says: I opened for the first time.
or
the app says: im coming from notification tapped, I was already working in background before.
I'm using the startPeriodicTask which works well, but it doesn't always run on the given interval.
I'm setting it up as followed:
FlutterForegroundServicePlugin.startPeriodicTask(
periodicTaskFun: periodicTaskFun,
period: const Duration(minutes: 15),
);
Then my periodicTaskFun
:
void periodicTaskFun() {
FlutterForegroundServicePlugin.executeTask(() async {
// initialize garmin
print("initializing...");
await GC.GarminCompanion.init(licenseKey);
print("initialized");
if (await GC.GarminCompanion.isBluetoothEnabled()) {
print("getting devices...");
final foundDevices = await GC.GarminCompanion.devices();
// wait for device setup to finish when pairing
print("waiting for first device...");
if (foundDevices.length == 0) {
return await FlutterForegroundServicePlugin
.refreshForegroundServiceContent(
notificationContent: NotificationContent(
iconName: 'ic_launcher',
titleText: 'Wavy',
bodyText: 'Connect wearable',
priority: NotificationPriority.high,
enableVibration: true,
enableSound: true,
color: Colors.blue,
),
);
}
final device = foundDevices.first;
print("device: ${device.address}");
var events = [];
StreamSubscription liveDataSubscription = device.liveData([
GC.RealTimeDataType.HEART_RATE_VARIABILITY,
GC.RealTimeDataType.HEART_RATE
]).listen((event) {
events.add(event);
print("data: ${events.length}");
FlutterForegroundServicePlugin.refreshForegroundServiceContent(
notificationContent: NotificationContent(
iconName: 'ic_launcher',
titleText: 'Wavy',
bodyText: "data: ${events.length}",
priority: NotificationPriority.high,
color: Colors.blue,
),
);
});
await Future.delayed(const Duration(minutes: 1), () {});
await liveDataSubscription.cancel();
} else {
await FlutterForegroundServicePlugin.refreshForegroundServiceContent(
notificationContent: NotificationContent(
iconName: 'ic_launcher',
titleText: 'Wavy',
bodyText: 'Enable bluetooth for wavy to work!',
priority: NotificationPriority.high,
color: Colors.blue,
),
);
}
});
This plugin is v great, but since it is not migrated to Null Safety, I cannot build an apk with sound Null Safety. It would be great if you migrate the plugin to null safety.
When I call FlutterForegroundServicePlugin.startPeriodicTask,get the following error:
D/AndroidRuntime( 7848): Shutting down VM E/AndroidRuntime( 7848): FATAL EXCEPTION: main E/AndroidRuntime( 7848): Process: xxx, PID: 7848 E/AndroidRuntime( 7848): java.lang.RuntimeException: Unable to start service com.saywut.flutter_foreground_service_plugin.FlutterForegroundService@204d1b2 with Intent { act=START_FOREGROUND_TASK cmp=xxx/com.saywut.flutter_foreground_service_plugin.FlutterForegroundService }: java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.BinaryMessenger.setMessageHandler(java.lang.String, io.flutter.plugin.common.BinaryMessenger$BinaryMessageHandler)' on a null object reference E/AndroidRuntime( 7848): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3057) E/AndroidRuntime( 7848): at android.app.ActivityThread.access$2200(ActivityThread.java:165) E/AndroidRuntime( 7848): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1467) E/AndroidRuntime( 7848): at android.os.Handler.dispatchMessage(Handler.java:102) E/AndroidRuntime( 7848): at android.os.Looper.loop(Looper.java:150) E/AndroidRuntime( 7848): at android.app.ActivityThread.main(ActivityThread.java:5546) E/AndroidRuntime( 7848): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime( 7848): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794) E/AndroidRuntime( 7848): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684) E/AndroidRuntime( 7848): Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.BinaryMessenger.setMessageHandler(java.lang.String, io.flutter.plugin.common.BinaryMessenger$BinaryMessageHandler)' on a null object reference E/AndroidRuntime( 7848): at io.flutter.plugin.common.MethodChannel.setMethodCallHandler(MethodChannel.java:119) E/AndroidRuntime( 7848): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundServicePlugin.setupChannels(FlutterForegroundServicePlugin.java:45) E/AndroidRuntime( 7848): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundServicePlugin.registerWith(FlutterForegroundServicePlugin.java:23) E/AndroidRuntime( 7848): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundService.createFlutterEngineAndBackgroundChannel(FlutterForegroundService.java:220) E/AndroidRuntime( 7848): at com.saywut.flutter_foreground_service_plugin.FlutterForegroundService.onStartCommand(FlutterForegroundService.java:95) E/AndroidRuntime( 7848): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3040) E/AndroidRuntime( 7848): ... 8 more I/Process ( 7848): Sending signal. PID: 7848 SIG: 9
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.