赞
踩
最近接到了公司的需求,因为公司设备是通过android 8.0源码自己编译全量包,安装到自己机器中,所以需要把android 调用camera 标准api 全部限制住,禁止第三方app可以使用设备的摄像头,只能通过我们自己的sdk才允许使用。
最开始想通过 修改AndroidManifest.xml 中的
<uses-permission android:name="android.permission.CAMERA" />
相机权限来限制,当时通过全文替换来修改相机权限名字,当镜像文件编译完成后,虽然像系统相机的确无法正常使用了,但是其他app在清单文件中设置新的权限名字,出现了两个问题:
1:这种所谓的自定义权限无法传递到源码中camera.java 他获取不到(这里有大神知道吗 可以参与讨论一下)
2:一但自定义权限名字泄漏出去,第三方app还是可以继续使用摄像头
那么这样肯定是不行的。所以我把目光放到了8.0源码中 android.hardware.Camera.java (在这里我们都知道 调用相机的方式 目前谷歌提供了几种方式 camera camera2 cameraX 这里我们只拿camera 举例子 如果大家有需要以后会继续更新)
好了接下来我们来看camera源码 有两个地方需要大家注意一下 当我们使用camera初始化的时候 是调用
Camera.open(cameraId);
进行初始化的
但是系统相机初始化是走的
- public static Camera openLegacy(int cameraId, int halVersion) {
- if (halVersion < CAMERA_HAL_API_VERSION_1_0) {
- throw new IllegalArgumentException("Invalid HAL version " + halVersion);
- }
-
- return new Camera(cameraId, halVersion);
- }
这里的代码
现在有两种选择 你可以直接在构造方法直接加入一个限制开关 , 也可以在绑定Surface的代码与获取yuv 回调的时候限制
第一种直接在构造方法限制,不过这样如果是未授权app 获取camera对象直接就返回的null 这样会造成其他app直接发生 空指针异常,非常不友好
第二种在 绑定Surface的代码与获取yuv 回调的时候限制 这种方式比较麻烦,但是不会引发空指针异常与意外闪退方式
这里我们使用第二种方式,这里我们先介绍在源码中限制的方法都有哪些
- public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
- if (holder != null) {
- setPreviewSurface(holder.getSurface());
- } else {
- setPreviewSurface((Surface)null);
- }
- }
public native final void setPreviewTexture(SurfaceTexture surfaceTexture) throws IOException;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。