Android 6.0以后,对用户的权限机制做了很大的修改,新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。
Dangerous Permission:
group:android.permission-group.CONTACTS 联系人
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR 日历
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
使用到上面的Dangerous Permission权限的时候都需要额外在代码中申请,值得注意的是,在同一组权限中,只要某一个权限被授予了,其他权限也默认被授予了。
申请权限流程:
1.检查权限是否被授予
2.如果权限没有被授予,则开始申请权限
//先检查是否有权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
//申请权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CODE_CALL_PHONE);
} else {
//权限已被授予,可以直接进行一步操作
}
3.申请完权限后回调处理
//申请完权限后回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
doCallPhone();
} else {
//提示用户权限未被授予,退出
}
break;
}
}
基本的流程就三步!
附加(当用户再次拒绝该权限时会调用):
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(this, "Permission Denied,App", Toast.LENGTH_SHORT).show();
}
下面基于慕课网老师的封装
public class BaseActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
}
/**
* 提供一个权限检查方法
* @param permissions
* @return
*/
public boolean hasPermission(String... permissions){
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.M){
return true;
}
for(String permission:permissions){
if(ContextCompat.checkSelfPermission(this,permission)
!= PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
/**
* 为子类提供一个权限请求方法
* @param code
* @param permissions
*/
public void requestPermission(int code,String... permissions){
ActivityCompat.requestPermissions(this,permissions,code);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case Contant.WRITE_EXTERNAL_CODE:
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
doSDCardPermission();
}else {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)){
}
toast();
}
break;
case Contant.CALL_PHONE_CODE:
doCallPhonePermission();
break;
default:
break;
}
}
void toast(){
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
/**
* 默认的打电话权限处理
*/
public void doCallPhonePermission() {
}
/**
* 默认实现SD卡权限处理
*/
public void doSDCardPermission() {
}
}
在类中调用
public class TsetPermissionActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tset_permission);
//当用到SD卡权限时
if(hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)){
doSDCardPermission();
}else {
requestPermission(Contant.WRITE_EXTERNAL_CODE,Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
//当用到打电话权限时
if(hasPermission(Manifest.permission.CALL_PHONE)){
doSDCardPermission();
}else {
requestPermission(Contant.CALL_PHONE_CODE,Manifest.permission.CALL_PHONE);
}
}
//通过子类去实现SD权限逻辑
@Override
public void doSDCardPermission(){
}
//通过子类去实现打电话逻辑
@Override
public void doCallPhonePermission(){
}
}