首页 > 解决方案 > Flutter 隔离的平台位置权限错误

问题描述

我正在尝试在 Flutter 隔离线程上运行位置更新,该错误仅在运行隔离时出现。位置请求在主线程上没有问题。这里的目标是将其作为后台服务运行,仅使用 dart 代码。我正在使用Geolocator插件进行位置请求。

这是我在启动隔离时面临的错误:

发生异常。FlutterError(在初始化绑定之前访问了ServicesBinding.defaultBinaryMessenger。

我试图包含WidgetsFlutterBinding.ensureInitialized()之前的 runApp 但没有结果。查看错误的调用堆栈,似乎在 android 位置平台调用出现问题:checkPermissionStatus 无论我使用什么位置插件,都会发生这种情况,它会在权限状态检查时停止。

我认为这可能与等待位置权限用户输入有关,但是此检查在非 ui 线程上会失败吗?

有关示例,请参见这个简单的 main.dart 文件:

import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Isolate location test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Isolate location test'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Isolate isolate;
  bool isRunning = false;
  String output = '';
  ReceivePort receivePort;

  void start() async {
    receivePort = ReceivePort();
    await Isolate.spawn(locationUpdate, receivePort.sendPort);
    receivePort.listen((dynamic data) {
      setState(() {
        isRunning = true;
      });
    }, onDone: () {
      print("done");
    });
  }

  void stop() {
    if (isolate != null) {
      setState(() {
        isRunning = false;
      });
      receivePort.close();
      isolate.kill(priority: Isolate.immediate);
      isolate = null;
    }
  }

  static void locationUpdate(SendPort sendPort) async {
    Geolocator().checkGeolocationPermissionStatus().then((status) {
      sendPort.send(status);
    });
    // Geolocator().getCurrentPosition().then((pos) {
    //   sendPort.send(pos);
    // });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(child: Text(output)),
      floatingActionButton: FloatingActionButton(
        onPressed: isRunning ? stop : start,
        child: Icon(isRunning ? Icons.stop : Icons.play_circle_filled),
      ),
    );
  }
}

标签: androidflutterdartlocationdart-isolates

解决方案


推荐阅读