运行时权限不适用于真实设备

Runtime Permissions Not Working on Real Device

我已经在我的应用程序中实现了 RT 位置权限,并在牛轧糖设备上进行了测试。我已经检查了 logcat 但它看起来像 ContextCompat.checkSelfPermission() and ActivityCompat.requestPermission 不执行并且随后 onRequestPermissionRationale 永远不会被调用但是在应用程序的设备设置中,它总是显示为授予权限

我试过在代码中像下面这样记录:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_client_home);

    prefsHelper = new SharedPrefsHelper(this);
    initViews();
    setSupportActionBar(toolbar);

    Log.d(TAG, "BEFORE CHECK");
    checkPerms();

    setUpDrawer();
    prefsHelper.setLoggedOut(false);

    getVehicles();
    handlePlacesInput();

    rideContinueLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (validate() && Utils.isNetwork(ClientHomeActivity.this)) {
                Intent intent = new Intent(ClientHomeActivity.this, BookRideActivity.class);
                intent.putExtra("start_addr", startAddr);
                intent.putExtra("dest_addr", destAddr);
                startActivity(intent);
                clearInputs();
            } else {
                Snackbar.make(findViewById(android.R.id.content), "Enter Start and Drop Locations", Snackbar.LENGTH_LONG).show();
            }
        }
    });

}

private void checkPerms() {
    Log.d(TAG, "DO CHECK");
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        Log.d(TAG, "INSIDE CHECK");
        reqPerms();
    }
}

private void reqPerms() {
    Log.d(TAG, "ASKING");
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, AppConstants.LOC_PERMS_REQ_CODE);
}

@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case AppConstants.LOC_PERMS_REQ_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "GRANTED");
            } else {
                if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
                    Log.d(TAG, "Permission Rationale");
                } else {
                    reqPerms();
                }

            }
            break;
    }
}

日志在 "DO CHECK" tag and other tags after that don't execute 处停止。我正在尝试构建一个基于位置的应用程序。谁能告诉我为什么会这样,是我设备上的错误还是代码中的错误?谢谢

ActivityCompat.requestPermission dont execute and subsequently onRequestPermissionRationale never gets called but in the device settings for the app, it is always showing as permission granted

由于您的应用是旧应用并且您已经授予该应用必要的权限,ActivityCompat.checkSelfPermission 将 return PackageManager.PERMISSION_GRANTED 并且您不会再看到权限请求。

如果您想查看权限请求,请卸载旧应用并安装新应用。另一种方法是仅从设置中禁用权限。

也许您已经授予了权限。

尝试重新安装应用。

试试这个 确保你的 app level gradle 文件在编译 sdk 版本中是最新的。 喜欢

  compileSdkVersion 27

然后在 android 清单文件中添加权限。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

然后像下面这样检查运行时权限后创建两个方法。

/**
 * this method check permission and return current state of permission need.
 */
private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    return permissionState == PackageManager.PERMISSION_GRANTED;
}

/**
 * this method request to permission asked.
 */
private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

    if (shouldProvideRationale) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
    } else {
        Log.i(TAG, "Requesting permission");
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission was granted. Kick off the process of building and connecting
            // GoogleApiClient.
            buildGoogleApiClient();
        } else {
            // Permission denied.

        }
    }
}

然后在调用 get location 方法时像下面这样检查

 // Check if the user revoked runtime permissions.
    if (!checkPermissions()) {
        requestPermissions();
    }

    buildGoogleApiClient();

您的代码记录 "DO CHECK" 而不是 "INSIDE CHECK" 的唯一合乎逻辑的解释是权限已经被授予。

在申请权限之前,如果权限已经被授予,您可以直接进行您需要的操作。

您还可以利用我的库轻松处理运行时权限。 https://github.com/nabinbhandari/Android-Permissions

有两种可能在请求后不显示权限对话框,如下所示。

目标版本
请在您的构建中将您的 targetSdkVersion 设置为大于 23

声明权限清单
请不要错过在清单中声明您需要并在运行时请求的权限,