zoukankan      html  css  js  c++  java
  • Android9.0动态运行时权限源码分析及封装改造<一>-----运行时权限名词解释、权限检测源码分析

    概述:

    我们都知道Google在Android6.0时引入了权限申请机制,也是变革非常大的一块,而如今商用项目中基本上都会涉及到这块,基本上都是使用三方成熟的框架来处理权限的问题,最常用的框为https://github.com/googlesamples/easypermissions,但是!!对于权限这块的知识有没有认真的去研究过呢?反正目前每次想到权限这块我的头还是有点大的,这也就是没有掌握这块原因所致,所以作为一个有追求的码农必须花时间给好好研究一下这块的机理,所以才产生写此篇博客的想法,虽说是烂大街的技术,但是只要是自己没掌握的就得学!

    运行时权限名词解释:

    先来了解一些跟权限相关的名词,了解它们能够更好的理解接下来要研究的东东,因为分析权限框架源码时会涉及到。

    什么是uid、pid?

    • uid:本身是linux权限系统中用以区分用户身份的标识,由于android是单一用户权限系统,uid在android里面又可以理解为应用的标识Id,该Id自安装之日起就被分配,始终如一。
    • pid:顾名思义是进程唯一标识id,用以和远程服务交互。

    什么是appId、callerId?

    • appId:可以理解为应用Id,跟uid一样,这是本地应用在远程服务中的叫法。
    • callerId:它是服务请求者的身份Id,可以是本地应用的身份Id,也可以是远程服务在身份标识Id。

    危险权限(组):

    Android6.0以后将系统权限分为两类:正常权限和危险权限, 对于这俩权限看一下它们俩的区别,借网上的说明:

    动态权限处理指的就是对于危险权限的处理,下面来了解一下危险权限都有哪一些:

    权限检测源码分析【Android9.0】:

    接下来则来分析Android9.0权限框架的源码,分析的入口则是从平常咱们写的申请权限的调用代码开始,先来回忆一下我们是如何来调用的:

    package com.permissionarchstudy.test;
    
    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.app.ActivityCompat;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final int RESULT_CODE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 100;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
    
                } else {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RESULT_CODE_PERMISSIONS_WRITE_EXTERNAL_STORAGE);
                }
            }
        }
    }

    其中申请权限涉及到上面标红的三个api,接下来则按着我们调用的顺序来分析。

    checkSelfPermission:

    具体来分析一下它:

    接下来则点击进去瞅一瞅,我们知道am的具体实现类是ActivityManagerService,所以咱们往它里面继续定位:

    继续,发现无法点进去了:

    如何解决IDE中跳不到隐藏API的问题?

    其实我们手动打开ActivityManager类是能找到这个方法的,如下:

    其实将这个hide注解去掉就可以了,问题是我们SDK是从官网下的,去不掉呀,其实网上github上已经有人帮我们整理了,地址:https://github.com/anggrayudi/android-hidden-api:

    下面咱们来试一下,下载android-28既可,因为正好咱们分析的就是这个版本:

     

    替换到这个位置:

    此时IDE刷新之后,就可以正常的跳转啦,如下:

    这样看代码就比较方便了,学了个小技巧,流程继续往下:

    那啥叫隔离进程呢?在Android中其实是有一个进程的范围的,比如有些应用被拉入黑名单,总之这个进程是没有任何权限的,继续往下:

    那又反问一下,啥叫应用自己的权限,我们知道我们可以在manifest中声明自己的权限,比如:

    我们知道在manifest中是可以加export属性的:

    像上面如果这样声明是不允许被其它调用的,比较好理解,继续:

    咱们来瞅一下它的细节:

     

    而我们知道它的具体Service则是PackageManagerService,跟进去看一下:

    所以,到这个类中来查看进一步的细节:

    这个是指访问者或者申请者的应用ID,这个一般是给Google小程序来使用的,国内APP是用不到的,继续:

    这里了解一下https://blog.csdn.net/singwhatiwanna/article/details/80490124,其实就是类似于微信小程序:

    对于我们应用来说肯定是用不到了,了解一下既可,继续:

    正常我们平常开发的应用是不会要配置它的,所以这个条件肯定是进不来的,则看其它条件:

    以上条件都没有通过,那很显然此权限木有拥有,则直接返回未授权了:

    下面用一张图对上面整个流程进行一个梳理:

    shouldShowRequestPermissionRationale:

    在上面中如果检测到该权限木有授权,则会往下来执行到它:

     

    这是干嘛的呢?看一下官方的解释:

    啥意思?继续往下读一段你就明白了,官方举了一个具体的使用它的场景:

    哦,这样哟,往里分析一下它的细节:

    而它最终会跳到这:

    一看就跳到了PackageManagerService了,如下:

    回到主流程继续往下分析:

     

    其中FLAG_PERMISSION_USER_FIXED它是指用户在权限中明确设置了“不再询问”了,最后就是判断一下是否是这个FLAG,如果是则就需要显示弹窗:

    这样的弹窗大概长这样子:

    下面也同样来总结一下上面的流程:

  • 相关阅读:
    nodejs学习(一)--express+ejs生成项目
    react-native React Native version mismatch
    qrcode length overflow 生成二维码网址长度溢出解决办法
    禁止input输入空格
    微信开发:清除微信浏览器缓存
    多行文本溢出显示...的方法(-webkit-line-clamp)
    angular路由(自带路由篇)
    angular入门(基础篇)
    Python文件读写(open(),close(),with open() as f...)
    centos6.9使用yum安装mysql(简单粗暴,亲测有效)
  • 原文地址:https://www.cnblogs.com/webor2006/p/12757460.html
Copyright © 2011-2022 走看看