在使用后台服务

时间:2017-07-19 15:29:38

标签: android camera preview surface android-camera2

tl; dr 我有camera2api的活动和后台服务 - 不知道如何通过" stream"预览到活动视图。

我知道如何在Activity中进行相机预览。我创建了例如SurfaceView在活动布局中,并传递其表面(通过这种方式:)

Surface surface = surfaceViewFromLayout.getHolder().getSurface();
myCameraObjWhichHandlesCamera2API.open(surface);

(当然还有设置适当大小的代码)

作为

的预览目标
CameraDevice.createCaptureSession(List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)

问题:但是如何在后台服务中使用工作捕获会话(对我来说仍然可行)并在屏幕打开时在Activity中显示预览?更多背景:我正在编写应用程序以进行计时 - 每次拍摄照片30秒。相机代码在后台服务中。我希望有时打开屏幕并查找进度,并从相机中查看当前视图。

主要的是我有两个组件 - 带摄像头的活动和后台服务,并且不知道如何通过当前的摄像头预览&#34;流&#34;。

  1. 如果我可以将Surface对象从Activity布局传递给后台服务组件,那么如果Activity通过关闭屏幕被破坏怎么办 - Surface也可能被破坏,因此也会捕获会话。
  2. 编辑但据我所知,在组件之间传递对象是不可能的 - 除了parcelable / serializable,但Surface是更复杂的对象?

    1. 不要将布局的表面传递给后台服务相机,但在后台服务中创建虚拟表面(代码) - 但如何传递&#34; stream&# 34;在组件之间,将Activity中的SurfaceView设置为。
    2. 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);

1 个答案:

答案 0 :(得分:1)

您可以考虑一些选项。请注意,我还没有尝试构建其中任何一个,所以我可能还没有考虑到其他问题。

  1. 每当您的Activity进入前台时,请将Surface从SurfaceView(一旦创建)传递到您的服务。然后,服务将需要通过创建新的捕获会话来重新配置相机设备以包括新的Surface。这会导致相机输出出现短暂的故障,但由于您正在进行游戏中时光倒流,因此它并不重要。表面可以通过Binder进行跨过程发送就好了。当您的活动进入后台以从捕获请求中删除SurfaceView Surface时,您还必须通知服务。您可以再次重新配置以获得静态捕获输出,但您可以保持会话相同,而不是在捕获请求中包含SurfaceView Surface。

  2. 在Activity中使用SurfaceTexture,使用自定义GLSurfaceView进行绘制。可以附加一个独立的SurfaceTexture,并从GL上下文中detached;当分离时,它仍然可以作为摄像头捕获请求的目标,缓冲区不会去任何地方,直到ST附加到GL上下文并且在其上调用updateTexImage()。然后你的GLSurfaceView需要将SurfaceTexture纹理绘制成全屏四边形。这基本上是您自己的小型TextureView,但可以更好地控制生命周期。从SurfaceTexture创建一个Surface,并将其传递给您的服务;然后它可以只创建一个捕获会话,但如果它与您的服务不同,您可能仍需要担心活动过程被拆除。