StateCallback не выполняется при попытке использовать API Camera2 - PullRequest
0 голосов
/ 29 февраля 2020

Я пытаюсь использовать 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

    }

}
...