android6.0以后权限的申请改成了动态申请,如果你的targetSdkVersion 大于23且手机系统是6.0以上的就会变成动态申请.为了项目的需求我自己整理了一套权限申请的方法.先上几张图片.
1.这是我第一次运行项目弹出权限请求的界面,我都选择了不允许,然后会通过Snackbar友好的提醒用户需要允许权限
2.当我第二次在点击拍照时,就会先弹出一个Snackbar告诉用户,我需要一些权限,这次我还是决绝而且还点击了不再提醒.这样用户下次在点击拍照时就无法弹出申请权限的界面了,这里我就通过Snackbar提醒用户是否要去设置界面开启权限
3.这是我选择了不再询问以后再次点击拍照的时候,这时就会直接弹出Snackbar提醒用户是否要去设置界面开启权限
通过上面的图片效果,应该可以看出这套权限请求的过程了,下面我就贴一下代码.
1.我把权限请求封装到了一个工具类中,代码如下
`public class PermissionUtil {
/**
* 检测权限
* @param activity
* @param view //随便一个view 来用显示snackbar
* @param permissions //请求的权限组
* @param requestCode //请求码
*/
public static void checkPermission(final Activity activity,View view, final String[] permissions, final int requestCode,permissionInterface permissionInterface) {
//小于23 就什么都不做
if (Build.VERSION.SDK_INT < 23) {
return;
}
List<String> deniedPermissions = findDeniedPermissions(activity, permissions);
if (deniedPermissions!=null&&deniedPermissions.size()>0) {
//大于0,表示有权限没申请
PermissionUtil.requestContactsPermissions(activity, view, deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
} else {
//拥有权限
permissionInterface.success();
}
}
/**
* 请求权限
*/
public static void requestContactsPermissions(final Activity activity,View view, final String[] permissions, final int requestCode) {
//默认是false,但是只要请求过一次权限就会为true,除非点了不再询问才会重新变为false
if (shouldShowPermissions(activity,permissions)) {
Snackbar.make(view, "需要一些权限",
Snackbar.LENGTH_INDEFINITE)
.setAction("确定", new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat
.requestPermissions(activity, permissions,
requestCode);
}
})
.show();
} else {
// 无需向用户界面提示,直接请求权限,如果用户点了不再询问,即使调用请求权限也不会出现请求权限的对话框
ActivityCompat.requestPermissions(activity,
permissions,
requestCode);
}
}
/**
* 判断请求权限是否成功
* @param grantResults
* @return
*/
public static boolean verifyPermissions(int[] grantResults) {
// At least one result must be checked.
if(grantResults.length < 1){
return false;
}
// Verify that each required permission has been granted, otherwise return false.
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
//回调接口
public interface permissionInterface{
void success();
}
/**
* 找到没有授权的权限
* @param activity
* @param permission
* @return
*/
public static List<String> findDeniedPermissions(Activity activity, String... permission)
{
//存储没有授权的权限
List<String> denyPermissions = new ArrayList<>();
for (String value : permission)
{
if (ContextCompat.checkSelfPermission(activity,value) != PackageManager.PERMISSION_GRANTED)
{
//没有权限 就添加
denyPermissions.add(value);
}
}
return denyPermissions;
}
/**
* 检测这些权限中是否有 没有授权需要提示的
* @param activity
* @param permission
* @return
*/
public static boolean shouldShowPermissions(Activity activity, String... permission)
{
for (String value : permission)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
value))
{
return true;
}
}
return false;
}
}`
2.下面在贴一下使用的代码
在需要权限请求的地方调用如下方法就可以开启权限请求
/**
* 请求拍照的权限
* 第二个参数表示一个view ,可以随便传入一个
* 第三个表示 请求的权限数组
* 第4个是请求码
* 第5个是回调接口
*/
private void requestPermiss() {
PermissionUtil.checkPermission(getmActivity(), linearAddbankcard2Bankcard, REQUEST_PERMISSIONS, REQUEST_PERMISSION_CODE_TAKE_PIC, new PermissionUtil.permissionInterface() {
@Override
public void success() {
UtilMethod.paizhao(getmActivity(), Constants.PHOTOHRAPH);
}
});
}
但是还得需要重写下面的方法来判断权限是否开启成功,并且做相应的处理
/**
* 检测权限的回调
*
* @param requestCode
* @param permissions
* @param grantResults
*/
public void onRequestPermissionsResult(int requestCode, final String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_PERMISSION_CODE_TAKE_PIC) {
if (PermissionUtil.verifyPermissions(grantResults)) {//有权限
ImageTools.paizhao(getmActivity(), Constants.PHOTOHRAPH);
} else {
//没有权限
if (!PermissionUtil.shouldShowPermissions(this,permissions)) {//这个返回false 表示勾选了不再提示
showSnackBar(linearAddbankcard2Bankcard, "请去设置界面设置权限","去设置");
} else {
//表示没有权限 ,但是没勾选不再提示
showSnackBar(linearAddbankcard2Bankcard, "请允许权限请求!");
}
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
重写下面的方法为了判断, 用户去设置界面是否开启了权限
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//如果是从设置界面返回,就继续判断权限
if (requestCode == REQUEST_PERMISSION_SEETING) {
requestPermiss();
}
}
3.这时去设置界面的代码
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SEETING);
4.最后提点小建议,最好在申请权限的代码用try catch 住,防止有些厂家修改了系统出现未知的BUG,为了方便使用,我封装了一个请求权限的库,使用非常简单, 一行调用代码即可