权限
首先在androidManifest.xml 加入权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<service
android:name="com.pravera.flutter_foreground_task.service.ForegroundService"
android:stopWithTask="true" />
开始
简单使用
//初始化这个前台任务
void _initForeground() {
FlutterForegroundTask.init(
androidNotificationOptions:
AndroidNotificationOptions(channelId: 'notification_channel_id', channelName: 'Foreground Notification'),
iosNotificationOptions: const IOSNotificationOptions(),
foregroundTaskOptions: const ForegroundTaskOptions());
}
然后在initState中调用这个_initForeground()函数,再使用 FlutterForegroundTask.startService 设置一下和标题和内容就可以启动一个简单的前台服务了。
回调函数
当我们想使用这个前台服务的操作的回调就需要设置这个服务的 Callback 首先要继承 TaskHandler 抽象类实现自己的处理前台服务的处理程序, 我们来看一下这个抽象类TaskHandler,
一共有五个方法,以及三个抽象方法
- onStart 当我们启动前台服务时,会回调用这个函数,
- onRepeatEvent 前台服务重复事件的回调,
- onDestroy自然不用多说,销毁啦~
- onNotificationPressed点击通知栏时回调,默认启动app,
- onNotificationButtonPressed 当通知栏里存在按钮 当点击按钮时,会将按钮id传递进来,可以根据不同的id 进行不同的处理
///简单的实现一下三个函数吧
class MyTaskHandler extends TaskHandler {
@override
Future<void> onDestroy(DateTime timestamp, SendPort? sendPort) async {
print("销毁事件");
}
@override
Future<void> onRepeatEvent(DateTime timestamp, SendPort? sendPort) async {
print("重复事件");
}
@override
Future<void> onStart(DateTime timestamp, SendPort? sendPort) async {
print("启动服务");
}
}
//回调函数应始终是顶级函数。所以他放在外面
//必须调用 setTaskHandler 函数来在后台处理任务。
@pragma('vm:entry-point')
void startCallback() {
FlutterForegroundTask.setTaskHandler(MyTaskHandler());
}
然后在我们的前台服务中加上这个回调函数
FlutterForegroundTask.startService(
notificationTitle: "一个服务", notificationText: "1111", callback: startCallback);
再点击启动按钮调用这个函数就会打印
前台服务初始化
在初始化中需要传3个参数,分别是 AndroidNotificationOptions ,IOSNotificationOptions ForegroundTaskOptions,
在AndroidNotificationOptions的参数
- id:通知的唯一 ID。
- channelId :通知通道的唯一 ID,
- channelName:通知通道的名称。此值在通知设置中向用户显示。
- channelDescription :描述。
- channelImportance :重要等级。
- priority:通知的优先级。
- showWhen:显示时间。
- isSticky:通知被销毁是否重建
- iconData :通知的图标,默认是app的图标
- buttons :通知下的按钮,最多三个,这个按钮点击会调用handle中onNotificationButtonPressed,并将按钮id传过去
IOSNotificationOptions
他比较简单只有两个参数,showNotification是否显示通知默认为true,playSound接收通知时是否播放声音,默认false
ForegroundTaskOptions
- interval:任务调用的间隔
- isOnceEvent :重复任务回调是不是只调用一次
- autoRunOnBoot :是否在引导时自动运行前台任务。
- allowWakeLock :通知时可以唤醒锁定
检测权限
这个就完全是插件的官方案例啦
///启动前台服务需要一系列的授权
Future<void> _requestPermissionForAndroid() async {
if (!Platform.isAndroid) {
return;
}
if (!await FlutterForegroundTask.canDrawOverlays) {
///打开设置页面,您可以在其中允许拒绝“android.permission.SYSTEM_ALERT_WINDOW”权限。传递“forceOpen”布尔值以打开权限页面,即使已授予。
await FlutterForegroundTask.openSystemAlertWindowSettings();
}
if (!await FlutterForegroundTask.isIgnoringBatteryOptimizations) {
//判断是否开启排除电池优化权限,如果没有开启去开启
await FlutterForegroundTask.requestIgnoreBatteryOptimization();
}
///检查前台服务权限授予的状态
final NotificationPermission notificationPermissionStatus =
await FlutterForegroundTask.checkNotificationPermission();
if (notificationPermissionStatus != NotificationPermission.granted) {
//没有授予先去请求
await FlutterForegroundTask.requestNotificationPermission();
}
}
使用isolate
在TaskHandler中利用sendPort将事件放在isolate中处理,在MyTaskHandler 定义一个 sendPort用来发送信息,
有发送端口,当然有接收端口啦!
在接收端口收到信息后就打印出来,于是我们得到
还可以在不重新启动服务的情况下获取以前的接收端口。
if (await FlutterForegroundTask.isRunningService) {
final newReceivePort = FlutterForegroundTask.receivePort;
_registerReceivePort(newReceivePort);
}
结束服务调用
FlutterForegroundTask.stopService();
ending ~~~~~