我正在参加第6期掘金创想营,点击查看活动详情

我正在参加第 6 期掘金创想营, 点击了解活动详情

‍ 作者简介:一个喜欢写作的大三菜鸟,主修会计

个人主页: 陆莉主演
订阅专栏: Android 基础知识入门
每日推荐: 牛客网——面试神器

在这里插入图片描述

如果文章对你有帮助记得点赞+收藏支持

今天实现一个小功能,调用相机权限实现手电筒,顺便学习一下 相机管理器 主要推荐系统服务和两个有用的权限请求框架 XX权限

1.权限设置

官方权限概述

存在 清单.xml 在中引入相机权限

 <!--引入相机权限-->  
 <uses-permission android:name= "android.permission.CAMERA"/>  
 复制代码

image-20220821222826932

2.xml布局文件

image-20220821223627820

 <?xml version= "1.0" encoding= "utf-8" ?>  
 < 相对布局 xmlns:android = "http://schemas.android.com/apk/res/android"  
 xmlns:app = "http://schemas.android.com/apk/res-auto"  
 xmlns:tools = "http://schemas.android.com/tools"  
 android:layout_width = "match_parent"  
 android:layout_height = "match_parent"  
 工具:上下文=“.MainActivity”>  
  
 < 图像视图  
 android:id = "@+id/flashBtn"  
 android:layout_width = "wrap_content"  
 android:layout_height = "match_parent"  
 android:scaleType = "centerCrop"  
 android:src = "@drawable/off"  
 应用程序:layout_constraintBottom_toBottomOf = “父”  
 应用程序:layout_constraintLeft_toLeftOf = “父”  
 应用程序:layout_constraintRight_toRightOf = “父”  
 应用程序:layout_constraintTop_toTopOf = "父" />  
  
 </ RelativeLayout >  
 复制代码

3. 预备知识

CameraManager 官方文档

相机管理器 是系统服务之一,致力于 探测打开照相机 ,也 获取相机设备属性

  1. 字符串[] getCameraIdList()
    获取当前连接的相机设备列表。这个id通常从0开始,依次递增。

对于普通手机:

后置摄像头一般 CameraCharacteristics.LENS_FACING_FRONT ,常数值为“0”;
前置摄像头一般 CameraCharacteristics.LENS_FACING_BACK ,常数值为“1”

2. void setTorchMode(String cameraId, boolean enabled)

打开和关闭指定相机设备的闪光灯功能。

4.XXPermissions 框架(推荐)

XXPermissions 框架官方文档

4.1 框架亮点

  • 第一的 适配安卓13 权限请求框架
  • 第一个也是唯一一个 兼容所有安卓版本 权限请求框架
  • 简单易用:使用 链式调用 方式,只使用一行代码
  • 令人印象深刻的体积:功能在同类镜架中最全,但镜架音量垫底
  • 适应极端情况:无论申请许可的环境多么极端,框架依然强大
  • 向下兼容属性:在旧系统中可以正常申请新权限,框架会自动适配,无需调用者适配
  • 自动检测错误:如果有错误,框架会主动向调用者抛出异常(只在Debug下判断,将bug杀在摇篮里)

4.2 集成步骤

  • 如果您的项目 Gradle 配置在 7.0以下 , 需要在 构建.gradle 添加到文件

    所有项目{
    存储库{
    // JitPack 远程仓库:https://jitpack.io
    maven { url 'https://jitpack.io' }
    }
    }
    复制代码

  • 如果您的 Gradle 配置是 7.0及以上 , 你需要 设置.gradle 添加到文件

    依赖解析管理{
    存储库{
    // JitPack 远程仓库:https://jitpack.io
    maven { url 'https://jitpack.io' }
    }
    }
    复制代码

  • 配置好远程仓库后,在项目app模块下 构建.gradle 将远程依赖项添加到文件

    安卓 {
    // 支持JDK 1.8
    编译选项 {
    目标兼容性 JavaVersion.VERSION_1_8
    sourceCompatibility JavaVersion.VERSION_1_8
    }
    }

    依赖{
    // 权限请求框架:https://github.com/getActivity/XXPermissions
    实施 'com.github.getActivity:XXPermissions:16.0'
    }
    复制代码

  • 如果项目基于 安卓X 包,请在项目 gradle.properties 添加到文件

    表示将第三方库迁移到 AndroidX

    android.enableJetifier = true
    复制代码

  • 如果项目基于 支持 不需要将包添加到此配置中

