zoukankan      html  css  js  c++  java
  • 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 及之后

      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一起交流
  • 相关阅读:
    《高校后勤管理信息系统设计与实现》论文笔记五
    《高校后勤管理系统的设计与实现》论文笔记三
    《高校后勤管理系统的设计与实现》论文笔记二
    如何利用React.js开发出强大Web应用
    关于啤酒和尿布故事的真相
    以生活例子说明单线程与多线程
    未来哪些领域WiFi将成为刚需?
    CSS开发中的10个不要
    10年后编程还有意义吗?
    JavaEE中遗漏的10个最重要的安全控制
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/7778418.html
Copyright © 2011-2022 走看看