如果设备运行在5.1或者以下的设备,或者targetSdkVersion在22或以下,系统会在安装app的时候让用户授权权限。再说一遍,系统只会提示用户app需要的权限组,而不会提示某一个特定的权限。
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M //6.0及以上
//current activity
int checkPermission = ContextCompat
.checkSelfPermission(activity,Manifest.permission.WRITE_CALENDAR);
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
//判断是否需要 向用户解释,为什么要申请该权限
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// 是否需要弹出一个解释申请该权限的提示给用户,如果为true,则可以弹
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
REQUEST_PERMISSIONS_READ_CONTACTS_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_PERMISSIONS_READ_CONTACTS_CODE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 授权成功
...
} else {
// 权限拒绝
...
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent,1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (!Settings.canDrawOverlays(this)) {
// SYSTEM_ALERT_WINDOW permission not granted...
Toast.makeText(this,"not granted",Toast.LENGTH_SHORT);
}
}
}
if(!Settings.System.canWrite(this)){
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (Settings.System.canWrite(this)) {
//检查返回结果
Toast.makeText(MainActivity.this, "WRITE_SETTINGS permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "WRITE_SETTINGS permission not granted", Toast.LENGTH_SHORT).show();
}
}
}
为了执行自定义权限,你必须在你的manifest中声明一个或多个标签。
比如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.myapp" >
<permission android:name="com.app.myapp.permission.DEADLY_ACTIVITY"
android:label="@string/permlab_deadlyActivity"
android:description="@string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="dangerous" />
...
</manifest>
<protectionLevel>
属性是必须的,告诉系统当app申请该权限的时候,要怎样通知用户。
<permissionGroup>
属性是可选的,可以帮助系统显示自定义属性属于哪个权限组,当通知用户弹出框的时候,当然你可以选择某一个自定义权限属于已知的权限组,也可以属于某一个自定义权限组,建议属于已知的权限组。
<android:label>
相当于权限组的提示,要简短
<android:description>
是某一个特定权限的描述,规则是两句话,第一句描述,第二句警告用户如果授权会发生什么后果。
比如,CALL_PHONE权限
<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the application to call
phone numbers without your intervention. Malicious applications may
cause unexpected calls on your phone bill. Note that this does not
allow the application to call emergency numbers.
</string>
即:
1. 如果在targetSdkVersion<23时,调用了处理权限的代码。在Android M运行targetSdkVersion < 23的应用时,调用checkSelfPermission,不管用户是否取消授权,checkSelfPermission的返回值始终为PERMISSION_GRANTED的解决办法
public boolean selfPermissionGranted(String permission) {
// For Android < Android M, self permissions are always granted.
boolean result = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (targetSdkVersion >= Build.VERSION_CODES.M) {
// targetSdkVersion >= Android M, we can
// use Context#checkSelfPermission
result = context.checkSelfPermission(permission)
== PackageManager.PERMISSION_GRANTED;
} else {
// targetSdkVersion < Android M, we have to use PermissionChecker
result = PermissionChecker.checkSelfPermission(context, permission)
== PermissionChecker.PERMISSION_GRANTED;
}
}
return result;
}