在Flutter启动Android的后台服务
16lz
2021-01-24
背景
(本文翻译自YouTube视频:https://www.youtube.com/watch?v=NXuAzXY_KOo&t=572s)
Android和iOS在后台服务的处理方式不同,因此Flutter并没有在这方面做统一处理,而是需要调用原生平台的代码来实现该功能,下面就简单介绍如何在Flutter中与Android的后台服务进行交互。
实现
- 在Flutter中有一个按钮,点击后会开启后台服务。此外建立了一个MethodChannel,通过该通道去调用Android原生代码里的 startService()。
class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState();}class _MyHomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: RaisedButton( child: Text("开启后台任务"), onPressed: () { startService(); }, ), ) ); } void startService() async{ if(Platform.isAndroid) { var methodChannel = MethodChannel("com.example.flutterapp"); String data = await methodChannel.invokeMethod("startService"); print("data: $data"); } }}
- 新建 MyApplication 继承自 FlutterApplication,并在 onCreate() 中创建 NotificationChannel 和 NotificationManager (Android 26 以上需要)。
public class MyApplication extends FlutterApplication { @Override public void onCreate() { super.onCreate(); //Android 8.0 26 //一种 Notification 对应一个 NotificationChannel //在 Application 注册 channel 可以在 app 启动时就完成注册 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("messages", "Messages", NotificationManager.IMPORTANCE_LOW); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); } }}
- 新建 MyService 继承自 Service,并在 onCreate() 中进行 Android 版本判断,对 26以上进行特殊处理(记得在 AndroidManifest 里注册 service)。
public class MyService extends Service { @Override public void onCreate() { super.onCreate(); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "messages") .setContentText("正在后台运行") .setContentTitle("Flutter后台") .setSmallIcon(R.drawable.launch_background); startForeground(101, builder.build()); } } @Override public IBinder onBind(Intent intent) { return null; }}
- 最后,在 MainActivity 中打开 注册 MethodChannel 并提供 startService() 给 Flutter 调用。
public class MainActivity extends FlutterActivity { private Intent serviceIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); serviceIntent = new Intent(MainActivity.this, MyService.class); new MethodChannel(getFlutterView(), "com.example.flutterapp") .setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) { if(methodCall.method.equals("startService")) { startService(); result.success("服务已启动"); } } }); } @Override protected void onDestroy() { super.onDestroy(); stopService(serviceIntent); } private void startService() { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(serviceIntent); } else { startService(serviceIntent); } }}
最终效果如下图所示,一开始没有后台任务,点击按钮后,再查看通知栏,发现后台服务已启动。
更多相关文章
- android中ListView点击和里边按钮或ImageView点击不能同时生效问
- Android驱动程序开发和调试环境配置
- [每天学点Android开发]Building Web Apps in WebView
- Android实现音乐的播放与停止(Service的初级应用)
- android 反射的使用场景
- Android问题集(七)——TableLayout 中让TableRow中的控件填充满整
- Android(安卓)源码获取-----在Windows环境下通过Git得到Android
- 鉴客 Android中如何生成带圆角的Bitmap图片
- 阅读手札:《:第一行代码》(第一章)