Android 6.0及运行时权限处理

需求

现在android版本出现到了7.0,今后高版本的android肯定会占据市场的主流,所以在我们的应用中进行运行时处理,也是势在必行的了。


引用郭霖对android运行时权限的总结,一共9组24个权限,只有在android6.0 及以上的android机上使用到这些权限的时候,才需要进行运行时权限处理.

这里写图片描述

使用场景

前提:应用运行到android 6.0 及以上的android机上(低版本的android机不用进行运行时权限处理);


1.项目的targetSdkVersion < 23 , 即应用没有兼容android6.0及以上

此时应用运行到android6.0 及以上的android机上是不需要进行运行时权限处理的。系统会按照默认的权限加载方式加载。


2.targetSdkVersion >=23,但是是从小于23的版本升级上来的

及应用以前不兼容android6.0及以上版本,但是现在升级后兼容了android6.0及以上版本。

实际场景:手机之前安装了低版本(不兼容android6.0)的应用,不卸载直接升级新版本(兼容了android6.0)的。这种情况
android会默认将应用申请的权限全部授权

但是,如果你是先卸载之前低版本的应用,再安装高版本的应用,那就需要进行运行时权限处理了。


3.targetSdkVersion >=23,应用兼容android6.0及以上

此时就需要进行运行时权限处理了,需要提一下,即使是在代码中处理的运行时权限,也是需要在manifest中注册的

郭霖CSDN运行时权限公开课地址:http://edu.csdn.net/course/detail/3539

郭霖运行时权限微信推荐文章:http://chuansong.me/n/1017834351332

下面我将郭霖公开课的代码截屏如下:

原生方式实现

基本用法,申请单个权限

这里写图片描述
这里写图片描述

  • 高级用法,申请一组权限

这里写图片描述
这里写图片描述

封装框架

郭神提供了三种实现思路

1.新建一个PermissionActivity,设置成透明的,所有的权限操作都在这个activity中进行,授权后在finish掉,回到原来的activity。

2.参考第三方开源运行时权限处理框架RxPermission

github地址:注意它是要结合RxJava一起使用的,但是RxJava有RxJava1和RxJava2两个库
所以RxPermission也有对应的两个库

RxPermission1:https://github.com/tbruyelle/RxPermissions

RxPermission2https://github.com/sirencode/RxPermissions2

这种的处理方法是,新建一个RxPermissionFragment 去集成 Fragment,因为Fragment里面也有运行时权限处理的方法,就是上面讲到的原生实现中涉及到的方法,并且这个RxPermissionFragment 利用了Fragment的特性,它是没有界面没有大小的,只用来处理运行时权限。

3.利用BaseActivity自己封装运行时权限

  • android源码中用0和-1来表示授权是否成功,0表示获取授权成功,-1表示获取授权失败。

    • PackageManager.PERMISSION_GRANTED = 0 ;

    • PackageManager.PERMISSION_DENIED= -1 ;


封装实战

实现思路

代码很简单,重点是学习这种封装的思路

  • 1.项目中所有的Activity都继承BaseActivity
    为了项目的可扩展性,一般的项目都是这样的。如果你的项目不是这样写的,自己赶紧改过来吧。

  • 2.将运行时权限检测写到BaseActivity中

  • 3.提供授权成功和授权失败的回调接口

  • 4.为了能够在非Activity中使用,使用Activity管理器提供栈顶Activity


实现代码

说一句,郭神在视频中说,不提供源码,是因为编程是个需要动手的过程,只看和复制别人的代码是很难提高的

  • 1.BaseActivity,运行时权限处理
public class BaseActivity extends AppCompatActivity {
    private static final String TAG = "BaseActivity";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }

    private static PermissionListener mListener;

    /**
     * 请求运行时权限
     *
     * @param permissions
     * @param listener
     */
    public static void requestRuntimePermission(String[] permissions, PermissionListener listener) {
        try {
            Activity topActivity = ActivityCollector.getTopActivity();
            if (topActivity == null) {
                return;
            }
            mListener = listener;
            List<String> permissionList = new ArrayList<>();
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(topActivity, permission) != PackageManager.PERMISSION_GRANTED) {
                    permissionList.add(permission);
                }
            }

            if (!permissionList.isEmpty()) {
                ActivityCompat.requestPermissions(topActivity, permissionList.toArray(new String[permissionList.size()]), 1);
            } else {
                //授权成功
                mListener.onGranted();
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "requestRuntimePermission: "+e.getMessage());
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 1:
                //有权限被拒绝
                if (grantResults.length > 0) {
                    List<String> deniedPermissions = new ArrayList<>();
                    for (int i = 0; i < grantResults.length; i++) {
                        int grantResult = grantResults[i];
                        String permission = permissions[i];
                        if (grantResult != PackageManager.PERMISSION_GRANTED) {
                            deniedPermissions.add(permission);
                        }
                    }
                    //全部授权成功
                    if (deniedPermissions.isEmpty()) {
                        mListener.onGranted();
                    } else {
                        mListener.onDenied(deniedPermissions);
                    }
                }
                break;
            default:
                break;
        }
    }
}
  • 2.授权回调接口
public interface PermissionListener {
    //授权,同意
    void onGranted();
    //拒绝
    void onDenied(List<String> deniedPermission);

}
  • 3.Activity控制器
public class ActivityCollector {

    private static List<Activity> activityList = new ArrayList<>();

    public static void addActivity(Activity activity){
        activityList.add(activity);
    }

    public static void removeActivity(Activity activity){
        activityList.remove(activity);
    }

    //获取当前栈顶activity
    public static Activity getTopActivity(){
        if (activityList.isEmpty()){
            return null;
        }else {
            return activityList.get(activityList.size()-1);
        }
    }

    public static void finishAll(){
        for (Activity activity : activityList) {
            if (!activity.isFinishing()){
                activity.finish();
            }
        }
    }
}
  • 注意

在非Activity中使用requestRuntimePermission()方法时需要在前面加上类名,如下:

BaseActivity.requestRuntimePermission(...);

requestRuntimePermission()方法里面的try–catch,加不加都可以。


课程中提到的一些小知识点

1.访问应用包名下的目录,可以不用申请权限
/data/data/包名

2.访问应用的缓存目录,getExternalCacheDir();

3.访问应用的重要文件存储目录,getExternalFilesDir(str);
str=”“,表files的根目录;
str=”adc”,表示files下的abc目录,没有就创建。

4.访问应用的包名目录,getDataDirectory();

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值