最近在写直播类应用,需要实现再打开直播前预览界面前首先判断应用是否拥有照相的权限。android自从更新到6.0之后应用的某些敏感权限变成了动态请求权限
(Dangerous permissions),具体需要动态请求的权限有
CALENDAR | READ_CALENDAR, WRITE_CALENDAR |
CAMERA | CAMERA |
CONTACTS | READ_CONTACTS ,WRITE_CONTACTS, GET_ACCOUNTS |
LOCATION | ACCESS_FINE_LOCATION , ACCESS_COARSE_LOCATION |
MICROPHONE | RECORD_AUDIO |
PHONE | READ_PHONE_STATE, CALL_PHONE READ_CALL_LOG , WRITE_CALL_LOG , ADD_VOICEMAIL , USE_SIP, PROCESS_OUTGOING_CALLS |
SENSORS | BODY_SENSORS |
SMS | SEND_SMS RECEIVE_SMS , READ_SMS RECEIVE_WAP_PUSH , RECEIVE_MMS |
STORAGE | READ_EXTERNAL_STORAGE , WRITE_EXTERNAL_STORAGE |
在6.0上可以很简单的判断出当前应用是否拥有这些权限:
在需要使用camera权限前用本方法判断是否已经拥有camera权限,
private void getPermission(){ if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) { //申请WRITE_EXTERNAL_STORAGE权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, WRITE_EXTERNAL_STORAGE_REQUEST_CODE); }else{ Log.e("我已有权限","已有权限"); } }
如果此权限对本应用设置为每次询问时,会弹出一个对话框向用户请求此权限,当用户点击确定或者取消时会回调下面的方法:
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Camera permission has been granted, preview can be displayed Log.e("text", "CAMERA permission has now been granted. Showing preview."); } else { Log.e("text", "CAMERA permission was NOT granted."); } } }
这个回调方法有三个参数:
requestCode:是调用
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
方法时传的请求参数“
WRITE_EXTERNAL_STORAGE_REQUEST_CODE
” 这个参数是自己自定义的,这样就和startactivityForResult一样,需要传一个自己定义的一个参数
permissions:是本次请求的权限,就是requestPermissions方法的第二个参数。
grantResults:返回的是用户的操作;
/** * Permission check result: this is returned by {@link #checkPermission} * if the permission has been granted to the given package. */ public static final int PERMISSION_GRANTED = 0; /** * Permission check result: this is returned by {@link #checkPermission} * if the permission has not been granted to the given package. */ public static final int PERMISSION_DENIED = -1;
由文档可以看出:
1、当返回0时,意思是用户允许本次操作
2、当返回-1时;代表用户拒绝本应用使用此权限;如果用户拒绝往后很多次都是系统都会自动拒绝,所以当grantResults是-1时 需要引导用户去设置里面打开本应用的权限
注:动态请求权限的方法是在6.0之后才有的,所以6.0以下没有这些方法,所以需要将应用的
targetSdkVersion设置成23往后;
在5.0及以下的android系统上并没有动态请求权限的方法,不过我们可以在获得这些权限时,trycatch 如果报错意味着我们没有这些权限,这时候提示用户打开权限也是可以实现判断的目的的。