Android 6.0在运行时申请权限解释与实例

Android 6.0在运行时申请权限

从android 6.0(API23)开始,当app运行时用户授予用户的权限,而不是在安装程序的时候。

系统权限分为2种,分别为normal和dangerous.

  • Normal permission:对于用户隐私没有危险的,在清单文件中申请就可以直接授权。

  • Dangerous permission:app需要访问用户的隐私信息等,即使在清单文件注册,也需要在运行是通过用户授权。

检查权限(check permission)

在android6.0及以上的sdk提供了一个检查权限的方法:ContextCompat.checkSelfPermission()。

eg:

int permission = ContextCompat.checkSelfPermission(MainActivity.this,
        Manifest.permission.RECORD_AUDIO);

if (permission == PackageManager.PERMISSION_GRANTED) {
    //表示已经授权
}
//PackageManager.PERMISSION_DENIED--->表示权限被否认了

如果在Activity中申请权限可以的调用:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    int permission  = checkSelfPermission(Manifest.permission.RECORD_AUDIO);
}

请求权限

在Android 6.0及以上,如果检查没有权限,需要主动请求权限。在请求权限是会弹出一个对话框提示用户,是否授权。
请求权限的方法:requestPermissions()。在请求权限后会有一个回调方法onRequestPermissionsResult()。

ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);

//或者 在Activity的方法调用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO},1);
}

/**
 * 参数1:requestCode-->是requestPermissions()方法传递过来的请求码。
 * 参数2:permissions-->是requestPermissions()方法传递过来的需要申请权限
 * 参数3:grantResults-->是申请权限后,系统返回的结果,PackageManager.PERMISSION_GRANTED表示授权成功,PackageManager.PERMISSION_DENIED表示授权失败。
 * grantResults和permissions是一一对应的
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

解释为什么应用程序需要权限

在某些情况下,你希望用户能理解你的app为什么需要这样一个权限。例如:用户打开一个摄影的app,用户不会惊讶于camera权限,但不理解location权限或联系人权限。所以在用户授权之前,需要向用户提供一个解释。

另一种方法是,如果一个用户试图使用需要一个权限的功能,但拒绝了权限请求,当下一次使用到此功能时,给用户一个解释。

对应此场景,android6.0(API23)及以上,提供了一个方法:shouldshowrequestpermissionrationale(),如果应用程序请求此权限,并且用户拒绝了请求,则此方法返回true。

注意:如果用户在过去拒绝了权限请求,对话框中选择了“不再询问”选项,该方法返回false。如果设置中禁止应用程序具有该权限,该方法还将返回false。

boolean flag = ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.RECORD_AUDIO);

//或者 在Activity的方法调用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    boolean flag = shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO);
}

案例:

public class MainActivity extends AppCompatActivity {

    private boolean granted;
    private Button record;

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

        initPermission();

        initView();

        initListener();
    }

    private void initView() {
        record = (Button) findViewById(R.id.btn_record);
    }

    private void initListener() {
        record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (granted) {
                    record();
                } else {
                    Toast.makeText(MainActivity.this, "你还没有获取录音权限", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private void record() {
        //录音代码
        MediaRecorder recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setOutputFile(getCacheDir().getPath() + "1.mp3");
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        try {
            recorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        recorder.start();
    }

    private void initPermission() {
        int permission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            //需不需要解释的dialog
            if (shouldRequest()) return;
            //请求权限
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
        }
    }

    private boolean shouldRequest() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
            //显示一个对话框,给用户解释
            explainDialog();
            return true;
        }
        return false;
    }

    private void explainDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("应用需要获取您的录音权限,是否授权?")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //请求权限
                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
                    }
                }).setNegativeButton("取消", null)
                .create().show();
    }

    /**
     * 请求权限的回调
     *
     * 参数1:requestCode-->是requestPermissions()方法传递过来的请求码。
     * 参数2:permissions-->是requestPermissions()方法传递过来的需要申请权限
     * 参数3:grantResults-->是申请权限后,系统返回的结果,PackageManager.PERMISSION_GRANTED表示授权成功,PackageManager.PERMISSION_DENIED表示授权失败。
     * grantResults和permissions是一一对应的
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1 && grantResults.length > 0) {
            granted = grantResults[0] == PackageManager.PERMISSION_GRANTED;//是否授权,可以根据permission作为标记
        }
    }
}

操作流程:app打开->点击否认->点击录音->返回退出->再次打开app->点击确定->点击允许->点击录音

操作流程:app打开->点击否认->点击录音->返回退出->再次打开app->点击确定->点击否认->点击录音
[注:]当不在询问勾选是,点击否认权限,shouldShowRequestPermissionRationale()返回值为false.

你可能感兴趣的:(android提升)