【问题标题】:请求用户权限时避免“检测到屏幕覆盖”错误
【发布时间】:2017-02-03 16:49:13
【问题描述】:

我正在开发一个 GoogleMap 应用程序,因此需要用户的位置。当使用以下代码询问时:

if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
   // all good, do my thing.
}else{
   ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, this.MY_PERMISSIONS_REQUEST_ACCESS_LOCATION);
   return false;
}

它会提示用户拒绝或允许它。当用户允许该权限时,会出现“检测到屏幕覆盖”错误。

我相信会发生这种情况,因为较新的 androids 不允许您在打开应用程序时更改应用程序的权限,因此您需要在设置->应用程序中关闭它以允许权限。

我的问题是,您将如何对应用程序进行编程以请求用户许可,而不会遇到屏幕覆盖问题,从而使用户体验变得糟糕。

问题是一旦提示用户拒绝/允许位置权限,然后在按下 ALLOW 后屏幕覆盖消息立即出现。

这是处理位置的代码:

public boolean requestCurrentLocation(float zoomLevel){
    if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        mZoomLevel = zoomLevel;

        // Check if gps is enabled
        LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
        boolean gpsEnabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if(!gpsEnabled){
            Log.d("GPS_TAG", "Gps not enabled");
            showToastMessageShort(getResources().getString(R.string.cannot_get_location));
            Intent gpsOptionsIntent = new Intent(
                    Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(gpsOptionsIntent);
            return false;
        }
        try{
            Log.d("GPS_TAG", "Calling FusedLocationApi request location updates");
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }catch(IllegalStateException ie){
            Log.d("GPS_TAG", "Error requesting FusedLocationApi locationUpdates: " + ie);
            return false;
        }
    }else{
        Log.d("GPS_TAG", "Location access not granted, asking for grant");
        showToastMessageShort(getResources().getString(R.string.cannot_get_location));
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, this.MY_PERMISSIONS_REQUEST_ACCESS_LOCATION);
        return false;
    }
    return true;
}

我还添加了 onRequestPermissionResult() 方法:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_ACCESS_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.
                requestCurrentLocation(ZOOM_LEVEL_BUILDING);
            } else {
                Log.e("GPS_", "Cannot get gps location data, permission not granted!");
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}

【问题讨论】:

  • 如果可以的话,贴出与当前屏幕相关的整个代码,加上权限模型相同,不要混淆自己
  • 较新的Android版本需要在运行时请求权限,所以应该在应用打开的情况下更改权限。您需要捕获权限结果(使用onRequestPermissionsResult)并尝试再次执行您的操作。
  • Overlay 消息不一定是错误,如果您已经对权限请求给出“否”回答,出于安全考虑,Android M 会要求您更改设置中的权限,但有时会有点错误,SO 中有一个帖子解释问题并提出解决方案。

标签: android android-permissions


【解决方案1】:

你会讨厌这个的。
问题是您对“showToastMessageShort(...)”的调用。
如果您在权限请求待处理时发送消息,您将看到您的体验。
要解决此问题,请不要在请求权限的代码路径中吐司。

是的,这是废话。

欲了解更多信息:Screen overlay detected blocks Android permissions

【讨论】:

  • 天才的答案,我永远不会独自思考
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-23
  • 2016-05-28
  • 2017-03-13
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 2016-09-18
相关资源
最近更新 更多