Я пытаюсь запустить обновление местоположения в потоке изолята Flutter, ошибка присутствует только при запуске изолята. Запросы местоположения работают без проблем в основном потоке. Цель здесь - запустить его в качестве фоновой службы, работающей только с кодом дротика. Я использую плагин Geolocator для запросов местоположения.
Это ошибка, с которой я сталкиваюсь при запуске изолята:
Произошло исключение. FlutterError (ServicesBinding.defaultBinaryMessenger был доступен до инициализации привязки.
Я попытался включить WidgetsFlutterBinding.ensureInitialized()
перед runApp, но без результатов. Глядя на стек вызовов ошибки, кажется, возникают проблемы при вызове платформы android: checkPermissionStatus
Это происходит независимо от того, какой плагин местоположения я использую, он останавливается при проверке состояния разрешений.
Я подумал, что это может быть связано с ожиданием разрешения местоположения пользовательский ввод, но эта проверка не будет выполнена в потоке, не являющемся пользовательским интерфейсом?
См. этот простой файл 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),
),
);
}
}