Android 6.0以上检测权限用ActivityCompat.checkSelfPermission(context,permissionCode)或ContextCompat.checkSelfPermission(context,permissionCode)
private static boolean hasPermission(Context context, String permissionCode) {MyLog.e("permission", "permissionCode:" + permissionCode);try {MyLog.e("permission", "checkSelfPermission:" + (ActivityCompat.checkSelfPermission(context, permissionCode) == PackageManager.PERMISSION_GRANTED));return ActivityCompat.checkSelfPermission(context, permissionCode) == PackageManager.PERMISSION_GRANTED;} catch (Exception e) {e.printStackTrace();return false;}}
但是部分手机机型无论权限是否开启都会返回PackageManager.PERMISSION_GRANTED,对这些机型要进行特殊处理,同样的方法也适用于6.0以下可以更改权限的机型
经检测有以下机型会始终返回PackageManager.PERMISSION_GRANTED,联想(lenovo),红米(xiaomi)、魅族(meizu)、锤子(smartisan)、vivo(vivo)、oppo(oppo)
1.判断手机系统版本是否为6.0以下,生产厂商是不是这几家
private static boolean isSpecialDevice() {MyLog.e("permission", "Build.BRAND:" + Build.BRAND);return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Build.BRAND.toLowerCase().equals("smartisan")|| Build.BRAND.toLowerCase().equals("xiaomi") || Build.BRAND.toLowerCase().equals("oppo") || Build.BRAND.toLowerCase().equals("vivo")|| Build.BRAND.toLowerCase().equals("lenovo") || Build.BRAND.toLowerCase().equals("meizu");}
2.对于符合1情况的手机特殊处理
(1)摄像头权限判断,通过打开相机的方式判断有无拍照权限,记得最终要释放资源
public static boolean checkCameraPermission(Context context) {try {if (isSpecialDevice()) {//通过尝试打开相机的方式判断有无拍照权限(在6.0以下使用拥有root权限的管理软件可以管理权限)boolean isCanUse = true;Camera mCamera = null;try {mCamera = Camera.open();Camera.Parameters mParameters = mCamera.getParameters();mCamera.setParameters(mParameters);} catch (Exception e) {isCanUse = false;} finally {if (mCamera != null) {try {mCamera.release();} catch (Exception e) {e.printStackTrace();isCanUse = false;} finally {return isCanUse;}} else {return false;}}} else {return hasPermission(context, Manifest.permission.CAMERA);}} catch (Exception e) {e.printStackTrace();return false;}}
(2)录音权限判断,通过能否开始录音判断有无录音权限,也是注意最终释放资源
public static boolean checkAudioPermission(Context context) {try {if (isSpecialDevice()) {// 音频获取源int audioSource = MediaRecorder.AudioSource.MIC;// 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025int sampleRateInHz = 44100;// 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道int channelConfig = AudioFormat.CHANNEL_IN_STEREO;// 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。int audioFormat = AudioFormat.ENCODING_PCM_16BIT;// 缓冲区字节大小int bufferSizeInBytes;boolean flag;bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);AudioRecord audioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);//开始录制音频try {// 防止某些手机崩溃,例如联想audioRecord.startRecording();} catch (IllegalStateException e) {e.printStackTrace();} finally {/*** 根据开始录音判断是否有录音权限*/if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING)flag = false;elseflag = true;audioRecord.stop();audioRecord.release();return flag;}} else {return hasPermission(context, Manifest.permission.RECORD_AUDIO);}} catch (Exception e) {e.printStackTrace();return false;}}
(3)存储权限判断,通过新建文件或者文件夹后判断新建文件或文件夹是否存在来判断,最后是否需要删除自行判定
public static boolean checkStoragePermission(Context context) {try {if (isSpecialDevice()) {String absolute_dir;absolute_dir = Environment.getExternalStorageDirectory().toString() + "/temp/";File f = new File(absolute_dir);if (!f.exists()) f.mkdirs();if (f.exists()) return true;else return false;} else {return hasPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);}} catch (Exception e) {e.printStackTrace();return false;}}
用这种方法常用手机基本都能覆盖到,有问题留言讨论哈