我正在参加第6期掘金创想营,点击查看活动详情
我正在参加第 6 期掘金创想营, 点击了解活动详情
作者简介:一个喜欢写作的大三菜鸟,主修会计
个人主页: 陆莉主演
订阅专栏: Android 基础知识入门
每日推荐: 牛客网——面试神器
如果文章对你有帮助记得点赞+收藏支持
今天实现一个小功能,调用相机权限实现手电筒,顺便学习一下 相机管理器
主要推荐系统服务和两个有用的权限请求框架 XX权限
1.权限设置
存在 清单.xml
在中引入相机权限
<!--引入相机权限-->
<uses-permission android:name= "android.permission.CAMERA"/>
复制代码
2.xml布局文件
<?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. 预备知识
相机管理器
是系统服务之一,致力于 探测 和 打开照相机 ,也 获取相机设备属性
字符串[] getCameraIdList()
获取当前连接的相机设备列表。这个id通常从0开始,依次递增。
对于普通手机:
后置摄像头一般 CameraCharacteristics.LENS_FACING_FRONT
,常数值为“0”;
前置摄像头一般 CameraCharacteristics.LENS_FACING_BACK
,常数值为“1”
2. void setTorchMode(String cameraId, boolean enabled)
打开和关闭指定相机设备的闪光灯功能。
4.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. 德克斯特框架
该框架不再处于积极开发中,最后一次更新是在 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】相对布局最全解析(RelativeLayout)
Android Camera2的CameraManager详解
订阅专栏: 《牛客刷题集》
每日推荐: 基本算法是研究生面试和求职面试中非常重要的一部分。这里有一个算法面试神器:牛客网-面试神器;算法题只有刷的更频繁才能记住和感受。大家赶紧行动吧。 (温馨提示:常见的面试题库也很nice)
如果文章对你有帮助记得点赞+收藏支持
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议。转载请附上原文出处链接和本声明。
这篇文章的链接: https://homecpp.art/2704/6413/0928
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库