4.3 请求许可

 XXPermissions.with(这个)  
 // 申请单个权限  
 .permission(Permission.RECORD_AUDIO)  
 // 申请多个权限  
 .permission(Permission.Group.CALENDAR)  
 // 设置权限请求拦截器(本地设置)  
 //.interceptor(new PermissionInterceptor())  
 // 设置不触发错误检测机制(本地设置)  
 //.unchecked()  
 .request(新的 OnPermissionCallback() {  
  
 @覆盖  
 public void onGranted (列表<String>权限,布尔全部){  
 我摔倒) {  
 toast("部分权限获取成功,但部分权限未正常授予");  
 返回;  
 }  
 toast("获取录音和日历权限成功");  
 }  
  
 @覆盖  
 公共无效 onDenied (列表<String>权限,布尔从不){  
 如果(从不){  
 toast("授权被永久拒绝,请手动授予录音和日历权限");  
 // 如果被永久拒绝,跳转到申请权限系统设置页面  
 XXPermissions.startPermissionActivity(上下文,权限);  
 } 别的 {  
 toast("获取录音和日历权限失败");  
 }  
 }  
 });  
 复制代码

4.4 框架的其他API

 // 判断一个或多个权限是否都被授予  
 XXPermissions.isGranted(上下文上下文,字符串...权限);  
  
 // 获取未授予的权限  
 XXPermissions.getDenied(上下文上下文,字符串...权限);  
  
 // 判断一个权限是否为特殊权限  
 XXPermissions.isSpecial(字符串权限);  
  
 // 判断一个或多个权限是否被永久拒绝  
 XXPermissions.isPermanentDenied(Activity activity, String... 权限);  
  
 // 跳转到应用权限设置页面  
 XXPermissions.startPermissionActivity(上下文上下文,字符串...权限);  
 XXPermissions.startPermissionActivity(活动活动,字符串...权限);  
 XXPermissions.startPermissionActivity(Activity 活动, String... 权限, OnPermissionPageCallback 回调);  
 XXPermissions.startPermissionActivity(Fragment fragment, String... 权限);  
 XXPermissions.startPermissionActivity(Fragment fragment, String... 权限, OnPermissionPageCallback 回调);  
  
 // 设置不触发错误检测机制(全局设置)  
 XXPermissions.setCheckMode(false);  
 // 设置权限请求拦截器(全局设置)  
 XXPermissions.setInterceptor(new IPermissionInterceptor() {});  
 复制代码

5. 德克斯特框架

Dexter 框架官方文档

该框架不再处于积极开发中,最后一次更新是在 14 个月前。

德克斯特 是一个 Android 库,可简化运行时请求权限的过程。 安卓棉花糖 包含一个新功能, 允许用户在运行应用程序时授予或拒绝权限,而不是在安装时授予所有权限 .这种方法让用户可以更好地控制应用程序,但需要开发人员添加大量代码来支持它。 Dexter 将您的权限代码从您的活动中释放出来,允许您在任何地方编写该逻辑。

5.1 引入依赖

将库包含在您的 构建.gradle

 依赖项{  
 实施 'com.karumi:dexter:6.2.3'  
 }  
 复制代码

5.2 个人权限

对于每个权限,注册一个 权限监听器 实施以接收请求的状态:

 Dexter.withContext(这个)  
 .withPermission(Manifest.permission.CAMERA)  
 .withListener(新 PermissionListener(){  
 @Override public void onPermissionGranted (PermissionGrantedResponse 响应) { /* ... */}  
 @Override public void onPermissionDenied (PermissionDeniedResponse 响应) { /* ... */}  
 @Override public void onPermissionRationaleShouldBeShown (PermissionRequest 权限,PermissionToken 令牌) { /* ... */}  
 })。查看();  
 复制代码

5.3 多重权限

 Dexter.withContext(这个)  
 .withPermissions(  
 Manifest.permission.CAMERA,  
 Manifest.permission.READ_CONTACTS,  
 Manifest.permission.RECORD_AUDIO  
 ).withListener( 新的 MultiplePermissionsListener() {  
 @Override public void onPermissionsChecked (MultiplePermissionsReport 报告) { /* ... */}  
 @Override public void onPermissionRationaleShouldBeShown (List<PermissionRequest>权限,PermissionToken 令牌){ /* ... */}  
 })。查看();  
 复制代码

6. 同类权限请求框架比较

