对于Android用户,将程序安装到Android6.0以下的系统手机时,程序要求用户一次性赋予该程序申请的权限。
为了避免程序强制要求用户一次性授权所有申请的权限,否则不允许安装该程序的情况,Android6.0系统加入了运行时权限的功能,即用户不需要在安装软件是一次性授权所有申请的权限,而是在程序使用过程中再对某一权限申请进行授权。
对于Android用户来说,不停授权也很烦琐,Android目前将所有的权限分为了两类,一类是普通权限,一类是危险权限。 普通权限指那些不会直接威胁到用户安全和隐私的权限,如网络访问等,对于这部分权限的申请,系统会自动帮我们进行授权。危险权限指那些可能触及用户的隐私或者对设备的安全性造成影响的权限,如Sd卡访问等,对于这部分权限的申请,必须由用户手动点击授权。
即对于Android开发者来说,如果targetSdkVersion >= 23, 将程序安装到Android6.0系统,申请危险权限不仅需要在AndroidManifest.xml中声明该权限,还需要在代码进行申请该权限。
Android危险权限
编号 | 权限组 | 权限 |
---|---|---|
0 | CALENDAR | READ_CALENDAR WRITE_CALENDAR |
1 | CAMERA | CAMERA |
2 | CONTACTS | READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTS |
3 | LOCATION | ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION |
4 | MICROPHONE | RECORD_AUDIO |
5 | PHONE | READ_PHONE_STATE CALL_PHONE READ_CALL_LOG WRITE_CALL_LOG ADD_VOICEMAIL USE_SIP PROCESS_OUTGOING_CALLS |
6 | SENSORS | BODY_SENSORS |
7 | SMS | SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEIVE_MMS |
8 | STORAGE | READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE |
即从目前的Android系统版本兼容情况来说,如果是属于这张表中权限,则需要进行运行时权限处理,否则只需要在AndroidManifest.xml中添加权限声明。
在程序运行时申请权限
public class PermissionActivity extends AppCompatActivity {
private Button test;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission);
test = (Button) findViewById(R.id.test);
test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(ContextCompat.checkSelfPermission(PermissionActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(PermissionActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}else{
doSomeWork();
}
}
});
}
private void doSomeWork() {
Toast.makeText(this,"doSomeWork",Toast.LENGTH_SHORT).show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch(requestCode){
case 1:
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
doSomeWork();
}else{
Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();
},
break;
default:
}
}
}
checkSelfPermission()方法判断用户是否以及授权,接受两个参数,第一个是Context,第二个是权限名,再将该方法的返回值与PackManager.PERMISSION_GRANTED做比较,相等则说明用户已授权,不等则说明用户没有授权。
ActivityCompat.requestPermissions()方法申请权限,接受三个参数,第一个是Activity的实例,第二个是String数组,里面包含申请的权限名,第三个是请求码。
调用完requestPermissions()方法后,系统会弹出一个权限申请的对话框,然后用户可以选择同意或者拒绝程序的权限申请,无论哪种结果,最终都会回调到onRequestPermissionsResult()方法中,授权的结果封装在grantResults参数中,可以用来判断授权的结果。