Android 6.0之前的系统用户在安装apk文件时会根据app声明的权限声称权限列表,用户只有在同意了申请的权限后才可以继续安装应用。这样就存在了很大的安全隐患。因此在android 6.0后的系统中对权限进行了分级。一种是normal permission,一种是 dangerous permission级别权限。
Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,又新增了运行时权限动态检测(就是对dangerous permission级别权限进行动态权限监测),以下权限都需要在运行时判断:
身体传感器
日历
摄像头
通讯录
地理位置
麦克风
电话
短信
存储空间
使用google的EasyPermissions
依赖
compile 'pub.devrel:easypermissions:1.0.0'
应用
package com.fate.permission;
import android.Manifest;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;
//让需要申请权限的Activity或者Fragment实现EasyPermissions.PermissionCallbacks接口,重写里面的方法
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks{
//https://github.com/googlesamples/easypermissions
private static final String[] LOCATION_AND_CONTACTS = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS};
private static final int RC_CAMERA_PERM = 10086;
private static final int RC_LOCATION_CONTACTS_PERM = 10010;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cameraTask();
locationAndContactsTask();
}
//重写要申请权限的Activity或者Fragment的onRequestPermissionsResult()方法,在里面调用EasyPermissions.onRequestPermissionsResult(),实现回调。
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// EasyPermissions handles the request result.
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
//当权限被成功申请的时候执行回调,requestCode是代表你权限请求的识别码,list里面装着申请的权限的名字
@Override
public void onPermissionsGranted(int requestCode, List perms) {
switch (requestCode) {
case RC_CAMERA_PERM:
Log.i("fate","RC_CAMERA_PERM size"+perms.size() +perms);
break;
case RC_LOCATION_CONTACTS_PERM:
Log.i("fate","RC_LOCATION_CONTACTS_PERM size" +perms.size() +perms);
break;
}
}
/*
当权限申请失败的时候执行的回调,参数意义同上。
在这个方法里面,官方还建议用EasyPermissions.somePermissionPermanentlyDenied(this, perms)方法来判断是否有权限被勾选了不再询问并拒绝,
还提供了一个AppSettingsDialog来给我们使用,在这个对话框里面解释了APP需要这个权限的原因,用户按下是的话会跳到APP的设置界面,可以去设置权限
*/
@Override
public void onPermissionsDenied(int requestCode, List perms) {
Log.d("fate", "onPermissionsDenied:" + requestCode + ":" + perms.size());
// (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN."
// This will display a dialog directing them to enable the permission in app settings.
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this).build().show();
}
}
private boolean hasCameraPermission() {
return EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA);
}
//EasyPermissions.hasPermissions(Context context, @NonNull String… perms)方法来检测一个或者多个权限是否被允许(当有一个权限被拒绝就会返回false)
private boolean hasLocationAndContactsPermissions() {
return EasyPermissions.hasPermissions(this, LOCATION_AND_CONTACTS);
}
@AfterPermissionGranted(RC_CAMERA_PERM)
public void cameraTask() {
if (hasCameraPermission()) {
// Have permission, do the thing!
Toast.makeText(this, "TODO: Camera things", Toast.LENGTH_LONG).show();
} else {
// Ask for one permission
EasyPermissions.requestPermissions(this, "要允许APK拍摄照片和录制视频吗?", RC_CAMERA_PERM, Manifest.permission.CAMERA);
}
}
@AfterPermissionGranted(RC_LOCATION_CONTACTS_PERM)
public void locationAndContactsTask() {
if (hasLocationAndContactsPermissions()) {
// Have permissions, do the thing!
Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show();
} else {
// Ask for both permissions
EasyPermissions.requestPermissions(this, "要允许APK通过网络或者卫星对您的手机定位吗和读取联系人吗?", RC_LOCATION_CONTACTS_PERM, LOCATION_AND_CONTACTS);
}
}
}
http://blog.csdn.net/cike110120/article/details/51678215