问题描述
我正在为我的一个颤振项目使用 Geolocator 包,并且我想在周期性的时间周期内获取我的当前位置。 为了获得许可,我编辑了 AndroidManifest.xml 并添加了这些行:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
一切正常,但是当我在其中一部 android 10 手机中使用 apk 时,一切都向南! 首先,每当我第一次检查应用程序的许可状态时
await Geolocator.checkPermission();
它在android 9中返回.denied
,在android 10中返回.deniedForever
,当检查权限时,android权限寻求弹出窗口出现,在android 9或以下版本中,允许按钮将权限设置为.always
但在 android 10 中设置为 .whileInUse
,我在设置中找不到任何选项以手动将其设置为 .always
。
经过一番研究,我了解到,我必须添加
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
我添加了它们,但 android 10 仍然不像 android 9,仍然缺少应用程序管理器中的“始终”选项!
我遇到的主要问题是,每当我离开屏幕时,Geolocator.getCurrentPosition()
就会停止工作,但相同的代码在 android 9 中完美运行。
模拟 -
class _MyHomePageState extends State<MyHomePage> {
List _loc = [];
bool _isSwitchon = false;
int _sec = 0;
String _permissonStatus = "";
Future _incrementCounter() async {
Timer.periodic(Duration(seconds: 1),(timer) async {
setState(() {
_sec++;
});
if (_isSwitchon == false) {
timer.cancel();
setState(() {});
} else if (_isSwitchon == true) {
Position currentPosition = await Geolocator.getCurrentPosition();
setState(() {
_loc.add(currentPosition.toString());
});
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),),body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Text("Time Elapsed"),Text(_sec.toString() + " sec"),Text(
'current Location',Container(
height: 300,child: ListView.builder(
itemCount: _loc.length,itemBuilder: (BuildContext context,int i) {
return Text(
_loc[i],);
},Row(
children: [
Expanded(
child: Container(),Column(
children: [
FloatingActionButton(
onpressed: () {
setState(() {
_isSwitchon = true;
});
_incrementCounter();
},child: Icon(Icons.play_arrow),Text("Start")
],SizedBox(
width: 50,Column(
children: [
FloatingActionButton(
onpressed: () {
setState(() {
_isSwitchon = false;
});
},child: Icon(Icons.cancel),Text("Stop")
],Expanded(
child: Container(),)
],Text(_permissonStatus),Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
Column(
children: [
FloatingActionButton(
onpressed: () async {
await Geolocator.checkPermission().then((value) =>
setState(
() => _permissonStatus = value.toString()));
},child: Icon(Icons
.signal_wifi_statusbar_connected_no_internet_4_sharp),Text("status")
],Column(
children: [
FloatingActionButton(
onpressed: () {
setState(() {
_loc = [];
});
},tooltip: 'Increment',child: Icon(Icons.add),Text("clear Location")
],Column(
children: [
FloatingActionButton(
onpressed: () async {
await Geolocator.requestPermission();
},child: Icon(Icons.gps_fixed),Text("Permission Seeking")
],],)
],);
}
}
我的清单中的场景 -
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gps_test">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<application
解决方法
你说的是 android 10,我不明白为什么没有正确的按钮,但为了将来证明这种方法已经过时了。
在 Android 11(API 级别 30)及更高版本上,系统对话框 不包括始终允许选项。相反,用户必须 在设置页面上启用后台位置,[...]。
您应该能够通过 .openLocationSettings()
或 .openAppSettings()
使用此 package 打开权限设置,然后用户必须导航到权限。