Java 将Android CameraX桥接到React Native

Java 将Android CameraX桥接到React Native,java,react-native,androidx,android-camerax,react-native-native-ui-component,Java,React Native,Androidx,Android Camerax,React Native Native Ui Component,我正在为CameraX创建一个本机UI组件以响应本机。第一次尝试在活动中触发检查,效果良好。查看React Native的提取为UI视图。它只是显示一个空白的白色屏幕 相机预览未显示(视图样式的100%w和h在JS中定义) 下面是我的片段: 摄像机布局: <androidx.constraintlayout.widget.ConstraintLayout ...> <TextureView android:id="@+id/textureView"

我正在为CameraX创建一个本机UI组件以响应本机。第一次尝试在活动中触发检查,效果良好。查看React Native的提取为UI视图。它只是显示一个空白的白色屏幕

  • 相机预览未显示(视图样式的100%w和h在JS中定义)
下面是我的片段:

摄像机布局:

<androidx.constraintlayout.widget.ConstraintLayout ...>
    <TextureView android:id="@+id/textureView" ... />
</androidx.constraintlayout.widget.ConstraintLayout>
public void startCamera() {
        CameraX.unbindAll();
        
        Rational aspectRatio = new Rational(textureView.getWidth(), textureView.getHeight());
        Size screen = new Size(textureView.getWidth(), textureView.getHeight()); //size of the screen

        PreviewConfig pConfig = new PreviewConfig.Builder().setTargetAspectRatio(aspectRatio).setTargetResolution(screen).build();
        Preview preview = new Preview(pConfig);

        preview.setOnPreviewOutputUpdateListener(
                new Preview.OnPreviewOutputUpdateListener() {
                    @Override
                    public void onUpdated(Preview.PreviewOutput output) {
                        ViewGroup parent = (ViewGroup) textureView.getParent();
                        parent.removeView(textureView);
                        parent.addView(textureView, 0);

                        textureView.setSurfaceTexture(output.getSurfaceTexture());
                        updateTransform();
                    }
                });

        //bind to lifecycle:
        CameraX.bindToLifecycle((AppCompatActivity) mContext.getCurrentActivity(), preview);
    }
09-26 20:15:18.994 8156-8178/com.app D/Camera: Use cases [Preview:androidx.camera.core.Preview-e0193733-9ece-4c39-85e5-b93a6f2bf2e1] OFFLINE for camera 0
09-26 20:15:18.994 8156-8178/com.app D/Camera: Closing camera: 0
09-26 20:15:18.995 8156-8178/com.app I/RequestQueue: Repeating capture request cancelled.
09-26 20:15:19.174 8156-8168/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.174 8156-8169/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.174 8156-8191/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.174 8156-8168/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.175 8156-8169/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.175 8156-8191/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.208 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.209 8156-8178/com.app D/Camera: CameraDevice.onClosed(): 0
09-26 20:15:19.209 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.216 8156-8178/com.app D/Camera: Use cases [Preview:androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] ONLINE for camera 0
09-26 20:15:19.216 8156-8178/com.app D/Camera: Opening camera: 0
09-26 20:15:19.216 8156-8178/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.230 8156-8178/com.app I/CameraManager: Using legacy camera HAL.
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: Active and online use case: [] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.432 8156-8178/com.app D/Camera: CameraDevice is null
09-26 20:15:19.432 8156-8178/com.app D/Camera: Use case Preview:androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b ACTIVE for camera 0
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: Active and online use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/Camera: CameraDevice.onOpened(): 0
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.433 8156-8178/com.app D/CaptureSession: Opening capture session.
09-26 20:15:19.435 8156-8178/com.app I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
09-26 20:15:19.437 8156-9611/com.app I/RequestThread-0: Configure outputs: 1 surfaces configured.
09-26 20:15:19.437 8156-9611/com.app D/Camera: app passed NULL surface
09-26 20:15:19.465 8156-8178/com.app I/CameraDeviceState: Legacy camera service transitioning to state IDLE
09-26 20:15:19.466 8156-8178/com.app D/CaptureSession: Attempting to send capture request onConfigured
09-26 20:15:19.466 8156-8178/com.app D/CaptureSession: Issuing request for session.
09-26 20:15:19.468 8156-8178/com.app I/RequestQueue: Repeating capture request set.
09-26 20:15:19.468 8156-8178/com.app D/CaptureSession: CameraCaptureSession.onConfigured()
09-26 20:15:19.468 8156-8178/com.app D/CaptureSession: CameraCaptureSession.onReady()
09-26 20:15:19.468 8156-8178/com.app D/CaptureSession: CameraCaptureSession.onReady()
09-26 20:15:19.471 8156-9611/com.app W/LegacyRequestMapper: convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
09-26 20:15:19.471 8156-9611/com.app W/LegacyRequestMapper: Only received metering rectangles with weight 0.
09-26 20:15:19.471 8156-9611/com.app W/LegacyRequestMapper: Only received metering rectangles with weight 0.
09-26 20:15:19.675 8156-9612/com.app I/CameraDeviceState: Legacy camera service transitioning to state CAPTURING
09-26 20:18:22.352 8156-8167/com.app I/art: Background partial concurrent mark sweep GC freed 483777(15MB) AllocSpace objects, 0(0B) LOS objects, 35% free, 29MB/45MB, paused 1.554ms total 104.490ms
09-26 20:19:30.100 8156-8167/com.app I/art: Background sticky concurrent mark sweep GC freed 473262(15MB) AllocSpace objects, 0(0B) LOS objects, 34% free, 29MB/45MB, paused 771us total 166.198ms
09-26 20:20:35.488 8156-8167/com.app I/art: Background partial concurrent mark sweep GC freed 491511(15MB) AllocSpace objects, 0(0B) LOS objects, 35% free, 29MB/45MB, paused 968us total 100.951ms

