如何在android 10或更高版本中获得“总是”位置的许可? (高于 API 29)?
Posted
技术标签:
【中文标题】如何在android 10或更高版本中获得“总是”位置的许可? (高于 API 29)?【英文标题】:How to get "always" permission of location for flutter in android 10 or above? (above API 29)? 【发布时间】:2021-08-30 23:39:44 【问题描述】:我正在为我的一个颤振项目使用 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();
,
tooltip: 'Increment',
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
【问题讨论】:
【参考方案1】:你说的是android 10,我不明白为什么没有右键,但为了将来证明这个方法已经过时了。
Android docs:
但是,在 Android 11(API 级别 30)及更高版本上,系统对话框 不包括“始终允许”选项。相反,用户必须 在设置页面上启用背景位置,[...]。
您应该能够通过.openLocationSettings()
或.openAppSettings()
使用此package 打开权限设置,然后用户必须导航到权限。
【讨论】:
以上是关于如何在android 10或更高版本中获得“总是”位置的许可? (高于 API 29)?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 api 17 或更高版本中使 android seekbar 全宽?
如何在 Android M 或更高版本中在运行时更改权限时防止重新创建 Activity
如何在 Android SDK 26 或更高版本上以编程方式重置锁屏密码
不再支持源选项 5。使用 6 或更高版本的 Android Studio
如何查看我的 Xamarin.Forms 应用程序是不是在 Visual Studio 中的 Android 6(或更高版本)上运行或/和可运行?