当我们使用手机相机的时候,通常就会想到先获取手机相机权限,也就是运行时权限。
也就是类似下面方法
/**
* 申请相机权限
*/
private void startRequestPermission(){
//321为请求码
ActivityCompat.requestPermissions(this,PERMISSIONS_STORAGE,321);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==CODE_CAMERA_REQUEST&&resultCode==RESULT_OK){
//TODO
}
}
但是对于Android 6.0以下的手机,都是默认拥有这个权限的,但如果将手机权限关闭掉,同样在代码上还是返回true,针对这个问题,可以通过try{}catch()的方式,也就是通过代码去使用相机,然后捕获异常,如果相机权限没有,就会走到你的异常处理里面,也就是说没有这个权限,也可以看看下面方式。
/**
* 摄像头是否可用
*/
public static boolean isCameraUseable() {
Camera mCamera = null;
try {
mCamera = Camera.open();
// setParameters 是针对魅族MX5。MX5通过Camera.open()拿到的Camera对象不为null
Camera.Parameters mParameters = mCamera.getParameters();
mCamera.setParameters(mParameters);
} catch (Exception e) {
return false;
} finally {
if (mCamera != null) {
try {
mCamera.release();
Thread.sleep(100);
} catch (Exception e) {
return false;
}
}
}
return true;
}
这样的话就基本处理了大部分手机,但是最近碰到一个vivo的手机,camera权限拒绝,但是这个判断摄像头是否可用返回的true,也就是进入到surfaceView渲染就一团黑,这时瞬间尴尬,感觉这个手机就像是华强北组装回来一样,但是问题肯定有解决方式,后来debug时候就看到一个Cmaera类。
不知发现了没有,这个里面有个叫做mHasPermission的变量,刚好还是false,然后我重新debug,去同意使用相机,然后就发现这个值变为true,这就让我想到了方式,去使用这个Camera去点看有没有成员变量叫做mHasPermission的,突然发现并没有,去这个源码里面看,也没有发现,就感觉马上要解决的问题感觉好像又遇到问题了。这个就不要紧了啊。这就想到了通过反射去获取成员变量,我使用的是getDeclaredField()这个方法。这样就可以找到这个值了,没错,下面就来看看具体实现了:
private boolean isHasPermission(Camera camera){
try {
Field fieldPassword = camera.getClass().getDeclaredField("mHasPermission");
fieldPassword.setAccessible(true);
return (boolean)fieldPassword.get(camera);
} catch (Exception e) {
return true;
}
}
就这样返回了mHasPermission的value了,经过测试,完美处理了Android 6以下某些手机不能获取到camera被拒绝的监听了。