启动CameraX功能:

<androidx.constraintlayout.widget.ConstraintLayout ...>
    <TextureView android:id="@+id/textureView" ... />
</androidx.constraintlayout.widget.ConstraintLayout>
public void startCamera() {
        CameraX.unbindAll();
        
        Rational aspectRatio = new Rational(textureView.getWidth(), textureView.getHeight());
        Size screen = new Size(textureView.getWidth(), textureView.getHeight()); //size of the screen

        PreviewConfig pConfig = new PreviewConfig.Builder().setTargetAspectRatio(aspectRatio).setTargetResolution(screen).build();
        Preview preview = new Preview(pConfig);

        preview.setOnPreviewOutputUpdateListener(
                new Preview.OnPreviewOutputUpdateListener() {
                    @Override
                    public void onUpdated(Preview.PreviewOutput output) {
                        ViewGroup parent = (ViewGroup) textureView.getParent();
                        parent.removeView(textureView);
                        parent.addView(textureView, 0);

                        textureView.setSurfaceTexture(output.getSurfaceTexture());
                        updateTransform();
                    }
                });

        //bind to lifecycle:
        CameraX.bindToLifecycle((AppCompatActivity) mContext.getCurrentActivity(), preview);
    }
09-26 20:15:18.994 8156-8178/com.app D/Camera: Use cases [Preview:androidx.camera.core.Preview-e0193733-9ece-4c39-85e5-b93a6f2bf2e1] OFFLINE for camera 0
09-26 20:15:18.994 8156-8178/com.app D/Camera: Closing camera: 0
09-26 20:15:18.995 8156-8178/com.app I/RequestQueue: Repeating capture request cancelled.
09-26 20:15:19.174 8156-8168/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.174 8156-8169/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.174 8156-8191/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.174 8156-8168/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.175 8156-8169/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.175 8156-8191/com.app E/BufferQueueProducer: [SurfaceTexture-1-8156-4] cancelBuffer: BufferQueue has been abandoned
09-26 20:15:19.208 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.209 8156-8178/com.app D/Camera: CameraDevice.onClosed(): 0
09-26 20:15:19.209 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.216 8156-8178/com.app D/Camera: Use cases [Preview:androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] ONLINE for camera 0
09-26 20:15:19.216 8156-8178/com.app D/Camera: Opening camera: 0
09-26 20:15:19.216 8156-8178/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.230 8156-8178/com.app I/CameraManager: Using legacy camera HAL.
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: Active and online use case: [] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.432 8156-8178/com.app D/Camera: CameraDevice is null
09-26 20:15:19.432 8156-8178/com.app D/Camera: Use case Preview:androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b ACTIVE for camera 0
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: Active and online use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/Camera: CameraDevice.onOpened(): 0
09-26 20:15:19.432 8156-8178/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-a29229b4-7347-4920-8407-d60e97ec229b] for camera: 0
09-26 20:15:19.432 8156-8178/com.app D/Camera: Closing Capture Session
09-26 20:15:19.433 8156-8178/com.app D/CaptureSession: Opening capture session.
09-26 20:15:19.435 8156-8178/com.app I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
09-26 20:15:19.437 8156-9611/com.app I/RequestThread-0: Configure outputs: 1 surfaces configured.
09-26 20:15:19.437 8156-9611/com.app D/Camera: app passed NULL surface
09-26 20:15:19.465 8156-8178/com.app I/CameraDeviceState: Legacy camera service transitioning to state IDLE
09-26 20:15:19.466 8156-8178/com.app D/CaptureSession: Attempting to send capture request onConfigured
09-26 20:15:19.466 8156-8178/com.app D/CaptureSession: Issuing request for session.
09-26 20:15:19.468 8156-8178/com.app I/RequestQueue: Repeating capture request set.
09-26 20:15:19.468 8156-8178/com.app D/CaptureSession: CameraCaptureSession.onConfigured()
09-26 20:15:19.468 8156-8178/com.app D/CaptureSession: CameraCaptureSession.onReady()
09-26 20:15:19.468 8156-8178/com.app D/CaptureSession: CameraCaptureSession.onReady()
09-26 20:15:19.471 8156-9611/com.app W/LegacyRequestMapper: convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
09-26 20:15:19.471 8156-9611/com.app W/LegacyRequestMapper: Only received metering rectangles with weight 0.
09-26 20:15:19.471 8156-9611/com.app W/LegacyRequestMapper: Only received metering rectangles with weight 0.
09-26 20:15:19.675 8156-9612/com.app I/CameraDeviceState: Legacy camera service transitioning to state CAPTURING
09-26 20:18:22.352 8156-8167/com.app I/art: Background partial concurrent mark sweep GC freed 483777(15MB) AllocSpace objects, 0(0B) LOS objects, 35% free, 29MB/45MB, paused 1.554ms total 104.490ms
09-26 20:19:30.100 8156-8167/com.app I/art: Background sticky concurrent mark sweep GC freed 473262(15MB) AllocSpace objects, 0(0B) LOS objects, 34% free, 29MB/45MB, paused 771us total 166.198ms
09-26 20:20:35.488 8156-8167/com.app I/art: Background partial concurrent mark sweep GC freed 491511(15MB) AllocSpace objects, 0(0B) LOS objects, 35% free, 29MB/45MB, paused 968us total 100.951ms

