本文转载自:http://blog.csdn.net/self_study/article/details/52965045

 最近在研究权限适配的相关内容,整理以前的权限博客如下: 
  android permission权限与安全机制解析(上) 
  android permission权限与安全机制解析(下) 
  Android 悬浮窗权限各机型各系统适配大全 
  这篇博客主要是介绍录音权限和摄像头权限的适配,android permission权限与安全机制解析(下)这篇博客中我介绍到了 6.0 之后危险权限的相关处理步骤,而录音和摄像头权限正好是属于危险权限,所以需要去单独申请,申请的步骤在这篇博客中就不介绍了,上面那篇博客中已经介绍的很详细,这里主要是介绍在不同版本如何去检测权限的授予与否。 
  转载请注明出处:http://blog.csdn.net/self_study/article/details/52965045。 
  PS:对技术感兴趣的同鞋加群544645972一起交流。

录音权限

6.0之前

  6.0 之前的检测方法我最刚开始的想法是依照悬浮窗权限的适配方案,使用 AppOpsManager 去检测,但是实际情况是,6.0 版本之下的机型很多判断都不准确,所以无奈在网上找到了一种粗暴的解决方案:

public class AudioPermissionCheckUtils {
private static final String TAG = "AudioPermissionCheckUtils"; // 音频获取源
public static int audioSource = MediaRecorder.AudioSource.MIC;
// 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025
public static int sampleRateInHz = 44100;
// 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道
public static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
// 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。
public static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
// 缓冲区字节大小
public static int bufferSizeInBytes = 0; /**
* 判断是是否有录音权限
*/
public static boolean checkAudioPermission(final Context context) {
bufferSizeInBytes = 0;
bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(audioSource, sampleRateInHz,
channelConfig, audioFormat, bufferSizeInBytes);
//开始录制音频
try{
// 防止某些手机崩溃,例如联想
audioRecord.startRecording();
}catch (IllegalStateException e){
e.printStackTrace();
AVLogUtils.e(TAG, Log.getStackTraceString(e));
}
/**
* 根据开始录音判断是否有录音权限
*/
if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING
&& audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED) {
AVLogUtils.e(TAG, "audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING : " + audioRecord.getRecordingState());
return false;
} if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED) {
//如果短时间内频繁检测,会造成audioRecord还未销毁完成,此时检测会返回RECORDSTATE_STOPPED状态,再去read,会读到0的size,所以此时默认权限通过
return true;
} byte[] bytes = new byte[1024];
int readSize = audioRecord.read(bytes, 0, 1024);
if (readSize == AudioRecord.ERROR_INVALID_OPERATION || readSize <= 0) {
AVLogUtils.e(TAG, "readSize illegal : " + readSize);
return false;
}
audioRecord.stop();
audioRecord.release();
audioRecord = null; return true;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

这个解决方案一目了然,就是直接调用 AudioRecord 去录音,如果发现录音的文件大小不正确,比如为0,再结合此时的录音状态,那么可以基本判定录音权限的开启与否。

6.0 及之后

  6.0 之后,系统提供了相关 API,权限检测就很简单了:

int hasCameraPermission;
hasCameraPermission = checkSelfPermission(Manifest.permission.CAMERA);
Toast.makeText(this, "camera granted : " + (hasCameraPermission == PackageManager.PERMISSION_GRANTED), Toast.LENGTH_SHORT).show();
  • 1
  • 2
  • 3

只要返回的值为 PackageManager.PERMISSION_GRANTED 就可以判定已经授权改权限。

摄像头权限

6.0之前

  同录音权限,在 6.0 之前的版本使用 AppOpsManager 在很多机型上会有适配问题,所以在这里依旧粗暴的采用下面这种方案:

public class CameraPermissionCheckUtils {
private static final String TAG = "CameraPermissionCheckUtils"; public static boolean checkCameraPermission(Context context) {
boolean canUse = true;
Camera mCamera = null;
try {
mCamera = Camera.open(0);
mCamera.setDisplayOrientation(90);
} catch (Exception e) {
AVLogUtils.e(TAG, Log.getStackTraceString(e));
canUse = false;
}
if (canUse) {
mCamera.release();
mCamera = null;
}
return canUse;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

但是貌似在少数机型和手机上依旧会有判断错误的情况存在,而且由于这个函数会调用 Camera.open 函数,所以造成在少些手机上会卡顿一下。

6.0 及之后

  6.0 之后就直接使用系统 API 进行判断就可以了:

int hasAudioPermission;
hasAudioPermission = checkSelfPermission(Manifest.permission.RECORD_AUDIO);
Toast.makeText(this, "audio granted : " + (hasAudioPermission == PackageManager.PERMISSION_GRANTED),
Toast.LENGTH_SHORT).show();
  • 1
  • 2
  • 3
  • 4

同样,只要判断返回结果为 PackageManager.PERMISSION_GRANTED 就可以判定 app 已被授权摄像头权限。

源码下载

  https://github.com/zhaozepeng/AndroidAudioCameraPermission

版权声明:转载请标明出处http://blog.csdn.net/self_study,对技术感兴趣的同鞋加群544645972一起交流

Android 录音和摄像头权限适配【转】的更多相关文章

  1. Android 9.0网络权限适配

    在做Android开发时,使用华为的p20和平板(均为Android 9.0)测试时,发现不能使用WIFI网络,一番郁闷纠结查找后 直接上方法: 在res文件夹下创建xml文件夹,在xml里面创建文件 ...

  2. Android 6.0权限适配

    targetSdkVersion 23以上,必须适配新的权限模式 安卓6.0及之后,权限分为三类  1.不涉及隐私的正常权限,如innernet2.危险权限 3.特殊权限 system_alert_w ...

  3. Android 6.0 - 动态权限管理的解决方案

    Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...

  4. Android 6.0 - 动态权限管理的解决方案(转)

    转自:http://www.cnblogs.com/dubo-/p/6018262.html Android 6.0 - 动态权限管理的解决方案   转载请标注 Android 6.0版本(Api 2 ...

  5. android 6.0 动态权限

    Android 6.0 动态权限: 除了要在AndroidManifest.xml中申请外,还需使用时,请求用户允许授权. 以下是需要单独申请的权限,共分为9组,每组只要有一个权限申请成功了,就默认整 ...

  6. Android 录音和播放

    今天工作上需要做一个一边录音一边播放的功能,大致原因是有一个外部设备输入音频到我们机器,然后我们机器需要马上把音频播放出来.所以了解了一些有关录音和播放的知识.接到这个任务的第一反应就是看看Andro ...

  7. Android权限申请完全解析(一):Android自带的权限申请

    1.为什么要权限申请 6.0以上就需要了,别问为什么.(不是重点,自行搜索) 2.如何进行权限申请 Android自带的权限申请 EasyPermission权限申请 Ps:EasyPermissio ...

  8. Android OpenCV集成摄像头图片动态识别车牌号

    最近两天开发一个使用OpenCV集成的一个识别车牌号的项目,困难重重,总结一下相关经验,以及开发注意事项: 一.开发环境: Android Studio 个人版本 3.1.4 NDK下载:14b CM ...

  9. Android 13 新特性及适配指南

    Android 13(API 33)于 2022年8月15日 正式发布(发布时间较往年早了一些),正式版Release源代码也于当日被推送到AOSP Android开源项目. 截止到笔者撰写这篇文章时 ...

随机推荐

  1. HDU - 2102 A计划(双层BFS)

    题目: 可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验.魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老.年迈的国王正是心急如焚, ...

  2. sphinx配置

    配置文件 ## 数据源src1 source src1 { ## 说明数据源的类型.数据源的类型可以是:mysql,pgsql,mssql,xmlpipe,odbc,python ## 有人会奇怪,p ...

  3. eclipse 导入svn项目并添加server

    1.打开svn资源库 window-->show view-->other-->svn-->svn资源库 2.控制台选中文件夹右键-->检出为--finish 3.添加服 ...

  4. mac 解决mysql启动不了

    mac升级了mysql,没有替换原来的链接的情况下, 启动mysql restart 会失败 解决方法,找到mysql真正的安装目录 mysql.server start

  5. rbac组件之菜单操作(三)

    菜单包括菜单列表,菜单列表不仅将菜单列出来,而且将每个菜单下的权限也列出来.菜单的添加.删除.修改. urls.py ... re_path(r'^menus/list/$', MenuView.as ...

  6. //……关于HTTP与HTTPS

    图1 图2 第一张访问域名http://www.tsinghua.edu.cn,谷歌浏览器提示不安全链接,第二张是https://www.12306.cn/index,浏览器显示安全,为什么会这样子呢 ...

  7. C51 keil 注意事项

    下载程序需要生成hex文件 仿真 蜂鸣器 音调:频率 音量:高低电平占空比 有源:上面没有加号,只需高低电平即可发声 无源:上面有加号,不仅要电平,还要, 的频率

  8. Qt笔记——连接第三方库&用libZPlay库获取音频文件的艺术家、专辑等信息

    连接第三方库libZPlay 概述 需要.a/.lib ,.h , .dll 三个文件 官网下载 http://libzplay.sourceforge.net/ import .h 链接 .a 放入 ...

  9. 下载Spring4.1.x源码并用IntelliJ IDEA打开-----

    下载Spring4.1.x源码并用IntelliJ IDEA打开-------https://blog.csdn.net/boling_cavalry/article/details/79426075 ...

  10. navicat mysql 连接本地 忘记密码 查看密码 操作

    https://jingyan.baidu.com/article/454316ab4e9e65f7a7c03ad1.html