android6.0动态权限申请

Posted 刘永祥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android6.0动态权限申请相关的知识,希望对你有一定的参考价值。

已经有一年多没有写博客了,主要就是忙。自己独立开发的确有点累,很多东西都要自己去脑补,遇到问题也没有可商量的同事,所以只能自己想办法解决。闲话少说,言归正传!
6.0动态权限的申请已经有很长时间了,网上也有很多案例,应某些人要求,这里我只是提供下我自己的见解!
之所以会有动态权限的申请,还是因为android手机做的越来越安全了,也越来越人性化了,同时对开发者来说是越来越麻烦了。有些涉及到用户的隐私的权限,是用户不想让其它应用获取到的(如:定位、联系人、读写文件…)。所以android就把这些关于个人隐私的权限交由用户自己来决定,涉及到的动态权限主要有(下图是从别处复制过来的)

以上权限如果只是在配置清单里面配置是获取不到任何权限的,那么这些权限是如何申请的呢?

/**
 * 发起权限请求
 *
 * @param context
 * @param permissions
 * @param callback
 */
public void requestPermissions(final Context context, final String[] permissions,
                               RequestPermissionCallBack callback) 
    this.mRequestPermissionCallBack = callback;
    List<String> permissionNames = PermissionUtils.transformText(this, Arrays.asList(permissions));
    StringBuilder permissionName = new StringBuilder();
    for (String s : permissionNames) 
        permissionName = permissionName.append(s + "\\r\\n");
    
    //如果所有权限都已授权,则直接返回授权成功,只要有一项未授权,则发起权限请求
    boolean isAllGranted = true;
    for (String permission : permissions) 
        if (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_DENIED) 
            isAllGranted = false;

            if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, permission)) 
                new AlertDialog.Builder(context)
                        .setMessage("您好,此操作需要如下权限:\\r\\n" +
                                permissionName +
                                " 请允许,否则此操作讲无法进行。")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() 
                            @Override
                            public void onClick(DialogInterface dialog, int which) 
                                ActivityCompat.requestPermissions(((Activity) context), permissions, mRequestCode);
                            
                        ).show();
             else 
                ActivityCompat.requestPermissions(((Activity) context), permissions, mRequestCode);
            

            break;
        
    
    if (isAllGranted) 
        mRequestPermissionCallBack.granted();
        return;
    

在应用被打开需要申请权限,弹出权限申请提示框,被用户不小心点成拒绝或不想给予权限,也就是说我们的权限申请被拒绝了,又该如何操作呢?其实我们申请权限的时候是有一个回调的,告诉我们申请权限的结果

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    boolean hasAllGranted = true;
    List<String> permissionNames = PermissionUtils.transformText(MyBaseAty.this, Arrays.asList(permissions));
    StringBuilder permissionName = new StringBuilder();
    for (String s : permissionNames) 
        permissionName = permissionName.append(s + "\\r\\n");
    
    switch (requestCode) 
        case mRequestCode: 
            for (int i = 0; i < grantResults.length; ++i) 
                if (grantResults[i] == PackageManager.PERMISSION_DENIED) 
                    hasAllGranted = false;
                    //在用户已经拒绝授权的情况下,如果shouldShowRequestPermissionRationale返回false则
                    // 可以推断出用户选择了“不在提示”选项,在这种情况下需要引导用户至设置页手动授权
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) 
                        new AlertDialog.Builder(this)
                                .setMessage("您好!由于您选择了不再提示这项操作,导致获取权限失败\\r\\n" +
                                        "获取相关权限如下:\\r\\n" +
                                        permissionName +
                                        "请前往设置页面手动授权")
                                .setPositiveButton("去授权", new DialogInterface.OnClickListener() 
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) 
                                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                        Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
                                        intent.setData(uri);
                                        startActivity(intent);
                                    
                                )
                                .setNegativeButton("取消", new DialogInterface.OnClickListener() 
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) 
                                        mRequestPermissionCallBack.denied();
                                    
                                ).setOnCancelListener(new DialogInterface.OnCancelListener() 
                            @Override
                            public void onCancel(DialogInterface dialog) 
                                mRequestPermissionCallBack.denied();
                            
                        ).show();

                     else 
                        //用户拒绝权限请求,但未选中“不再提示”选项
                        mRequestPermissionCallBack.denied();
                    
                    break;
                
            
            if (hasAllGranted) 
                mRequestPermissionCallBack.granted();
            
        
    

关于权限请求接口的回调是自己写的

/**
 * 权限请求结果回调接口
 */
public interface RequestPermissionCallBack 
    /**
     * 同意授权
     */
    void granted();

    /**
     * 取消授权
     */
    void denied();

有了上面这些代买还是不够的,因为我们上面的代码并没有看到有任何权限出现,其实上面的代码只是实现的一个基类而已,就是方便大家使用的时候可以多处调用,下面以申请读写为例来实现具体的权限申请。其实很简单,请看如下代码

public void requestMultiPermission() 
    requestPermissions(this, new String[]
                    Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
            new MainAty.RequestPermissionCallBack() 
                @Override
                public void granted() 
                //获取权限成功的操作
                

                @Override
                public void denied() 
            	 //获取失败的操作
                
            );

别以为是动态权限就不需要在配置清单里面设置用户权限了,请切记!上面说的不要只是在配置清单里面设置就可以了,并不是说不要再配置清单里面设置权限申请的

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

通过上面的代码是不是感觉动态申请权限其实并没有那么复杂?
效果图如下

点击下载源码

以上是关于android6.0动态权限申请的主要内容,如果未能解决你的问题,请参考以下文章

android6.0以上权限动态申请

Android6.0动态权限申请步骤以及需要注意的一些坑

Android6.0以上系统动态获取权限

android6.0动态权限申请

android6.0动态权限申请

android6.0权限管理工具EasyPermissionUtil