适配细节 XX权限 和权限 权限X AndroidUtilCode 权限调度程序 接收权限 EasyPermissions 对应版本 16.0 2.0.3 1.6.4 1.31.0 4.9.2 0.12 3.0.0 帧量 51KB 127KB 90KB 500KB 99KB 28KB 48KB 框架维护状态 维护中 停止维护 维护中 停止维护 维护中 停止维护 停止维护 报警提醒权限 ✅ ❌ ❌ ❌ ❌ ❌ ❌ 所有文件管理权限 ✅ ❌ ✅ ❌ ❌ ❌ ❌ 安装包权限 ✅ ✅ ✅ ❌ ❌ ❌ ❌ 浮窗权限 ✅ ✅ ✅ ✅ ✅ ❌ ❌ 系统设置权限 ✅ ✅ ✅✅✅✅❌❌通知栏权限✅✅✅❌❌❌❌❌通知栏监控权限✅✅❌❌❌❌❌请勿打扰权限✅❌❌❌❌❌❌忽略电池优化权限✅❌❌❌❌❌❌查看应用用法许可✅❌❌❌❌❌❌❌❌❌❌❌❌❌✅✅✅❌❌❌❌❌❌❌❌❌❌❌❌❌❌13危险许可✅✅✅❌❌❌❌❌❌❌❌❌❌❌android 12危险许可证危险许可❌ Android 10 危险权限 ✅ ✅ ✅ ❌ ✅ ❌ ❌ Android 9.0 危险权限 ✅ ❌ ✅ ❌ ✅ ❌ ❌ Android 8.0 危险权限 ✅ ✅ ✅ ❌ ✅ ❌ ❌ 新权限自动兼容旧设备 ✅ ❌ ❌ ❌ ❌ ❌旋转场景适配✅✅✅✅❌✅❌❌后台应用权限场景适配✅❌❌❌❌❌❌Android 12内存泄漏错误修复✅❌❌❌❌❌❌错误检测机制✅❌❌❌❌❌❌

7. Dexter 请求实现手电筒的权限

使用这个框架的前提只需要在 构建.gradle 引入依赖项

 公共类 MainActivity 扩展 AppCompatActivity {  
  
 ImageView flashBtn;  
 布尔状态;  
 @覆盖  
 protected void onCreate (Bundle savedInstanceState) {  
 super.onCreate(savedInstanceState);  
 setContentView(R.layout.activity_main);  
 flashBtn=findViewById(R.id.flashBtn);  
  
 Dexter.withContext( this) //指定页面  
 .withPermission(Manifest.permission.CAMERA) //指定权限  
 .withListener( new PermissionListener() { //创建监听器  
  
 @覆盖  
 公共无效 onPermissionGranted (PermissionGrantedResponse permissionGrantedResponse) {  
 // 运行手电筒  
 运行手电筒();  
  
 }  
  
 //用户提示  
 @覆盖  
 公共无效 onPermissionDenied (PermissionDeniedResponse permissionDeniedResponse) {  
 Toast.makeText(MainActivity.this, "相机权限请求",Toast.LENGTH_SHORT).show();  
 }  
  
 @覆盖  
 公共无效 onPermissionRationaleShouldBeShown (PermissionRequest permissionRequest, PermissionToken permissionToken) {  
  
 }  
 })。查看();  
 }  
  
 私人无效运行手电筒(){  
 flashBtn.setOnClickListener(new View.OnClickListener() {  
 @覆盖  
 public void onClick(查看视图){  
 如果(!状态){  
 //设置摄像头功能管理  
 CameraManager cameraManager=(CameraManager) getSystemService(Context.CAMERA_SERVICE);  
 尝试 {  
 //getCameraIdList() 按标识符返回当前连接的相机设备列表,包括其他相机 API 客户端可能使用的相机。  
 字符串 cameraId=cameraManager.getCameraIdList()[0];  
 //开启和关闭指定相机设备的闪光灯功能。  
 cameraManager.setTorchMode(cameraId, true);  
 //设置状态为true,打开  
 状态=真;  
 //改变图片资源  
 flashBtn.setImageResource(R.drawable.on);  
 } 捕捉(CameraAccessException e){  
  
 }  
 } 别的{  
 //设置摄像头功能管理  
 CameraManager cameraManager=(CameraManager) getSystemService(Context.CAMERA_SERVICE);  
 尝试 {  
 //getCameraIdList() 按标识符返回当前连接的相机设备列表,包括其他相机 API 客户端可能使用的相机。  
 字符串 cameraId=cameraManager.getCameraIdList()[0];  
 //开启和关闭指定相机设备的闪光灯功能。  
 cameraManager.setTorchMode(cameraId, false);  
 状态=假;  
 flashBtn.setImageResource(R.drawable.off);  
 } 捕捉(CameraAccessException e){  
  
 }  
 }  
  
 }  
 });  
 }  
 }  
 复制代码

