Android 录音和摄像头权限适配

天下之事常成于困约,而败于奢靡。这篇文章主要讲述Android 录音和摄像头权限适配相关的知识,希望能为你提供帮助。
本文转载自: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 及之后【Android 录音和摄像头权限适配】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一起交流

    推荐阅读