今晚看了一下动态权限的官方文档,做个简单的笔记:
文档地址:https://developer.android.com/training/permissions/requesting
github上自己写的demo地址:https://github.com/MrShareone/AndroidPermission
动态权限的问题应对策略和和API有关:
API < 23 只需在manifest中声明即可
API >=23 需要动态申请
危险权限列表
*权限列表主要需要注意的地方是,当一个权限组中的任一权限被允许时,其它权限也会被默许,需要时不会提示没有权限
一、权限组
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
二、检查权限
public boolean checkPermission(Context context,String permissionid) {
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(context, permissionid);
if(permissionCheck == PackageManager.PERMISSION_GRANTED){
//有当前权限
return true;
}else{
//没有当前权限(permissionCheck == PackageManager.PERMISSION_DENIED)
return false;
}
三、获取权限(还包括判断是否需要做出权限解释)
// 这个地方需要注意,动态获取权限的前提是在manifest中已经声明过
// 如下面的代码想要动态申请read-contacts权限,就必须先要在manifest中添加下面的声明
<uses-permission android:name="android.permission.READ_CONTACTS"/>
public class MainActivity extends AppCompatActivity {
public static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Here, thisActivity is the current activity
//这里,thisActivity表示的是当前所在activity
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
//我们需不需要一个解释??
//当用户不知道为什么需要获取此权限,所以取消给予权限一次后再次请求到此功能时,我们可以执行这个函数。这个函数会返回true,这里我们就可以向用户解释(dailog等等形式的弹窗)为什么需要这个权限
//需要注意的是,如果用户上一次取消给予权限并且选择了不再提醒的话,表明用户很清楚这个权限是为什么要获取,并很清楚的表示不给此应用该权限,那么我们就没必要做出解释(这种情形,这个方法返回的是false)
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//向用户展示出解释,然后再次发出请求
} else {
// No explanation needed, we can request the permission.
//不需要任何解释,直接请求这个权限(这是一个不能被我们重写的对话框)
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
//MY_PERMISSIONS_REQUEST_READ_CONTACTS是自定义的全局变量,用来标识自己发出的权限请求,并在onRequestPermissionsResult中做出相应的回应
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
//用户选择取消获取权限,那么返回结果就是空的
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//权限获取失败,为所欲为吧!
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
//权限获取失败,寸步难行啊!
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
}
break;
default:
break;
// other 'case' lines to check for other
// permissions this app might request
//给其他权限的请求结果作出相应的回应
}
}
}