Android-usbCamera移植步骤
1,导入libusbcamera (库模块),统一sdk版本号。
在工程project的gradle添加该仓库地址:
maven { url 'http://raw.github.com/saki4510t/libcommon/master/repository/' }
和构建脚本
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
2,作者把usb 监听封装到了自己的单例类 UVCCameraHelper
private UVCCameraHelper mCameraHelper;
private CameraViewInterface mUVCCameraView;
首先初始化这个类,和初始化摄像头渲染器UVCCameraView
// step.1 initialize UVCCameraHelper
mUVCCameraView = (CameraViewInterface) mTextureView;
mUVCCameraView.setCallback(this);
mCameraHelper = UVCCameraHelper.getInstance();
mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_MJPEG);
mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener);
//设置预览帧回调
mCameraHelper.setOnPreviewFrameListener(new AbstractUVCCameraHandler.OnPreViewResultListener() {
@Override
public void onPreviewResult(byte[] nv21Yuv) {
Log.d(TAG, "onPreviewResult: "+nv21Yuv.length);
}
});
//Oncreate外
private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() {} ;
分析:
1,mUVCCameraView = (CameraViewInterface) mTextureView;
mUVCCameraView.setCallback(this);
在布局添加usbcamera的看图渲染器 <com.serenegiant.usb.widget.UVCCameraTextureView ,绑定控件,并设置回调this。 需要父类实现这个回调接口和接口方法。 CameraViewInterface.Callback
CameraViewInterface.Callback的3个接口方法:
@Override // xml的渲染器创建时候,如果渲染器第一次创建,没激活预览标志且 usb摄像头已经准备好,那就开始预览
public void onSurfaceCreated(CameraViewInterface view, Surface surface) {
if (!isPreview && mCameraHelper.isCameraOpened()) {
mCameraHelper.startPreview(mUVCCameraView);
isPreview = true;
}
}
public void onSurfaceChanged // 这个一般不写
@Override // 销毁渲染器时候,如果正在预览 和usb设备在打开 ,停止预览
public void onSurfaceDestroy(CameraViewInterface view, Surface surface) {
if (isPreview && mCameraHelper.isCameraOpened()) {
mCameraHelper.stopPreview();
isPreview = false;
}
}
2,初始化mCameraHelper 这个类,设置输入格式和 插进usb设备监听,把渲染器和usb设备连接监听传给它。
这样就可以检测到设备usb插入了。
在oncreate外 新建usb设备连接监听。在里面实现usb设备插入,拔出,连接各个状态的方法。
private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() {} ;
3,在 onstart 和 onstop注册卸载 usb监听类registerUSB();,在ondestroy 释放这个mCameraHelper类。
@Override
protected void onStart() {
super.onStart();
// step.2 register USB event broadcast
if (mCameraHelper != null) {
mCameraHelper.registerUSB();
}
}
@Override
protected void onStop() {
super.onStop();
// step.3 unregister USB event broadcast
if (mCameraHelper != null) {
mCameraHelper.unregisterUSB();
}
}
// step.4 release uvc camera resources
@Override
protected void onDestroy() {
super.onDestroy();
if (mCameraHelper != null) {
mCameraHelper.release();
}
问题一: 移植步骤出现空指针:
Attempt to invoke interface on a null object reference
可能是我用自带的绑定了这个控件,
@BindView(R.id.camera_view)
public View mTextureView;
后面改用mTextureView = findViewById(R.id.camera_view);
问题二:
插进usb没反应,原来是获取usb设备列表时候,把信息要存放到手机卡指定目录。
由于手机没这个文件夹,获取不了设备信息。(paxel也没有创建文件夹的能力)
public List<UsbDevice> getDeviceList(final List<DeviceFilter> filters)
如果不存在这个文件夹,那就创建。 但是用这个方法不能创建。所以就没这个文件夹。
也有可能手机没给读写权限。
解决方法:
后面新建文件夹,再新建文件。
String fileName = "/failed_devices.txt";
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/USBCamera/");/
//根目录新建一个文件夹
if (!file.exists())
file.mkdirs(); //m目录不存在,则新建目录。
File logFile =new File(file, fileName);
if(! logFile.exists()) {
问题三:偶尔出现
setDefaultFrameFormat should be call before initMonitor
问题四;
有时候退出进来闪退
java.lang.IllegalStateException: The specified message queue synchronization barrier token has not been posted or has already been removed.
消息队列问题。
使用gosky 原来已经有ijkview了,自己再添加一个显示view 后的层叠顺序问题。
解决,用帧布局,最后个添加的总是在最上面。或者用这个函数XXview.bringToFront()把它提到上面。
有些摄像头用不了,原来是分辨率不对。不设置的话初始分辨率是800X600,可以在
mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_MJPEG);
后面设置预览分辨率。
mCameraHelper.setDefaultPreviewSize(1280,720);
这个分辨率,小米6完美全屏,但是PEXAL由于有虚拟按键,不能全屏。
然后金立5.1 不能用,原来我用all64debug 来调式。 这个应该是32位的。
待解决!!!
mCameraHelper封装一些接口给开发者用,如设置分辨率,拍照录像。获取设备列表。等等。