java - 尝试使用 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
}
}
解决方案
推荐阅读
- c# - 调用 .StartRecording() 时出现 NAudio UnspecifiedError
- asp.net-mvc - Axios Filter 表返回计数但不返回数据
- php - filemtime 在 php 中返回垃圾值
- c# - 如何使用下拉列表过滤 Razor 视图中的数据
- c# - Visual Studio for Mac 上的奇怪 linq 异常
- bash - 我想将 ls 的输出重定向到一个文件,并将一个常量字符串附加到输出文件中列出的每个文件
- python - 为什么我没有足够的值来解压缩某些图像(预期为 2,得到 1)?
- api - 使用 Google 脚本在列中列出工作表 ID
- python - Django查询集到一个字符串
- python-3.x - 将从 S3 绘制的 PDF 和 PPTX 文件转换为 JPG 格式