![](/img/trans.png)
[英]Android App crashes when disabling the location permission from settings?
[英]App crashes on disabling location permission from settings
我有一个在后台连续运行以获取位置更新的服务类。 一切正常,但是当我从设置中禁用权限时,应用程序崩溃。 从设置中禁用位置权限后,我无法弄清楚为什么应用程序崩溃。 以下是我在logcat中获得的内容。
FATAL EXCEPTION: GoogleApiHandler
Process: com.android.myapp, PID: 7703
java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.
at android.os.Parcel.readException(Parcel.java:1683)
at android.os.Parcel.readException(Parcel.java:1636)
at com.google.android.gms.internal.zzeu.zza(Unknown Source)
at com.google.android.gms.internal.zzcfa.zzif(Unknown Source)
at com.google.android.gms.internal.zzcfd.getLastLocation(Unknown Source)
at com.google.android.gms.internal.zzcfk.getLastLocation(Unknown Source)
at com.google.android.gms.location.zzg.zza(Unknown Source)
at com.google.android.gms.common.api.internal.zze.zza(Unknown Source)
at com.google.android.gms.common.api.internal.zzbo.zzb(Unknown Source)
at com.google.android.gms.common.api.internal.zzbo.zzaiw(Unknown Source)
at com.google.android.gms.common.api.internal.zzbo.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzac.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzn.zzakr(Unknown Source)
at com.google.android.gms.common.internal.zze.zzw(Unknown Source)
at com.google.android.gms.common.internal.zzi.zzaks(Unknown Source)
at com.google.android.gms.common.internal.zzh.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
这是我的服务班级。 它始终在后台运行。
public class LocationService extends Service {
...
...
...
@Override
public void onCreate() {
try {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
onNewLocation(locationResult.getLastLocation());
}
};
createLocationRequest();
getLastLocation();
requestLocationUpdates();
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service started");
return START_STICKY;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Log.i(TAG, "Service destroy");
Toast.makeText(getApplicationContext(), "Service Destroy", Toast.LENGTH_SHORT).show();
}
/**
* Makes a request for location updates. Note that in this sample we merely log the
* {@link SecurityException}.
*/
public void requestLocationUpdates() {
Log.i(TAG, "Requesting location updates");
Utils.setRequestingLocationUpdates(this, true);
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, false);
Log.e(TAG, "Lost location permission. Could not request updates. " + unlikely);
}
}
/**
* Removes location updates. Note that in this sample we merely log the
* {@link SecurityException}.
*/
public void removeLocationUpdates() {
Log.i(TAG, "Removing location updates");
try {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
Utils.setRequestingLocationUpdates(this, false);
stopSelf();
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, true);
Log.e(TAG, "Lost location permission. Could not remove updates. " + unlikely);
}
}
private void getLastLocation() {
try {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(task -> {
if (task.isSuccessful() && task.getResult() != null) {
mLocation = task.getResult();
} else {
Log.w(TAG, "Failed to get location.");
}
});
} catch (SecurityException unlikely) {
Log.e(TAG, "Lost location permission." + unlikely);
}
}
private void onNewLocation(Location location) {
Log.i(TAG, "New location: " + location);
mLocation = location;
// Doing some operations using location data.
mPreviousLocation = mLocation;
System.gc();
}
/**
* Sets the location request parameters.
*/
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest
.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Log.i(TAG, "Service Task Removed");
Toast.makeText(getApplicationContext(), "Service Task Removed", Toast.LENGTH_SHORT).show();
startService(new Intent(getApplicationContext(), LocationService.class));
super.onTaskRemoved(rootIntent);
}
}
我正在活动类中检查位置权限,并在用户接受权限后启动服务。 这样做没有问题,我什至可以从后台服务获取位置更新。 同时,当我尝试从设置中禁用权限时,应用崩溃。 这是我的MainActivity类,用于检查位置权限。
public class MainActivity extends AppCompatActivity{
@Override
protected void onResume() {
super.onResume();
checkAndEnableGps();
}
private void checkAndEnableGps() {
try {
new RxPermissions(this)
.request(Manifest.permission.ACCESS_FINE_LOCATION)
.subscribe(granted -> {
if (granted) {
if (!Utils.isServiceRunning(this, LocationService.class)) {
startService(new Intent(this, LocationService.class));
}
showSettingDialog();
}
});
}catch (Exception e){
e.printStackTrace();
}
}
}
您收到有关用户拒绝的位置访问权限的错误,并且需要检查使用checkSelfPermission(context,Permission)方法授予的权限,这将返回权限授予状态,然后您可以请求用户进行权限访问。
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
// Show rationale and request permission.
}
然后,从您请求权限的上下文中使用“ onRequestPermissionsResult”回调,如果授予了权限,则启动位置服务。
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == MY_LOCATION_REQUEST_CODE) {
if (permissions.length == 1 &&
permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
// Permission was denied. Display an error message.
}
}
请参阅https://developers.google.com/maps/documentation/android-api/location以获取文档。
您必须添加6 checkpermission
以上的Checkpermission,例如棉花糖,如下所示,
public void checkPermission()
{
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},
123);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
checkPermission();
}
希望能帮助到你!
它需要这些权限,将其删除,因此当它尝试获取位置时会崩溃。
使用catch语句来处理异常,或者检查您是否具有权限,并在实际尝试获取位置之前先请求运行时
在运行服务之前,只需检查您是否有权限。
mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED;
如果没有权限,则可以从Fragment
或Activity
进行请求。
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION }, 200 /*request code*/);
您可以在Fragment
或Activity
类中获得用户响应,即PERMISSION_GRANTED 。
@Override
public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
switch(permsRequestCode){
case 200: // notice the request code is the same as requested.
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startService();
}
else {
// don't start service.
}
break;
}
}
发生这种情况是因为自API版本6.0起,您需要在运行时检查权限。 并且,如果未授予权限,则您的应用应在执行与权限相关的任务之前要求授予权限。
在这里,访问用户位置所需的权限是ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
。 因此,您需要检查是否授予用户授予的位置权限。
还有一件事,您正在位置服务类中。 这是一个问题-
您不能要求用户获得服务许可
但您可以通过调用checkSelfPermission()
检查
为了使其更加美观,您应该在Activity / Fragment类中检查并请求权限,然后手动启动Service。
另一方面,您可以检查服务中的权限,如果未被用户接受,则显示通知,授予权限,然后启动服务。
您已在活动中检查权限:
因此,现在使用checkSelfPermission()来检查用户是否授予了权限。 如果没有,则显示带有PendingIntent的Notification并添加一些标志。 打开活动请求许可,然后通过以下方式启动服务:
startService(new Intent(YourActivity.this, YourService.class));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.