Android动态获取Sdcard存储权限

3,980 阅读3分钟

在Android 6以后的版本中引入了动态权限管理的概念,也就是之前的版本我们只需要在AndroidManifest里面把需要的权限列出来即可,但是在Android 6以后的版本中,需要在运行时请求用户批准。本文以申请Sdcard的读写权限为例演示这种方式。

权限申明

在AndroidManif中针对需要使用的权限做出申明,例如添加Sdcard的写权限。假如在Android6.0一下的版本,只需要进行这个操作,app就具有对sdcard写的权限了。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

权限检查

使用ContextCompat.checkSelfPermission()方法可以检查是否具有某项权限,可以检查应用是否具有某项权限,假如具有某项权限则返回PERMISSION_GRANTED,否则返回PERMISSION_DENIED,这时候应用应该向用户请求权限

例如我们可以在MainActivity的onCreate函数中,我们首先就检查是否具有读取Sdcard的权限。

    if (Build.VERSION.SDK_INT >= 23) {
        if (checkPermission()) {

        } else {
            requestPermission();
        }
    }

首先判断当前的系统是否是6.0及以后的版本,然后通过checkPermission的一个函数来检查是否有我们需要的权限。

    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (result == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }

请求权限

当检测到相应的权限没有时,我们需要向用户请求获取相应的权限,也就是调用ContextCompat.requestPermission()。函数原型如下所示,

例如我们实现的requestPermission函数如下,在这里还需要考虑另外一种情况,用户之前选择了拒绝某项权限,并且勾选了不在询问对话框时,我们不应该在弹出请求权限的对话框,而是应该在界面上做出相应的展示为什么需要这个权限(比如没有sdcard权限,某些功能不能用)。shouldShowRequestPermissionRationale这个函数可以来检查是否需要向用户展示请求权限对话框,假如在前面说的这种情况下(用户已经明确拒绝了某项权限,并且表示不再询问),这个函数会返回true。

    private void requestPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(MainActivity.this, "Please grante write storage permission", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
        }
    }

处理权限响应请求

requestPermissions会弹出一个系统对话框来给用户选择,当用户选择了之后,会回调系统的onRequestPermissionsResult方法来给用户来做相应的处理。

其中requestCode和requestPermissions中使用的是一致的,这个是一个自定义的常量,比如在我们的实例中定义PERMISSION_REQUEST_CODE=1,重写的代码函数如下所示。

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.e("DEBUG", "PERMISSION_GRANTED");
                } else {
                    Log.e("DEBUG", "PERMISSION_DENIED");
                }
                break;
        }
    }

这样我们就完成了一个Sdcard权限的申请,当用户在弹出的界面中选择允许,我们就可以正常的操作Sdcard了。

命令行方式授予权限

我们在开发调试时,也可以通过命令行方式显示的给某一个包授予权限,如下所示

adb shell pm grant com.xxx.xxx  android.permission.READ_EXTERNAL_STORAGE

参考

developer.android.com/training/pe… developer.android.com/guide/topic… developer.android.com/reference/a…