PreviewView 中未显示 CameraX Preview

CameraX Preview not showing in PreviewView

我已按照此处的说明使用 CameraX 实现 PreviewView (https://developer.android.com/training/camerax/preview)。我还下载了示例代码,效果很好。但在我的代码中它只是不会显示预览。日志看起来很好,它正在做一些事情,因为我将预览视图的背景颜色设置为绿色,如果我启动预览逻辑,它就会被清除。 我在带有 TabLayout 的 ViewPager 中使用它,如果有任何不同的话。

Layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.camera.view.PreviewView
            android:id="@+id/preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

片段

public class QRFragment extends Fragment {
    public static final String TAG = QRFragment.class.getSimpleName();
    private static final int REQUEST_PERMISSION_CAMERA = 777;

    public static Fragment newInstance() {
        return new QRFragment();
    }

    private GuideQrFragmentBinding binding;
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.v(TAG, "create view");
        this.binding = GuideQrFragmentBinding.inflate(inflater, container, false);
        // binding.setViewModel(this.mViewModel);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.v(TAG, "view created");
    }

    private void startPreview() {
        Log.v(TAG, "startPreview");
        this.cameraProviderFuture = ProcessCameraProvider.getInstance(this.requireContext());
        this.cameraProviderFuture.addListener(() -> {
            Log.v(TAG, "cameraProviderFuture.Listener");
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

                Preview preview = new Preview.Builder()
                        .build();

                CameraSelector cameraSelector = new CameraSelector.Builder()
                        .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                        .build();

                cameraProvider.unbindAll();
                Camera camera = cameraProvider.bindToLifecycle(this.getViewLifecycleOwner(),
                        cameraSelector,
                        preview);

                preview.setSurfaceProvider(this.binding.preview.getSurfaceProvider());

            } catch (ExecutionException | InterruptedException e) {
                // No errors need to be handled for this Future.
                // This should never be reached.
                Log.e(TAG, "cameraProviderFuture.Listener", e);
            }
        }, ContextCompat.getMainExecutor(this.requireContext()));
    }

    @Override
    public void onResume() {
        super.onResume();

        if( ActivityCompat.checkSelfPermission(this.requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED ) {
            if( this.cameraProviderFuture == null ) {
                this.startPreview();
            }
        } else {
            this.requestPermissions(new String[] { Manifest.permission.CAMERA }, REQUEST_PERMISSION_CAMERA);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if( requestCode == REQUEST_PERMISSION_CAMERA ) {
            for( int p = 0; p < permissions.length; p++ ) {
                if( Manifest.permission.CAMERA.equals(permissions[p]) ) {
                    if( grantResults[p] == PackageManager.PERMISSION_GRANTED ) {
                        this.startPreview();
                    } else {

                    }
                }
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

日志

2021-02-01 13:05:18.920 4217-4217/com.myapp.app V/QRFragment: create view
2021-02-01 13:05:18.936 4217-4217/com.myapp.app V/QRFragment: view created
2021-02-01 13:05:18.953 4217-4217/com.myapp.app V/QRFragment: startPreview
2021-02-01 13:05:18.982 4217-4782/com.myapp.app I/CameraManagerGlobal: Connecting to camera service
2021-02-01 13:05:18.985 4217-4782/com.myapp.app D/VendorTagDescriptor: addVendorDescriptor: vendor tag id 3854507339 added
2021-02-01 13:05:18.988 4217-4257/com.myapp.app I/CameraManagerGlobal: Camera 0 facing CAMERA_FACING_BACK state now CAMERA_STATE_CLOSED for client com.myapp.app API Level 2
2021-02-01 13:05:18.989 4217-4257/com.myapp.app I/CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.samsung.adaptivebrightnessgo API Level 2
2021-02-01 13:05:18.990 4217-4257/com.myapp.app I/CameraManagerGlobal: Camera 2 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client android.system API Level 2
2021-02-01 13:05:18.990 4217-4257/com.myapp.app I/CameraManagerGlobal: Camera 50 facing CAMERA_FACING_BACK state now CAMERA_STATE_CLOSED for client android.system API Level 2
2021-02-01 13:05:19.046 4217-4782/com.myapp.app D/CameraRepository: Added camera: 0
2021-02-01 13:05:19.099 4217-4782/com.myapp.app I/Camera2CameraInfo: Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
2021-02-01 13:05:19.101 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 0 status STATUS_PRESENT
2021-02-01 13:05:19.101 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 1 status STATUS_PRESENT
2021-02-01 13:05:19.102 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 2 status STATUS_PRESENT
2021-02-01 13:05:19.102 4217-4782/com.myapp.app D/CameraRepository: Added camera: 1
2021-02-01 13:05:19.102 4217-4802/com.myapp.app D/UseCaseAttachState: Active and attached use case: [] for camera: 0
2021-02-01 13:05:19.104 4217-4782/com.myapp.app I/Camera2CameraInfo: Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
2021-02-01 13:05:19.104 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 0 status STATUS_PRESENT
2021-02-01 13:05:19.105 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 1 status STATUS_PRESENT
2021-02-01 13:05:19.105 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 2 status STATUS_PRESENT
2021-02-01 13:05:19.105 4217-4782/com.myapp.app D/CameraRepository: Added camera: 2
2021-02-01 13:05:19.105 4217-4803/com.myapp.app D/UseCaseAttachState: Active and attached use case: [] for camera: 1
2021-02-01 13:05:19.107 4217-4782/com.myapp.app I/Camera2CameraInfo: Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
2021-02-01 13:05:19.108 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 0 status STATUS_PRESENT
2021-02-01 13:05:19.108 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 1 status STATUS_PRESENT
2021-02-01 13:05:19.108 4217-4802/com.myapp.app D/UseCaseAttachState: Active and attached use case: [] for camera: 2
2021-02-01 13:05:19.108 4217-4782/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 2 status STATUS_PRESENT
2021-02-01 13:05:19.110 4217-4217/com.myapp.app V/QRFragment: cameraProviderFuture.Listener
2021-02-01 13:05:19.149 4217-4217/com.myapp.app D/DeferrableSurface: Surface created[total_surfaces=1, used_surfaces=0](androidx.camera.core.SurfaceRequest@f584149}
2021-02-01 13:05:19.153 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Use case Preview:androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983 INACTIVE
2021-02-01 13:05:19.154 4217-4217/com.myapp.app D/CameraOrientationUtil: getRelativeImageRotation: destRotationDegrees=0, sourceRotationDegrees=90, isOppositeFacing=true, result=90
2021-02-01 13:05:19.154 4217-4803/com.myapp.app D/UseCaseAttachState: Active and attached use case: [] for camera: 0
2021-02-01 13:05:19.155 4217-4217/com.myapp.app D/PreviewView: Surface requested by Preview.
2021-02-01 13:05:19.156 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Use cases [Preview:androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983] now ATTACHED
2021-02-01 13:05:19.158 4217-4803/com.myapp.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983163463287] for camera: 0
2021-02-01 13:05:19.159 4217-4803/com.myapp.app D/UseCaseAttachState: Active and attached use case: [] for camera: 0
2021-02-01 13:05:19.160 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Resetting Capture Session
2021-02-01 13:05:19.162 4217-4217/com.myapp.app D/SurfaceView: onWindowVisibilityChanged(0) true android.view.SurfaceView{9f7ad5a V.E...... ......ID 0,0-0,0} of ViewRootImpl@581aad2[MainActivity]
2021-02-01 13:05:19.162 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Releasing session in state INITIALIZED
2021-02-01 13:05:19.163 4217-4217/com.myapp.app D/PreviewView: Preview transformation info updated. TransformationInfo{cropRect=Rect(0, 0 - 1440, 1080), rotationDegrees=90, targetRotation=0}
2021-02-01 13:05:19.163 4217-4217/com.myapp.app D/PreviewTransform: Transformation info set: TransformationInfo{cropRect=Rect(0, 0 - 1440, 1080), rotationDegrees=90, targetRotation=0} 1440x1080 false
2021-02-01 13:05:19.165 4217-4803/com.myapp.app D/CameraStateRegistry: tryOpenCamera(Camera@ea5acee[id=0]) [Available Cameras: 1, Already Open: false (Previous state: null)] --> SUCCESS
2021-02-01 13:05:19.169 4217-4803/com.myapp.app D/CameraStateRegistry: Recalculating open cameras:
    Camera                                       State                 
    -------------------------------------------------------------------
    Camera@163f523[id=2]                         UNKNOWN               
    Camera@640eda1[id=1]                         UNKNOWN               
    Camera@ea5acee[id=0]                         OPENING               
    -------------------------------------------------------------------
    Open count: 1 (Max allowed: 1)
2021-02-01 13:05:19.171 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Transitioning camera internal state: INITIALIZED --> OPENING
2021-02-01 13:05:19.173 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Opening camera.
2021-02-01 13:05:19.175 4217-4803/com.myapp.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983163463287] for camera: 0
2021-02-01 13:05:19.187 4217-4217/com.myapp.app D/ViewRootImpl@581aad2[MainActivity]: Relayout returned: old=(0,0,1080,2340) new=(0,0,1080,2340) req=(1080,2340)0 dur=9 res=0x1 s={true 498507776000} ch=false
2021-02-01 13:05:19.201 4217-4217/com.myapp.app D/SurfaceView: surfaceCreated 1 #8 android.view.SurfaceView{9f7ad5a V.E...... ......ID 0,0-1440,1080}
2021-02-01 13:05:19.201 4217-4217/com.myapp.app D/SurfaceViewImpl: Surface created.
2021-02-01 13:05:19.201 4217-4217/com.myapp.app D/SurfaceView: surfaceChanged (1440,1080) 1 #8 android.view.SurfaceView{9f7ad5a V.E...... ......ID 0,0-1440,1080}
2021-02-01 13:05:19.202 4217-4217/com.myapp.app D/SurfaceViewImpl: Surface changed. Size: 1440x1080
2021-02-01 13:05:19.207 4217-4217/com.myapp.app D/SurfaceViewImpl: Surface set on Preview.
2021-02-01 13:05:19.411 4217-4257/com.myapp.app I/CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client com.samsung.adaptivebrightnessgo API Level 2
2021-02-01 13:05:19.422 4217-4257/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 0 status STATUS_NOT_AVAILABLE
2021-02-01 13:05:19.423 4217-4257/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 0 status STATUS_NOT_AVAILABLE
2021-02-01 13:05:19.425 4217-4257/com.myapp.app I/CameraManagerGlobal: postSingleUpdate device: camera id 0 status STATUS_NOT_AVAILABLE
2021-02-01 13:05:19.428 4217-4257/com.myapp.app I/CameraManagerGlobal: Camera 0 facing CAMERA_FACING_BACK state now CAMERA_STATE_OPEN for client com.myapp.app API Level 2
2021-02-01 13:05:19.452 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Use case Preview:androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983 INACTIVE
2021-02-01 13:05:19.455 4217-4803/com.myapp.app D/UseCaseAttachState: Active and attached use case: [] for camera: 0
2021-02-01 13:05:19.458 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Use case Preview:androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983 ACTIVE
2021-02-01 13:05:19.460 4217-4803/com.myapp.app D/UseCaseAttachState: Active and attached use case: [androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983163463287] for camera: 0
2021-02-01 13:05:19.470 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} CameraDevice.onOpened()
2021-02-01 13:05:19.476 4217-4803/com.myapp.app D/Camera2CameraImpl: {Camera@ea5acee[id=0]} Transitioning camera internal state: OPENING --> OPENED
2021-02-01 13:05:19.481 4217-4803/com.myapp.app D/CameraStateRegistry: Recalculating open cameras:
    Camera                                       State                 
    -------------------------------------------------------------------
    Camera@163f523[id=2]                         UNKNOWN               
    Camera@640eda1[id=1]                         UNKNOWN               
    Camera@ea5acee[id=0]                         OPEN                  
    -------------------------------------------------------------------
    Open count: 1 (Max allowed: 1)
2021-02-01 13:05:19.483 4217-4803/com.myapp.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983163463287] for camera: 0
2021-02-01 13:05:19.497 4217-4803/com.myapp.app D/UseCaseAttachState: Active and attached use case: [androidx.camera.core.Preview-ece4a019-fe39-4341-ab30-82f47580d983163463287] for camera: 0
2021-02-01 13:05:19.505 4217-4803/com.myapp.app D/SyncCaptureSessionBase: [androidx.camera.camera2.internal.SynchronizedCaptureSessionBaseImpl@e53a798] getSurface...done
2021-02-01 13:05:19.506 4217-4803/com.myapp.app D/DeferrableSurface: New surface in use[total_surfaces=1, used_surfaces=1](androidx.camera.core.SurfaceRequest@f584149}
2021-02-01 13:05:19.507 4217-4803/com.myapp.app D/DeferrableSurface: use count+1, useCount=1 androidx.camera.core.SurfaceRequest@f584149
2021-02-01 13:05:19.507 4217-4803/com.myapp.app D/CaptureSession: Opening capture session.
2021-02-01 13:05:19.646 4217-4803/com.myapp.app D/CaptureSession: Attempting to send capture request onConfigured
2021-02-01 13:05:19.646 4217-4803/com.myapp.app D/CaptureSession: Issuing request for session.
2021-02-01 13:05:19.666 4217-4803/com.myapp.app D/CaptureSession: CameraCaptureSession.onConfigured() mState=OPENED
2021-02-01 13:05:19.667 4217-4803/com.myapp.app D/CaptureSession: CameraCaptureSession.onReady() OPENED
2021-02-01 13:05:20.414 4217-4248/com.myapp.app I/CameraManagerGlobal: Camera 0 facing CAMERA_FACING_BACK state now CAMERA_STATE_ACTIVE for client com.myapp.app API Level 2
2021-02-01 13:05:20.448 4217-4803/com.myapp.app D/StreamStateObserver: Update Preview stream state to STREAMING

我发现了问题。我必须在预览视图上将实施模式设置为 COMPATIBLE。

this.binding.preview.setImplementationMode(PreviewView.ImplementationMode.COMPATIBLE);