在使用后台服务的情况下,android camera2预览表面
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在使用后台服务的情况下,android camera2预览表面相关的知识,希望对你有一定的参考价值。
tl; dr我有camera2api的活动和后台服务 - 不知道如何将“流”预览传递给活动视图。
我知道如何在Activity中进行相机预览。我创建了例如SurfaceView在活动布局中,并传递其表面(通过这种方式:)
Surface surface = surfaceViewFromLayout.getHolder().getSurface();
myCameraObjWhichHandlesCamera2API.open(surface);
(当然也有代码来设置合适的大小)
作为预览目标
CameraDevice.createCaptureSession(List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)
问题:但是如何在后台服务中使用工作捕获会话(对我来说仍然可行)并在屏幕打开时在Activity中显示预览?更多背景:我正在编写应用程序以进行计时 - 每次拍摄照片30秒。相机代码在后台服务中。我想有时打开屏幕并查找进度,并从相机中查看当前视图。
主要的是我有两个组件 - 带摄像头的Activity和Background Service,并且不知道如何通过当前的摄像头预览“stream”。
- 如果我可以将Surface对象从Activity布局传递给后台服务组件,那么如果Activity通过关闭屏幕被破坏怎么办 - Surface也可能被破坏,因此也会捕获会话。
编辑:但据我所知,不可能在组件之间传递对象 - 除了parcelable / serializable,但Surface是更复杂的对象?
- 不要将布局的表面传递给后台服务相机,而是在后台服务中创建虚拟表面(下面的代码) - 但是如何在组件之间传递“流”,将Activity中的SurfaceView设置为。
SurfaceTexture dummySurface = new SurfaceTexture(10);
dummySurface.setDefaultBufferSize(choosenSize.getWidth(), choosenSize.getHeight());
Surface previewSurface = new Surface(dummySurface);
// then when creating request, pass this:
cameraDevice.createCaptureSession(Arrays.asList(previewSurface, imageReader.getSurface(), stateCallback, null);
您可以考虑一些选项。请注意,我还没有尝试构建其中任何一个,所以可能还有其他我没有想到的问题。
- 每当您的Activity进入前台时,请将Surface从SurfaceView(一旦创建)传递到您的服务。然后,服务将需要通过创建新的捕获会话来重新配置相机设备以包括新的Surface。这会导致相机输出出现短暂的故障,但是因为你正在进行游戏中时光倒流,所以这并不重要。表面可以通过Binder进行跨过程发送就好了。当您的Activity进入后台以从捕获请求中删除SurfaceView Surface时,您还必须通知服务。您可以再次重新配置以获得静态捕获输出,但您可以将会话保持不变,并且不要在捕获请求中包含SurfaceView Surface。
- 在Activity中使用SurfaceTexture,使用自定义GLSurfaceView进行绘制。可以附加一个独立的SurfaceTexture,并从GL上下文中添加detached;当分离时,它仍然可以作为摄像头捕获请求的目标,缓冲区只是在ST附加到GL上下文并且在其上调用updateTexImage()之前不会去任何地方。然后你的GLSurfaceView需要将SurfaceTexture纹理绘制成全屏四边形。这基本上是您自己的小型TextureView,但可以更好地控制生命周期。从SurfaceTexture创建一个Surface,并将其传递给您的服务;然后,它可以只创建一个捕获会话,但如果它与您的服务不同,您可能仍需要担心活动过程被拆除。
以上是关于在使用后台服务的情况下,android camera2预览表面的主要内容,如果未能解决你的问题,请参考以下文章
在不增加会话数的情况下跟踪 Android 中的后台事件的好方法是啥?