Android Permission 权限申请,EasyPermission和其他三方库

news/2024/10/30 15:29:09/

在Android的实际开发中,经常会因为需求的实现,需要申请用户权限。

今天总结下Android中常用的权限申请。

一、基本介绍和流程

Android中的权限申请是通过应用程序与操作系统之间的交互实现的。在Android中,每个应用程序都被赋予了一组预定义的权限,这些权限定义了应用程序可以执行的操作范围,例如访问摄像头、读取联系人、发送短信等。

当应用程序需要执行需要特定权限的操作时,它必须在运行时向操作系统请求这些权限。以下是Android中的权限申请流程:

  1. 权限声明:在应用程序的清单文件(AndroidManifest.xml)中,开发者需要声明应用程序所需的权限。这些权限声明描述了应用程序需要的访问级别。例如,如果应用程序需要访问设备的摄像头,开发者需要在清单文件中声明相应的权限。

  2. 运行时权限请求:对于一些敏感权限(如访问设备位置、读取联系人等),Android要求应用程序在运行时动态请求这些权限。当应用程序需要执行需要特定权限的操作时,它会向操作系统发起权限请求。

  3. 用户授权:当应用程序发起权限请求时,操作系统会弹出一个对话框,显示权限请求的详细信息,并询问用户是否同意授予该权限。用户可以选择允许或拒绝权限请求。

  4. 权限回调:一旦用户对权限请求做出了响应,系统会将结果通知给应用程序。应用程序可以处理用户的授权结果并相应地执行相应操作。这通常涉及检查权限是否被授予,如果权限被拒绝,则可以采取其他适当的行动。

二、简单的实现 相机和文件读写权限

manifest文件:

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

kotlin核心方法:

companion object {private const val RC_CAMERA_AND_LOCATION = 123const val PERMISSION_REQUEST_CODE = 100}
//在onCreate里定义一个按钮添加点击事件
normal.setOnClickListener {// 请求相机和文件读写权限if (checkPermissions()) {//检查权限//返回true 则进行接下来的逻辑ToastUtils.showShort("已经获得权限normal")} else {//没有权限,申请权限requestPermissions()}}private fun requestPermissions() {ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE),PERMISSION_REQUEST_CODE)}private fun checkPermissions(): Boolean {val cameraPermission = ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)val storagePermission = ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)return cameraPermission == PackageManager.PERMISSION_GRANTED &&storagePermission == PackageManager.PERMISSION_GRANTED}
//权限申请回掉override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)if (requestCode == PERMISSION_REQUEST_CODE) {var allPermissionsGranted = truefor (result in grantResults) {if (result != PackageManager.PERMISSION_GRANTED) {allPermissionsGranted = falsebreak}}if (allPermissionsGranted) {//进行} else {// 权限未授予,可以执行一些其他操作,如显示权限被拒绝的提示信息等Log.d(TAG, "Permissions denied")}}
}

这是自己实现的,很简单,检查权限,请求权限和权限回调全是用的系统的方法。但是现在的权限申请拒绝了的时候,很多手机会默认不在询问,导致用户一次拒绝过后,第二次进来,我们再次请求权限时用户根本不会看见权限授权弹窗,得写个方法去打开用户手机系统的权限设置页才行。

思来想去,偷个懒吧,用三方库

三、EasyPermissions

emmmm,实现起来很简单

1.build.gradle配置三方库(app下的)

dependencies {// For developers using AndroidX in their applicationsimplementation 'pub.devrel:easypermissions:3.0.0'// For developers using the Android Support Libraryimplementation 'pub.devrel:easypermissions:2.0.1'
}

2.业务代码(很简单,照着官方文档走就是了)

优点就是方便,且权限被拒绝后,下次申请回弹窗,用户点击后跳转设置页

class MainActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {private lateinit var easyPermissionsTv: TextViewprivate lateinit var permissionsDispatcherTv: TextViewprivate lateinit var rxPermissionsTv: TextViewprivate lateinit var dexterTv: TextViewprivate lateinit var normal: TextViewvar perms =arrayOf(android.Manifest.permission.CAMERA,android.Manifest.permission.ACCESS_FINE_LOCATION)companion object {private const val RC_CAMERA_AND_LOCATION = 123const val PERMISSION_REQUEST_CODE = 100}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)normal = findViewById(R.id.normalPermission)easyPermissionsTv = findViewById(R.id.EasyPermissions)permissionsDispatcherTv = findViewById(R.id.PermissionsDispatcher)dexterTv = findViewById(R.id.Dexter)rxPermissionsTv = findViewById(R.id.RxPermissions)easyPermissionsTv.setOnClickListener {requestCameraPermission()}}private fun requestCameraPermission() {if (EasyPermissions.hasPermissions(this, *perms)) {// 已经具有权限ToastUtils.showShort("已经获得权限")openCamera()} else {EasyPermissions.requestPermissions(PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, *perms).setRationale("需要相机权限和位置权限").setPositiveButtonText("给").setNegativeButtonText("就不给").build())}}@AfterPermissionGranted(RC_CAMERA_AND_LOCATION)private fun openCamera() {// 在此处执行打开相机的逻辑}override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)//将结果转发到EasyPermissionsEasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)}override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {ToastUtils.showShort("onPermissionsGranted")}override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {ToastUtils.showShort("onPermissionsDenied")if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {AppSettingsDialog.Builder(this).setRationale("老铁,没有相机权限和位置权限这事儿很难办啊").setNegativeButton("就不给就不给").setPositiveButton("给你给你给你").build().show()}}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {ToastUtils.showShort("申请权限返回")}}
}

