Android 动态权限最全解析

在这里插入图片描述
在这里插入图片描述

动态权限概述

Android6.0 开始,Google调整了应用的权限申请方案。调整之后将权限分级,分成了普通权限危险权限,普通权限的授权方式跟之前一样,只需要在Manifest文件中申明即可,危险权限不仅需要在Manifest文件中声明,还需要在程序中调用官方提供的Api主动申请。

动态权限分类

Android6.0 以后,一共将动态权限分成了9组,每组只要有一个权限申请成功了,就默认整组权限都可以使用了。这九组权限分别如下:

权限组名称权限组权限组权限成员
读写联系人group:android.permission-group.CONTACTSpermission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTS
电话group:android.permission-group.PHONEpermission:android.permission.READ_CALL_LOG permission:android.permission.READ_PHONE_STATE permission:android.permission.CALL_PHONE permission:android.permission.WRITE_CALL_LOG permission:android.permission.USE_SIP permission:android.permission.PROCESS_OUTGOING_CALLS permission:com.android.voicemail.permission.ADD_VOICEMAIL
日历信息group:android.permission-group.CALENDARpermission:android.permission.READ_CALENDAR permission:android.permission.WRITE_CALENDAR
相机group:android.permission-group.CAMERApermission:android.permission.CAMERA
传感器group:android.permission-group.SENSORSpermission:android.permission.BODY_SENSORS
地理位置group:android.permission-group.LOCATIONpermission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATION
存储卡group:android.permission-group.STORAGEpermission:android.permission.READ_EXTERNAL_STORAGE permission:android.permission.WRITE_EXTERNAL_STORAGE
多媒体group:android.permission-group.MICROPHONEpermission:android.permission.RECORD_AUDIO
SMSgroup:android.permission-group.SMSpermission:android.permission.READ_SMS permission:android.permission.RECEIVE_WAP_PUSH permission:android.permission.RECEIVE_MMS permission:android.permission.RECEIVE_SMS permission:android.permission.SEND_SMS permission:android.permission.READ_CELL_BROADCASTS

动态权限申请方法

方法1:官方API提供的方法

步骤1:检查是否有权限

由于低于API 23 是不需要使用动态权限申请的,我们需要先判断一下系统版本,代码如下是Android 6.0以上的系统还是Android 6.0以下的系统。用ContextCompat类中的checkSelfPermission方法进行是否有权限判断。

public static int checkSelfPermission(@NonNull Context context, @NonNull String permission) {
    if (permission == null) {
        throw new IllegalArgumentException("permission is null");
    }

    return context.checkPermission(permission, android.os.Process.myPid(), Process.myUid());
}

具体使用方法如下:

if (Build.VERSION.SDK_INT >= 23) {
  if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
              != PackageManager.PERMISSION_GRANTED) {
              //无该权限,需要申请
      }
} else { //低于23 不需要处理

}

步骤2:申请权限

在步骤的的checkSelfPermission方法中如果判断没有权限,就需要用到ActivityCompat类中的requestPermissions方法进行动态权限申请,该方法需要传一个需要申请权限名称的权限permissions数组。

public static void requestPermissions(final @NonNull Activity activity,
         final @NonNull String[] permissions, final @IntRange(from = 0) int requestCode) {
}

申请方法如下:先定一个需要申请权限的权限数组PERMISSIONS_STORAGE

private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {"android.permission.READ_EXTERNAL_STORAGE",
        "android.permission.WRITE_EXTERNAL_STORAGE"};
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);

步骤3:回调函数的处理

由于权限申请是异步的,用户完成了以后,需要回调函数处理,
Activity中提供了一个回调处理方法onRequestPermissionsResult,只需要重写该方法即可
case 中的参数REQUEST_EXTERNAL_STORAGE 即步骤2申请权限中定一个的参数

 @Override
 public void onRequestPermissionsResult(int requestCode,
                                        String permissions[], int[] grantResults) {
     switch (requestCode) {
         case REQUEST_EXTERNAL_STORAGE: {
             if (grantResults.length > 0
                     && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                 Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
             } else {
                 Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();
             }
         }

     }
 }

完整代码

在这里插入图片描述

我们以申请SD卡读写权限为例,完整代码如下:

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {"android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (Build.VERSION.SDK_INT >= 23) {
            checkPermission();
        }
    }


    private void checkPermission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission
                    .WRITE_EXTERNAL_STORAGE)) {
                Toast.makeText(this, "请开通相关权限,否则无法正常使用本应用!", Toast.LENGTH_SHORT).show();
            }
            //申请权限
            ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);

        } else {
            Toast.makeText(this, "已授权成功!", Toast.LENGTH_SHORT).show();
            dothings();
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_EXTERNAL_STORAGE: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    dothings();
                    Toast.makeText(this, "授权成功!", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "授权被拒绝!", Toast.LENGTH_SHORT).show();
                }
            }

        }
    }

    public void dothings() {

    }
}

AndroidManifest.xml声明权限

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

方法2:RxPermission

