Flutter:尝试使用位置和 workManager 插件在后台访问位置数据
Flutter: Trying to access location data in background using location and workManager plugin
问题简述:
尝试使用 location 和 workManager 插件在后台访问用户的位置数据。
目前使用下面提到的代码,如果应用程序打开,我可以访问位置信息,因为 callbackDispatcher 是顶级函数,我无法调用位置插件。
当在 class 内完成调用时,位置插件会起作用。我正在尝试一种从 callbackDispatcher 访问 _getlocation() 的方法,我收到 PlatformException(NO_ACTIVITY).
我尝试过的事情:
发现很少有人面临类似问题 here, here and here
累了所有这些步骤,没有运气。
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:workmanager/workmanager.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
Location location = new Location();
void callbackDispatcher() {
Workmanager.executeTask((task, inputData) {
if (task == "simplePeriodicTask") {
print("task working");
_getLocation();
}
return Future.value(true);
});
}
LocationData _location;
String _error;
double lat;
double long;
_getLocation() async {
_error = null;
try {
var _locationResult = await location.getLocation();
_location = _locationResult;
lat = _location.latitude;
long = _location.longitude;
} on PlatformException catch (err) {
_error = err.code;
}
if (_error == null) {
// _check();
print(lat);
} else {
//dialog
print(_error);
}
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
Workmanager.initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode:
true // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
);
_checkPermissions();
}
// Permission for location
PermissionStatus _permissionGranted;
// final Location location = new Location();
_checkPermissions() async {
PermissionStatus permissionGrantedResult = await location.hasPermission();
setState(() {
_permissionGranted = permissionGrantedResult;
});
if (_permissionGranted == PermissionStatus.DENIED) {
_requestPermission();
} else if (_permissionGranted == PermissionStatus.GRANTED) {
_checkService();
}
}
_requestPermission() async {
if (_permissionGranted != PermissionStatus.GRANTED) {
PermissionStatus permissionRequestedResult =
await location.requestPermission();
setState(() {
_permissionGranted = permissionRequestedResult;
});
if (permissionRequestedResult != PermissionStatus.GRANTED) {
return;
} else if (permissionRequestedResult == PermissionStatus.GRANTED) {
_checkService();
}
}
}
//Permission ends
//services enabled function
bool _serviceEnabled;
_checkService() async {
bool serviceEnabledResult = await location.serviceEnabled();
setState(() {
_serviceEnabled = serviceEnabledResult;
});
if (_serviceEnabled == false) {
_requestService();
} else {
// _getLocation();
}
}
_requestService() async {
if (_serviceEnabled == null || !_serviceEnabled) {
bool serviceRequestedResult = await location.requestService();
setState(() {
_serviceEnabled = serviceRequestedResult;
});
if (!serviceRequestedResult) {
return;
} else {
// _getLocation();
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dart'),
),
body: Column(children: <Widget>[
RaisedButton(
child: Text('get Location'),
onPressed: () {
Workmanager.registerPeriodicTask(
"2",
"simplePeriodicTask",
// When no frequency is provided the default 15 minutes is set.
// Minimum frequency is 15 min. Android will automatically change your frequency to 15 min if you have configured a lower frequency.
);
print('task registered');
_getLocation();
}),
RaisedButton(
onPressed: () async {
await Workmanager.cancelAll();
print('task Destroyd');
},
child: Text("cancel"),
),
]),
);
}
}
正在尝试从 callbackDispatcher() 访问 _getlocation();
非常感谢对此的任何帮助。
我最近遇到了同样的问题。位置包不适用于 WorkManager 插件,我不知道原因,但这是我的解决方案;
/// This Function calls only from WorkManager
/// Used GeoLocator instead of Location package due to PlatformException(NO_ACTIVITY) error throwing
Future<String> getPlaceMarkLocationWhileAppOff() async {
Geolocator geoLocator = Geolocator()..forceAndroidLocationManager = true;
var _position = await geoLocator.getCurrentPosition(
// desiredAccuracy: LocationAccuracy.high,
);
var value = await geoLocator.placemarkFromCoordinates(_position.latitude, _position.longitude);
return _placeMark = "${value.first.subLocality}\n${value.first.subAdministrativeArea}";
}
离线时使用Geolocator包,在线时使用Location包..
希望对你有所帮助..
问题简述: 尝试使用 location 和 workManager 插件在后台访问用户的位置数据。 目前使用下面提到的代码,如果应用程序打开,我可以访问位置信息,因为 callbackDispatcher 是顶级函数,我无法调用位置插件。 当在 class 内完成调用时,位置插件会起作用。我正在尝试一种从 callbackDispatcher 访问 _getlocation() 的方法,我收到 PlatformException(NO_ACTIVITY).
我尝试过的事情: 发现很少有人面临类似问题 here, here and here 累了所有这些步骤,没有运气。
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:workmanager/workmanager.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
Location location = new Location();
void callbackDispatcher() {
Workmanager.executeTask((task, inputData) {
if (task == "simplePeriodicTask") {
print("task working");
_getLocation();
}
return Future.value(true);
});
}
LocationData _location;
String _error;
double lat;
double long;
_getLocation() async {
_error = null;
try {
var _locationResult = await location.getLocation();
_location = _locationResult;
lat = _location.latitude;
long = _location.longitude;
} on PlatformException catch (err) {
_error = err.code;
}
if (_error == null) {
// _check();
print(lat);
} else {
//dialog
print(_error);
}
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
Workmanager.initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode:
true // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
);
_checkPermissions();
}
// Permission for location
PermissionStatus _permissionGranted;
// final Location location = new Location();
_checkPermissions() async {
PermissionStatus permissionGrantedResult = await location.hasPermission();
setState(() {
_permissionGranted = permissionGrantedResult;
});
if (_permissionGranted == PermissionStatus.DENIED) {
_requestPermission();
} else if (_permissionGranted == PermissionStatus.GRANTED) {
_checkService();
}
}
_requestPermission() async {
if (_permissionGranted != PermissionStatus.GRANTED) {
PermissionStatus permissionRequestedResult =
await location.requestPermission();
setState(() {
_permissionGranted = permissionRequestedResult;
});
if (permissionRequestedResult != PermissionStatus.GRANTED) {
return;
} else if (permissionRequestedResult == PermissionStatus.GRANTED) {
_checkService();
}
}
}
//Permission ends
//services enabled function
bool _serviceEnabled;
_checkService() async {
bool serviceEnabledResult = await location.serviceEnabled();
setState(() {
_serviceEnabled = serviceEnabledResult;
});
if (_serviceEnabled == false) {
_requestService();
} else {
// _getLocation();
}
}
_requestService() async {
if (_serviceEnabled == null || !_serviceEnabled) {
bool serviceRequestedResult = await location.requestService();
setState(() {
_serviceEnabled = serviceRequestedResult;
});
if (!serviceRequestedResult) {
return;
} else {
// _getLocation();
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dart'),
),
body: Column(children: <Widget>[
RaisedButton(
child: Text('get Location'),
onPressed: () {
Workmanager.registerPeriodicTask(
"2",
"simplePeriodicTask",
// When no frequency is provided the default 15 minutes is set.
// Minimum frequency is 15 min. Android will automatically change your frequency to 15 min if you have configured a lower frequency.
);
print('task registered');
_getLocation();
}),
RaisedButton(
onPressed: () async {
await Workmanager.cancelAll();
print('task Destroyd');
},
child: Text("cancel"),
),
]),
);
}
}
正在尝试从 callbackDispatcher() 访问 _getlocation(); 非常感谢对此的任何帮助。
我最近遇到了同样的问题。位置包不适用于 WorkManager 插件,我不知道原因,但这是我的解决方案;
/// This Function calls only from WorkManager
/// Used GeoLocator instead of Location package due to PlatformException(NO_ACTIVITY) error throwing
Future<String> getPlaceMarkLocationWhileAppOff() async {
Geolocator geoLocator = Geolocator()..forceAndroidLocationManager = true;
var _position = await geoLocator.getCurrentPosition(
// desiredAccuracy: LocationAccuracy.high,
);
var value = await geoLocator.placemarkFromCoordinates(_position.latitude, _position.longitude);
return _placeMark = "${value.first.subLocality}\n${value.first.subAdministrativeArea}";
}
离线时使用Geolocator包,在线时使用Location包..
希望对你有所帮助..