8.XXPermissions 请求权限实现手电筒

  • 我的项目的 Gradle 配置是 7.0及以上 ,所以我需要 设置.gradle 添加到文件 maven { url 'https://jitpack.io' } ,

  • 我的项目是基于 安卓X 包,项目中需要 gradle.properties 添加到文件 android.enableJetifier = true

  • 最后在项目app模块下 构建.gradle 将远程依赖项添加到文件

    公共类 MainActivity 扩展 AppCompatActivity {

    ImageView flashBtn;
    布尔状态;
    @覆盖
    protected void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    flashBtn=findViewById(R.id.flashBtn);

    XXPermissions.with(这个)
    // 申请单个权限(摄像头)
    .permission(权限.CAMERA)
    // 申请多个权限(日历),要申请多个权限,只需要列出你要申请的权限
    //.permission(Permission.Group.CALENDAR)
    .request(新的 OnPermissionCallback() {
    @覆盖
    public void onGranted (列表权限,布尔全部){
    我摔倒) {
    Toast.makeText(MainActivity.this, "获取部分权限成功,但部分权限未正常授予",Toast.LENGTH_SHORT).show();
    返回;
    }
    运行手电筒();
    Toast.makeText(MainActivity.this, "获取相机权限成功",Toast.LENGTH_SHORT).show();
    }

    @覆盖
    公共无效 onDenied (列表权限,布尔从不){
    如果(从不){
    Toast.makeText(MainActivity.this, "授权被永久拒绝,请手动授予相机权限",Toast.LENGTH_SHORT).show();
    // 如果被永久拒绝,跳转到申请权限系统设置页面
    XXPermissions.startPermissionActivity(MainActivity.this, 权限);
    } 别的 {
    Toast.makeText(MainActivity.this, "获取录制和日历权限失败",Toast.LENGTH_SHORT).show();
    }
    }
    });

    }

    私人无效运行手电筒(){
    flashBtn.setOnClickListener(new View.OnClickListener() {
    @覆盖
    public void onClick(查看视图){
    如果(!状态){
    //设置摄像头功能管理
    CameraManager cameraManager=(CameraManager) getSystemService(Context.CAMERA_SERVICE);
    尝试 {
    //getCameraIdList() 按标识符返回当前连接的相机设备列表,包括其他相机 API 客户端可能使用的相机。
    字符串 cameraId=cameraManager.getCameraIdList()[0];
    //开启和关闭指定相机设备的闪光灯功能。
    cameraManager.setTorchMode(cameraId, true);
    //设置状态为true,打开
    状态=真;
    //改变图片资源
    flashBtn.setImageResource(R.drawable.on);
    } 捕捉(CameraAccessException e){

    }
    } 别的{
    //设置摄像头功能管理
    CameraManager cameraManager=(CameraManager) getSystemService(Context.CAMERA_SERVICE);
    尝试 {
    //getCameraIdList() 按标识符返回当前连接的相机设备列表,包括其他相机 API 客户端可能使用的相机。
    字符串 cameraId=cameraManager.getCameraIdList()[0];
    //开启和关闭指定相机设备的闪光灯功能。
    cameraManager.setTorchMode(cameraId, false);
    状态=假;
    flashBtn.setImageResource(R.drawable.off);
    } 捕捉(CameraAccessException e){

    }
    }

    }
    });
    }
    }
    复制代码

9.效果展示

在这里插入图片描述

10. 参考文献

胡老师(胡老师的博客)Android动态权限最全解析

胡老师(胡老师博客)【Android】相对布局最全解析(RelativeLayout)

官方权限概述

在运行时请求 Android 权限的 Android 库

Android Camera2的CameraManager详解

Android 支持和 AndroidX

订阅专栏: 《牛客刷题集》

每日推荐: 基本算法是研究生面试和求职面试中非常重要的一部分。这里有一个算法面试神器:牛客网-面试神器;算法题只有刷的更频繁才能记住和感受。大家赶紧行动吧。 (温馨提示:常见的面试题库也很nice)

在这里插入图片描述

如果文章对你有帮助记得点赞+收藏支持

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议。转载请附上原文出处链接和本声明。

这篇文章的链接: https://homecpp.art/2704/6413/0928

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/12312/08350412

posted @   哈哈哈来了啊啊啊  阅读(7810)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示