 关于文件读写权限,由于Android各个版本的异同,有些很烦的区别,且看stack overflow大神的讨论:

WRITE_EXTERNAL_STORAGE when targeting Android 10 - Stack Overflow

4、常用的权限申请框架

  1. EasyPermissions: EasyPermissions是一个轻量级的开源库,简化了Android权限申请的过程。它提供了简单的API,用于请求权限、处理权限回调和解释权限的目的。该库还支持批量请求权限和自定义权限弹窗。

  2. TedPermission: TedPermission是一个易于使用的权限申请库,它提供了简洁的API,并具有可自定义的权限弹窗。该库还支持批量请求权限和处理回调。

  3. RxPermissions: RxPermissions是一个基于RxJava的权限申请库,它提供了使用Observables的方式来请求和处理权限。这使得在响应式编程中更容易处理权限相关的操作。

  4. PermissionsDispatcher: PermissionsDispatcher是一个基于注解的权限申请库,它使用了Java注解处理器技术,通过生成相关代码来简化权限申请过程。使用该库,开发者可以在方法上添加注解来声明所需的权限,并自动生成相关的权限申请和回调代码。

  5. Dexter: Dexter是一个简单而灵活的权限申请库,它通过简洁的API和回调接口来处理权限请求和回调。该库还提供了自定义权限弹窗的功能。

开源库的链接我就不给了,自己去github搜一下,star数都很高,blankj的工具库里面其实也有PermissionUtils.


http://www.ppmy.cn/news/84187.html

相关文章

智慧水务系统如何进行有效的数据架构整改?三个企业的改造实践分享

在智慧水务系统中&#xff0c;往往需要对设备中产生的液位、电流、水量等实时指标数据进行存储、分析及监控操作&#xff0c;而这些都是典型的时序数据。面对这些数据的处理时&#xff0c;很多企业在前期选择的大都是传统的实时数据库甚至关系型数据库&#xff0c;随着设备数量…

Linux 网络基础(2)应用层(http/https协议、请求格式、响应格式、session、cookie、加密传输)

说明&#xff1a;网络基础2讲解的是应用层的典型协议&#xff0c; 通过对于典型协议的理解&#xff0c;来体会数据的网络传输的软件层面的流程与原理。 面试中网络通信相关问题占了很大的比重&#xff0c;而网络通信相关的问题大多都集中在网络基础2这个单元中 下面是应用层的位…

安卓项目如何做单元测试

前言 先说一下创建篇文章的目的&#xff0c;近期负责搭建公司的单元测试框架&#xff0c;于是查阅了网上的很多文章&#xff0c;以及参考了github上很多的项目例子&#xff0c;并且也进行了相当多的尝试。这其中花费了很多的精力&#xff0c;大约有两三周的时间&#xff0c;远…

xml报文转Java实体

公众号推广: 目前CSDN进行VIP可见,文章可在微信公众号进行免费的阅读。 文章内容经过认证实践,比较的清晰易懂,适合初次接触的人员。 请关注微信公众号:菜鸟编程踩坑之路,进入公众号搜索关键词 xml转实体 需求场景: 因为需要对接一些比较老的系统接口,他们的请求方…

每日一练 | 网络工程师软考真题 Day11

1、以下关于网络存储描述正确的选项是 。 A&#xff0e;SAN系统是将存储设备连接到现有的网络上&#xff0c;其扩展能力有限 B&#xff0e;SAN系统是将存储设备连接到现有的网络上&#xff0c;其扩展能力很强 C&#xff0e;SAN系统使用专用网络&#xff0c;其扩展能力有限 …

MyBatis中使用第三方分页插件PageHelper完成分页功能

文章目录 一、前言二、基于插件拦截方式1、自定义插件2、使用第三方插件完成分页1、分页插件的配置2、分页插件的使用 一、前言 分页是web应用程序非常重要的一个技术。数据库中的数据可能是成千上万的&#xff0c;不可能把这么多的数据一次显示在浏览器上面。一般根据每行数据…

springboot 上传文件常见问题汇总

springboot 上传文件常见问题汇总 AccessDeniedException步骤配置怎么确保应用程序有这个路径及其子路径的访问权限步骤 AccessDeniedException 使用 SpringBoot 上传文件报错 java.nio.file.AccessDeniedException: /xx/xx/xx&#xff0c;这个异常意味着程序在试图访问该目录…

SDN — Google B4 SDN WAN 网络架构

目录 文章目录 目录Google B4 SDN WAN 网络B4 网络架构物理设备层局部网络控制层全局控制层Hybrid SDN 模式Google B4 SDN WAN 网络 Google 的 WAN 有 2 张网络(Two Backbones): B2(I-Scale Network):数据中心互联 Internet(POP)的网络,用于面向 Internet 用户访问,…