【问题标题】:Application crashes if user remove Application permission from setting如果用户从设置中删除应用程序权限,应用程序崩溃
【发布时间】:2017-06-23 00:03:57
【问题描述】:

如果用户授予权限,则会创建一个后台服务来开始跟踪用户位置。

后台服务会持续跟踪用户的位置,即使在用户销毁应用程序后也是如此。

但是如果用户去应用程序设置并删除位置权限然后服务崩溃并给出以下错误消息,

java.lang.SecurityException: 客户端必须有 ACCESS_COARSE_LOCATION 或 ACCESS_FINE_LOCATION 权限来执行任何位置操作。

该服务每 10 秒运行一次,请指导我如何在运行服务中检查它是否具有权限,因为它每 10 秒运行一次服务并调用 onLocationChanged 方法。

public class UpdateService extends Service implements
        LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {


     @Override
    public void onCreate() {
        super.onCreate();

        if (isGooglePlayServicesAvailable()) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();

            mGoogleApiClient.connect();
        }
    }



    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: ");
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(10000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        super.onStartCommand(intent, flags, startId);
        return START_STICKY ;
    }                        


 @Override
    public void onLocationChanged(Location location) {

    saveLocationand(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));

}         

编辑:

这就是我在应用程序启动中检查权限的方式

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
                android.Manifest.permission.ACCESS_FINE_LOCATION);
        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
            if (!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                showGPSDisabledAlertToUser();
            }
            startService(new Intent(MainActivity.this, UpdateService.class));
        } else
            checkLocationPermission();
    }       

【问题讨论】:

  • 很明显,如果您使用remove location permission,那么应用程序将无法运行。

标签: android android-layout android-fragments android-service android-permissions


【解决方案1】:

使用谷歌设置的api查看位置权限是否开启。

Settings API docmentation

您还可以使用以下代码检查应用是否具有必要的权限。

String permission = "**permission**";
int res = getContext().checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED); 

【讨论】:

  • 谢谢,但是我如何在运行服务中检查它
  • 每当应用程序启动时,您都需要检查这一点。查看 SettingsApi 的文档。
  • 服务在用户启动应用程序之前就已经崩溃了。假设用户第一次安装应用程序并授予位置权限,启动后台服务,用户关闭应用程序并转到设置并删除此应用程序的位置权限。后台服务会立即崩溃。
  • GoogleApiclient 字段为您提供 onConnectionFailed 方法,该方法在 api 客户端无法连接时为您提供错误代码。使用它可以使您的应用程序故障安全。甚至您可以将 try catch 放入请求位置更新中。
【解决方案2】:

这是因为Location 权限被标记为Dangerous 权限,因此它需要运行时权限。

您可以在此处查看我的回答,了解如何检查是否启用了位置权限,然后继续。

What is the difference between shouldShowRequestPermissionRationale and requestPermissions?

阅读更多

https://developer.android.com/training/permissions/requesting.html

这是我在项目中使用的代码:

private void startLocationUpdates() {

    if (!(mHasLocationPermission && mHasLocationSettings)) {
        return;
    }
    try {
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient,
                mLocationRequest,
                this
        );
    } catch (SecurityException e) {
        e.printStackTrace();
    }
}

您可以检查您是否仍然启用了这些权限和位置设置。

【讨论】:

  • 谢谢你的回答,我明白你的意思了。但是我如何在运行服务中检查这一点。该服务正在运行,每 10 秒获取一次用户位置,在用户删除位置权限之间,它不知道它,再次点击 onLocationUpdate() 方法,它崩溃了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-02
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多