ReactViewManager:将当前活动从reactContext传递到视图实例

public class ReactCameraXManager extends SimpleViewManager<CameraXView> implements LifecycleEventListener {
   public static final String TAG = ReactContextBaseJavaModule.class.getSimpleName();
   public static final String REACT_CLASS = "CameraXView";
   private Activity mActivity;

   public ReactCameraXManager(ReactApplicationContext reactContext) {
       super();
       mActivity = reactContext.getCurrentActivity();
       reactContext.addLifecycleEventListener(this);
   }

   @Override
   public String getName() {
       return REACT_CLASS;
   }

   @Override
   public CameraXView createViewInstance(final ThemedReactContext context) {
       return new CameraXView(context);
   }

注意:我没有看到任何react本机包。因此计划创建一个新包。

我发现PreviewView没有添加到父级中(甚至
getChildCount
返回0)

在使用根目录附加布局后,它工作:

FrameLayout layout = (FrameLayout) LayoutInflater.from(context).inflate(R.layout.camera_layout, this, true);
与此相反:

FrameLayout layout = (FrameLayout) LayoutInflater.from(context).inflate(R.layout.camera_layout, null);

注意:性能不是很好。FPS在大多数设备上都太低。

您可以添加您使用的CameraX版本吗?调用“bindToLifecycle”时,您似乎也没有发送任何预览用例,请看这里:您使用的是一个相当旧的CameraX版本。SetOnPreviewOutUpdateListener自beta版以来将被弃用。请检查最新版本,看看它是否有效。另外,我建议您尝试新的PreviewView,它可以为您处理预览曲面。您能找到解决方案吗?@ARaj123分享了下面的解决方案。谢谢@Balasubramanian。我正在尝试做一些类似的事情,创建一个CameraX ui视图并将其连接到react native。您是否遵循了任何教程来实现上述代码?