在Flutter启动Android的后台服务

背景

(本文翻译自YouTube视频:https://www.youtube.com/watch?v=NXuAzXY_KOo&t=572s)
Android和iOS在后台服务的处理方式不同,因此Flutter并没有在这方面做统一处理,而是需要调用原生平台的代码来实现该功能,下面就简单介绍如何在Flutter中与Android的后台服务进行交互。

实现

  1. 在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");
    }
  }
}
  1. 新建 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);
        }
    }
}
  1. 新建 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;
    }
}
  1. 最后,在 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);
    }
  }
}

最终效果如下图所示,一开始没有后台任务,点击按钮后,再查看通知栏,发现后台服务已启动。在Flutter启动Android的后台服务_第1张图片
在Flutter启动Android的后台服务_第2张图片

你可能感兴趣的:(flutter)