RxPermission 可以帮助开发者简化获取权限的相关处理操作,而且内部也自动帮我们判断了版本是否需要申请权限。同时结合RxJava可以方便的回调各种结果。
官网:https://github.com/tbruyelle/RxPermissions

引入依赖

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
 
dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.10.2'
     implementation 'io.reactivex.rxjava2:rxjava:2.0.1'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
}

由于rxpermissions需要用到rxjava,所有rxjava的包也一起引入。

声明权限

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

申请单个权限

RxPermissions permissions = new RxPermissions(this);
permissions.request(Manifest.permission.CAMERA)
       .subscribe(new Consumer<Boolean>() {
           @Override
           public void accept(Boolean aBoolean)  {
               if (aBoolean ) {
                   Toast.makeText(MainActivity.this, "授权成功!", Toast.LENGTH_SHORT).show();
               }else {
                   Toast.makeText(MainActivity.this, "授权失败!", Toast.LENGTH_SHORT).show();
               }
           }
       });

申请多个权限

RxPermissions permissions = new RxPermissions(this);  
permissions.request(Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE)
  .subscribe(new Consumer<Boolean>() {
            @Override
            public void accept(Boolean aBoolean)  {
                if (aBoolean ) {
                    Toast.makeText(MainActivity.this, "授权成功!", Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(MainActivity.this, "授权失败!", Toast.LENGTH_SHORT).show();
                }
            }
        });

方法3:AndPermission

AndPermission跟前面的RxPermission使用方法类似
官网:https://github.com/yanzhenjie/AndPermission

引入依赖

implementation 'com.yanzhenjie:permission:2.0.3'

申请单个或多个权限

 AndPermission.with(this)
            .runtime()
            .permission(Permission.WRITE_EXTERNAL_STORAGE,Permission.CAMERA)
            .onGranted(permissions -> {
                Toast.makeText(MainActivity.this, "授权成功!", Toast.LENGTH_SHORT).show();
            })
            .onDenied(permissions -> {
                Toast.makeText(MainActivity.this, "授权失败!", Toast.LENGTH_SHORT).show();
            })
            .start();

效果如下:在这里插入图片描述

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Android 11.0是谷歌推出的最新版本操作系统,其中包含了众多新的功能和特性。在Android系统中,Framework是系统的核心部分,它提供了许多基本功能,如UI管理、资源管理、通知机制等。因此,详细讨论整个Framework源码是非常复杂和庞大的任务。在这里,我将简要介绍一些Android 11.0最新Framework源码的解析内容。 首先,Android 11.0引入了一些新的特性,例如屏幕共享、一次性权限、自适应通知历史等。这些特性的实现涉及到多个模块,如Activity、PermissionManager和NotificationManager等。在源码中,我们可以看到这些模块的实现逻辑,以及它们与其他模块的关联。 其次,Android 11.0在安全方面做出了一些改进。例如,它增强了对应用程序之间的隔离机制,改善了应用程序的权限管理。这些安全性的提升主要是通过对Framework的修改和优化来实现的,我们可以在源码中找到相关的修改部分。 此外,Android 11.0还优化了性能和稳定性。在源码中,我们可以看到一些对性能优化的改动,如优化了UI渲染流程、资源加载机制等。这些改动旨在提高系统的响应速度和流畅性,提供更好的用户体验。 最后,需要注意的是,要完整解析整个Android 11.0 Framework源码是非常庞大和复杂的任务,需要深入研究各个模块之间的关联和实现细节。此外,由于源码的更新和改进很快,因此为了获得最新的信息,我们可以参考谷歌官方文档和开发者社区的讨论。 总而言之,Android 11.0最新Framework源码解析需要耗费大量时间和精力,涉及到众多模块和功能的实现。以上只是对一些主要方面的简要介绍,希望能够给您提供一个概览。 ### 回答2: Android 11.0 是Google最新发布的Android操作系统版本,它引入了一系列新的功能和改进,同时也对框架层的源码进行了更新和优化。 首先,在Android 11.0中,Google对用户隐私进行了更多的保护。例如,对于一些敏感权限,如位置信息、麦克风和相机访问权限,应用需要动态申请,并且用户可以选择只在使用应用时授予权限。此外,Android 11.0还对应用访问用户剪贴板中的内容进行了限制,增强了用户的隐私安全性。 其次,Android 11.0还加强了与5G网络的兼容性。在新的框架源码中,Google为开发者提供了一些新的API,以便更好地利用5G网络的优势。开发者可以根据网络的类型和条件,优化应用的网络连接和数据传输,提供更好的用户体验。 此外,Android 11.0还增加了一些新的功能,如呼吸灯通知模式、音频和视频编解码功能的改进、更强大的图像捕捉API等。这些功能的实现都离不开框架层的支持。开发者可以通过阅读最新的框架源码,了解和学习这些功能的具体实现方式,并在自己的应用中加以应用和优化。 总之,Android 11.0最新框架源码解析涵盖了对用户隐私的保护、与5G网络的兼容性以及一系列新功能的实现。了解和学习最新的框架源码,有助于开发者更好地理解Android操作系统的工作原理,提供更好的应用体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Teacher.Hu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值