首页 > 解决方案 > 尝试使用 Camera2 api 时未执行 StateCallback

问题描述

我正在尝试使用 Android Camera2 api 创建预览,但是我的代码不执行 cameraCaptureSession.StateCallback。我的代码通过 cameraDevice.createCaptureSession(camConfig) 执行。执行此操作后,它应该执行 StateCallback 但是据我所知它没有。我想知道是否有人知道为什么这个回调没有执行?以及如何解决它。

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import android.util.Log;
import android.util.Size;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import com.example.atlas2.R;
import com.example.atlas2.Util.BackgroundThreadFactory;

import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT;
import static android.hardware.camera2.params.SessionConfiguration.SESSION_REGULAR;

public class ProfilePhotoFragment extends Fragment implements SurfaceHolder.Callback2, ThreadFactory 
{

    Button capture;
    CameraManager cameraManager;
    String[] cameraIDs;
    String frontCamera;
    String cameraId;
    SurfaceView camPreview;
    SurfaceHolder camHolder;
    Size surfaceSize;
    CameraDevice cameraDevice;
    SessionConfiguration camConfig;
    CameraCaptureSession cameraCaptureSessions;
    CaptureRequest.Builder captureRequestBuilder;

    CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {

        @Override
        public void onOpened(@NonNull CameraDevice camera) {

            cameraDevice = camera;
            previewSetUp();

        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {

        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {

        }

    };

    public ProfilePhotoFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

        View profilePhotoView = inflater.inflate(R.layout.fragment_profile_photo, container, false);

        cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
        try {
            cameraIDs = cameraManager.getCameraIdList();
            Log.v("cameraIDs", cameraIDs[1]);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        camPreview = profilePhotoView.findViewById(R.id.camOutput);
        camHolder = camPreview.getHolder();

        openCamera();

        capture = profilePhotoView.findViewById(R.id.capture);
        capture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


            }
        });

        // Inflate the layout for this fragment
        return profilePhotoView;

    }

    public void openCamera() {

        chooseCamera();
        String frontFacing = frontCamera;

        try {
            cameraManager.openCamera(frontFacing, stateCallback, null); //permissions taken care of 
                                                                          in ProfilePhotoActivity
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    public void chooseCamera() {

        //find front facing camera through getCameraCharacteristics(cameraId)

        for(int i = 0; i < cameraIDs.length; i++) {

            try {

if(cameraManager.getCameraCharacteristics(cameraIDs[1]).get(CameraCharacteristics.LENS_FACING) == 
LENS_FACING_FRONT) {

                    frontCamera = cameraIDs[i];
                    Log.v("frontfacing", frontCamera);
                    cameraId = cameraIDs[i];

                    break;

                }
            } catch (CameraAccessException e) {
            e.printStackTrace();
            }

        }

    }

    @Override
    public void surfaceRedrawNeeded(SurfaceHolder holder) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r);
    }

    public void previewSetUp() {

        CameraCharacteristics characteristics = null;
        try {
            characteristics = cameraManager.getCameraCharacteristics(cameraId);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        StreamConfigurationMap map = 
        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        assert map != null;
        surfaceSize = map.getOutputSizes(SurfaceHolder.class)[0];
        camHolder.setFixedSize(surfaceSize.getWidth(), surfaceSize.getHeight());
        Surface surface = camHolder.getSurface();

        try {
            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        captureRequestBuilder.addTarget(surface);

        OutputConfiguration outputConfig = new OutputConfiguration(surface);
        Log.v("outputconfig", outputConfig.toString());
        ExecutorService executor = Executors.newFixedThreadPool(2, new BackgroundThreadFactory());
        Log.v("executor", executor.toString());
        camConfig = new SessionConfiguration(SESSION_REGULAR, Arrays.asList(outputConfig), executor, 
                                             new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraCaptureSession session) {

                cameraCaptureSessions = session;
                Log.v("onConfigured", "onconfigured");
                updatePreview();

            }

            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                Log.v("onConfiguredFailed", session.toString());
                Toast.makeText(getContext(), "Changed", Toast.LENGTH_SHORT).show();

            }
        });

        String supported = cameraDevice.getId();

        try {
            cameraDevice.createCaptureSession(camConfig);
            Log.v("createCaptureSession", supported);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    public void updatePreview() {

        Log.v("createCaptureSession2", String.valueOf(cameraCaptureSessions));
        if(cameraDevice == null)
            Toast.makeText(getContext(), "Error", Toast.LENGTH_SHORT).show();

        Log.v("createCaptureSession1", String.valueOf(cameraCaptureSessions));
        captureRequestBuilder.set(CaptureRequest.CONTROL_MODE,CaptureRequest.CONTROL_MODE_AUTO);
        captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, 
                                  CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

        try{

            Log.v("createCaptureSession", String.valueOf(cameraCaptureSessions));
            cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, null);

        }catch (CameraAccessException e) {

            e.printStackTrace();

        }

    }

    /**@Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }**/

    public void switchCameras() {

        //start a new cameracapturesession; this will stop the pre-existing one

    }

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

    }

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

        //executor.shutdown(); //executor in previewSetUp needs to be global

    }

}

标签: javaandroidsurfaceviewandroid-camera2

解决方案


推荐阅读