谷歌在2015的I/O大会上正式发布了代号为Marshmallow的 Android 6.0系统,6.0对我们开发者影响最大的改变应该够就是运行时权限了,这要求我们开发者要对针对6.0以上的系统做更多的适配工作了。
在6.0中权限分为了2中类别的权限,一类是普通权限,和之前申请权限的方式一样我们只要在Manifest文件中申请就可以了,还有一类就是危险权限了,这类权限我们不只是要在Manifest文件中申请,还要在运行时动态的向用户申请。这些危险权限共有9组,每组中只要有一个权限申请成功了就默认整组的权限都可以使用了。
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
那么适配6.0的的运行时权限需要一下步骤:
1.将targetSDKVersion设置为23以上则需要进行动态的权限申请,如果设置为23以下则不需要进行动态申请
2.在AndroidManifest.xml文件中申请你需要的权限,包括普通权限和需要动态申请的特殊权限
3.开始申请权限,首先是检查是否已经拥有所需要的权限,如果有则直接做接下来的操作,否则就要动态申请了。
正式开始之前先介绍一下运行时权限相关的一些接口
1.ContextCompat.checkSelfPermission(Context context,String permission):检查是否拥有某权限。该方法的返回值为
PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED,如果是PackageManager.PERMISSION_DENIED
则表示未被授予该权限,这样的话就需要进行权限申请了。
2.ActivityCompat.requestPermissions(Activity activity,String[] permissions,int requestCode):申请权限。
该方法是异步的,从方法的第二个参数可以看出是支持一次多个权限的申请的。
3.ActivityCompat.shouldShowRequestPermissionRationale(Context context,String permission):这个接口则是向用户解释为什么需要该权限。
4.权限申请回调:
@Override
public void onRequestermissionsResult(int requestCode,String[] permissions,int[] grantResults):从@Override可以看出这个是需要我们重写的
第三个参数是权限申请结果,如果同时申请了2个权限则grantResults的长度就是2。
下面我们来举个栗子,简单的处理一下打电话权限:
首先定义了一个BaseActivity基类继承自AppCompatActivity
public class BaseActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* 为子类提供权限检查方法
* @param permissions
* @return
*/
public boolean hasPermission(String... permissions){
for (String permission:permissions){
if(ContextCompat.checkSelfPermission(this,permission)!= PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
/**
* 为子类提供权限请求方法
* @param requestCode
* @param permissions
*/
public void requestPermissions(int requestCode,String... permissions){
ActivityCompat.requestPermissions(this,permissions,requestCode);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case Const.REQUEST_CODE_CALL:
if(PackageManager.PERMISSION_GRANTED==grantResults[0]){
doCall();
}else{
Toast.makeText(this,"需要此权限才能拨打电话",Toast.LENGTH_SHORT).show();
}
break;
}
}
/**
* 默认打电话处理
*/
public void doCall(){}
}
接下来我们在需要处理打电话权限的activity中继承刚才的BaseActivity,在BaseActivity中我们已经完成了权限检查申请和回调的处理,
所以我们只要调用和重写相应的方法即可。
public class MainActivity extends BaseActivity implements View.OnClickListener{
private Button btCall;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
/**
* 初始化views
*/
private void initViews(){
btCall= (Button) findViewById(R.id.bt_call);
btCall.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.bt_call:
callPhone();
break;
}
}
/**
*重写父类打电话方法,实现具体操作
*/
@Override
public void doCall() {
Intent intent=new Intent(Intent.ACTION_CALL);
Uri data=Uri.parse("tel:10086");
intent.setData(data);
startActivity(intent);
}
/**
*点击拨打电话按钮时的的权限检查和后续操作
*/
public void callPhone() {
if(Build.VERSION.SDK_INT>=23) {
if (hasPermission(Manifest.permission.CALL_PHONE)) {
doCall();
} else {
requestPermissions(Const.REQUEST_CODE_CALL, Manifest.permission.CALL_PHONE);
}
}
}
}
在该Activity中我们定义了一个打电话按钮,点击该按钮我们会调用callPhone()方法来检查权限和进行后续的操作。
我们点击打电话按钮会弹出如下对话框:
如果点击允许则系统授权了我们打电话的权限,如果点击了拒绝则拒绝了该权限,无论点击了哪个我们都可以处理后续的操作了。
好了,就说这么多了。
源码地址:http://download.youkuaiyun.com/detail/u011282703/9642675