I am trying to use the Android Camera2 api to create a preview, however my code does not execute the cameraCaptureSession.StateCallback. My code executes through cameraDevice.createCaptureSession(camConfig). Upon executing this, it should execute the StateCallback however from what I can tell it does not. I was wondering if anyone knows why this callback did not executed? And how to fix it.
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
}
}