android6.0棉花糖,app将不会在安装的时候授予权限。取而代之的是,app不得不在运行时一个一个询问用户授予权限。
android {
compileSdkVersion 23
...
defaultConfig {
...
targetSdkVersion 23
...
}
}
如何app/build.gradle是23的话,在6.0上运行一些权限,没有做处理,会直接崩溃:
...
Caused by: java.lang.SecurityException: Permission Denial:
opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord
{c3b3c66 16712:com.wuxiaolong.apksample/u0a62} (pid=16712, uid=10062)
requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
...
如果targetSdkVersion 22,就不会发生这样的错误,下面就来实践下这个6.0运行的权限。
效果预览
按照惯例,先上效果图:
说明:第一次请求授权,是没有“不再询问”,拒绝后,再次请求授权,就会出现“不再询问”。
实践
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
代码调用
在需要使用到权限之前调用以下代码:
private void mayRequestContacts() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
switch (checkSelfPermission(Manifest.permission.READ_CONTACTS)) {
case PackageManager.PERMISSION_GRANTED:
// 已有授权
Log.i("wxl", "已有授权");
break;
case PackageManager.PERMISSION_DENIED:
// 没有权限:尚未请求过权限,
// 或者请求授权被拒绝,
// 或者曾经授权过,但被用户在设置中禁用权限
Log.i("wxl", "没有权限:尚未请求过权限,或者请求授权被拒绝," +
"或者曾经授权过, 但被用户在设置中禁用权限");
/**
* 如果用户勾上了“不再询问”,这时候就不应弹请求权限的对话框,
* 可以在请求权限之前用
* shouldShowRequestPermissionRationale判断用户是否拒绝过,
* 如果返回true,表示用户拒绝过。
*/
Log.i("wxl", "shouldShowRequestPermissionRationale=="
+ shouldShowRequestPermissionRationale(READ_CONTACTS));
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
Snackbar.make(mEmailView,
R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(android.R.string.ok, new View.OnClickListener() {
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{READ_CONTACTS},
REQUEST_READ_CONTACTS);
}
}).show();
} else {
requestPermissions(new String[]{READ_CONTACTS},
REQUEST_READ_CONTACTS);
}
break;
default:
break;
}
}
}
checkSelfPermission:检查权限
requestPermissions:请求权限
shouldShowRequestPermissionRationale:判断用户是否拒绝过
授权回调
不管是允许或拒绝,都会回调:
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,@NonNull int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 授权请求被通过,读取通讯录
Log.i("wxl", "授权请求被通过,读取通讯录");
} else {
Log.i("wxl", "授权请求不被通过");
}
}
}
多个权限
@TargetApi(Build.VERSION_CODES.M)
private void checkPermissions() {
List<String> permissionsNeeded = new ArrayList<>();
final List<String> permissionsList = new ArrayList<>();
if (deniedPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("GPS");
if (deniedPermission(permissionsList, Manifest.permission.READ_CONTACTS))
permissionsNeeded.add("Read Contacts");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), REQUEST_PERMISSIONS);
}
}
}
@TargetApi(Build.VERSION_CODES.M)
private boolean deniedPermission(List<String> permissionsList, String permission) {
if (checkSelfPermission(permission) == PackageManager.PERMISSION_DENIED) {
permissionsList.add(permission);
// true,表示用户拒绝过
if (shouldShowRequestPermissionRationale(permission)) {
return true;
}
}
return false;
}
/**
* Callback received when a permissions request has been completed.
*/
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_PERMISSIONS) {
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
// All Permissions Granted
Log.i("wxl", "授权请求被通过");
} else {
// Permission Denied
Log.i("wxl", "授权请求不被通过");
}
}
}
同一组的任何一个权限被授权了,其他权限也自动被授权。例如,一旦WRITE_CONTACTS被授权了,app也有READ_CONTACTS和GET_ACCOUNTS了。
网友评论