如何解决 "gps" 位置提供者需要 ACCESS_FINE_LOCATION 权限
How to solve "gps" location provider requires ACCESS_FINE_LOCATION permission
我正在开发一个 flutter 应用程序,它使用位置包来跟踪用户位置,它运行良好,但在同样的情况下,我已将位置包升级到 4.0.0(从 3.0.1),但现在是问题如出现:
E/AndroidRuntime(12224): at java.lang.reflect.Method.invoke(Native
Method) E/AndroidRuntime(12224): at
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/AndroidRuntime(12224): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
E/AndroidRuntime(12224): Caused by: android.os.RemoteException: Remote
stack trace: E/AndroidRuntime(12224): at
com.android.server.LocationManagerService.checkResolutionLevelIsSufficientForProviderUseLocked(LocationManagerService.java:1979)
E/AndroidRuntime(12224): at
com.android.server.LocationManagerService.hasGnssPermissions(LocationManagerService.java:1752)
E/AndroidRuntime(12224): at
com.android.server.LocationManagerService.addGnssDataListener(LocationManagerService.java:3053)
E/AndroidRuntime(12224): at
com.android.server.LocationManagerService.registerGnssStatusCallback(LocationManagerService.java:2991)
E/AndroidRuntime(12224): at
android.location.ILocationManager$Stub.onTransact(ILocationManager.java:583)
我已经在 android 清单文件中正确添加了权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
我在启动位置侦听器之前也检查了权限,但问题是允许存在。
我的定位服务:
class LocationService with ChangeNotifier {
static LocationService _instance;
factory LocationService() => _instance ??= LocationService._internal();
LocationService._internal();
bool hasPermission = false;
bool hasService = false;
String lastError;
Location _locationService = Location();
LatLng _currentLocation = LatLng(0, 0);
set currentLocation(LatLng value) {
_currentLocation = value;
notifyListeners();
}
LatLng get currentLocation => _currentLocation;
@override
void dispose() {
super.dispose();
}
void init() async {
await _locationService.changeSettings(
accuracy: LocationAccuracy.high,
interval: 1000,
);
try {
hasService = await _locationService.serviceEnabled();
if (hasService) {
print('Location service is enabled');
var permission = await _locationService.requestPermission();
hasPermission = permission == PermissionStatus.granted;
if (hasPermission) {
print('Location service has permission');
final location = await _locationService.getLocation();
currentLocation = LatLng(location.latitude, location.longitude);
_locationService.onLocationChanged.listen((data) =>
currentLocation = LatLng(data.latitude, data.longitude));
} else
throw geo.PermissionDeniedException(null);
} else {
hasService = await _locationService.requestService();
if (hasService) {
init();
return;
} else
throw geo.LocationServiceDisabledException();
}
} catch (e) {
lastError = e.toString();
String message;
if (e.runtimeType == geo.PermissionDeniedException)
message = 'Veuillez vérifier l\'autorisation d\'activation';
else if (e.runtimeType == geo.LocationServiceDisabledException)
message = 'Veuillez activer votre service GPS';
AlertUtils.showConfirmDialog(e.toString(),
content: message, okLabel: 'Settings', okFunction: () async {
Get.back();
if (e.runtimeType == geo.PermissionDeniedException) {
if (await geo.Geolocator.openAppSettings())
AlertUtils.showConfirmDialog('Réessayez?', okLabel: 'Réessayez?',
okFunction: () {
Get.back();
init();
});
else
AlertUtils.showConfirmDialog(
'Impossible d\'activer l\'autorisation automatiquement, merci de le faire manuellement.');
} else if (e.runtimeType == geo.LocationServiceDisabledException) {
if (await geo.Geolocator.openLocationSettings())
AlertUtils.showConfirmDialog('Réessayez?', okLabel: 'Réessayez?',
okFunction: () {
Get.back();
init();
});
else
AlertUtils.showConfirmDialog(
'Impossible d\'activer le GPS automatiquement, merci de le faire manuellement.');
}
});
}
}
}
感谢您的帮助
一些权限被认为是“危险的”(FINE_LOCATION 就是其中之一)。
为了保护用户,他们必须在运行时获得授权,以便用户知道这是否与他的操作有关。
为此:
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
它将显示一个对话框,用户可以在其中选择他是否授权您的应用使用位置信息。
然后使用这个函数获取用户答案:
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
如果用户接受一次,那么您的应用程序将记住它,您将不再需要发送此 DialogBox。请注意,如果用户决定,他可以稍后将其禁用。然后在请求位置之前,您必须测试权限是否仍然被授予:
public boolean checkLocationPermission()
{
String permission = "android.permission.ACCESS_FINE_LOCATION";
int res = this.checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
请关注:https://developer.android.com/training/permissions/requesting.html
我发现问题是在检查权限之前设置我的本地化插件的配置,所以我只是将它移动到 if 条件中,例如:
if (hasPermission) {
print('Location service has permission');
await _locationService.changeSettings(
accuracy: LocationAccuracy.high,
interval: 1000,
);
final location = await _locationService.getLocation();
currentLocation = LatLng(location.latitude, location.longitude);
_locationService.onLocationChanged.listen((data) =>
currentLocation = LatLng(data.latitude, data.longitude));
} else
throw geo.PermissionDeniedException(null);
我正在开发一个 flutter 应用程序,它使用位置包来跟踪用户位置,它运行良好,但在同样的情况下,我已将位置包升级到 4.0.0(从 3.0.1),但现在是问题如出现:
E/AndroidRuntime(12224): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(12224): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) E/AndroidRuntime(12224): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980) E/AndroidRuntime(12224): Caused by: android.os.RemoteException: Remote stack trace: E/AndroidRuntime(12224): at com.android.server.LocationManagerService.checkResolutionLevelIsSufficientForProviderUseLocked(LocationManagerService.java:1979) E/AndroidRuntime(12224): at com.android.server.LocationManagerService.hasGnssPermissions(LocationManagerService.java:1752) E/AndroidRuntime(12224): at com.android.server.LocationManagerService.addGnssDataListener(LocationManagerService.java:3053) E/AndroidRuntime(12224): at com.android.server.LocationManagerService.registerGnssStatusCallback(LocationManagerService.java:2991) E/AndroidRuntime(12224): at android.location.ILocationManager$Stub.onTransact(ILocationManager.java:583)
我已经在 android 清单文件中正确添加了权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
我在启动位置侦听器之前也检查了权限,但问题是允许存在。
我的定位服务:
class LocationService with ChangeNotifier {
static LocationService _instance;
factory LocationService() => _instance ??= LocationService._internal();
LocationService._internal();
bool hasPermission = false;
bool hasService = false;
String lastError;
Location _locationService = Location();
LatLng _currentLocation = LatLng(0, 0);
set currentLocation(LatLng value) {
_currentLocation = value;
notifyListeners();
}
LatLng get currentLocation => _currentLocation;
@override
void dispose() {
super.dispose();
}
void init() async {
await _locationService.changeSettings(
accuracy: LocationAccuracy.high,
interval: 1000,
);
try {
hasService = await _locationService.serviceEnabled();
if (hasService) {
print('Location service is enabled');
var permission = await _locationService.requestPermission();
hasPermission = permission == PermissionStatus.granted;
if (hasPermission) {
print('Location service has permission');
final location = await _locationService.getLocation();
currentLocation = LatLng(location.latitude, location.longitude);
_locationService.onLocationChanged.listen((data) =>
currentLocation = LatLng(data.latitude, data.longitude));
} else
throw geo.PermissionDeniedException(null);
} else {
hasService = await _locationService.requestService();
if (hasService) {
init();
return;
} else
throw geo.LocationServiceDisabledException();
}
} catch (e) {
lastError = e.toString();
String message;
if (e.runtimeType == geo.PermissionDeniedException)
message = 'Veuillez vérifier l\'autorisation d\'activation';
else if (e.runtimeType == geo.LocationServiceDisabledException)
message = 'Veuillez activer votre service GPS';
AlertUtils.showConfirmDialog(e.toString(),
content: message, okLabel: 'Settings', okFunction: () async {
Get.back();
if (e.runtimeType == geo.PermissionDeniedException) {
if (await geo.Geolocator.openAppSettings())
AlertUtils.showConfirmDialog('Réessayez?', okLabel: 'Réessayez?',
okFunction: () {
Get.back();
init();
});
else
AlertUtils.showConfirmDialog(
'Impossible d\'activer l\'autorisation automatiquement, merci de le faire manuellement.');
} else if (e.runtimeType == geo.LocationServiceDisabledException) {
if (await geo.Geolocator.openLocationSettings())
AlertUtils.showConfirmDialog('Réessayez?', okLabel: 'Réessayez?',
okFunction: () {
Get.back();
init();
});
else
AlertUtils.showConfirmDialog(
'Impossible d\'activer le GPS automatiquement, merci de le faire manuellement.');
}
});
}
}
}
感谢您的帮助
一些权限被认为是“危险的”(FINE_LOCATION 就是其中之一)。
为了保护用户,他们必须在运行时获得授权,以便用户知道这是否与他的操作有关。
为此:
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
它将显示一个对话框,用户可以在其中选择他是否授权您的应用使用位置信息。
然后使用这个函数获取用户答案:
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
如果用户接受一次,那么您的应用程序将记住它,您将不再需要发送此 DialogBox。请注意,如果用户决定,他可以稍后将其禁用。然后在请求位置之前,您必须测试权限是否仍然被授予:
public boolean checkLocationPermission()
{
String permission = "android.permission.ACCESS_FINE_LOCATION";
int res = this.checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
请关注:https://developer.android.com/training/permissions/requesting.html
我发现问题是在检查权限之前设置我的本地化插件的配置,所以我只是将它移动到 if 条件中,例如:
if (hasPermission) {
print('Location service has permission');
await _locationService.changeSettings(
accuracy: LocationAccuracy.high,
interval: 1000,
);
final location = await _locationService.getLocation();
currentLocation = LatLng(location.latitude, location.longitude);
_locationService.onLocationChanged.listen((data) =>
currentLocation = LatLng(data.latitude, data.longitude));
} else
throw geo.PermissionDeniedException(null);