我目前正在开发一款非常简单的小工具和Idea的相机应用程序,这是我迄今遇到的最大障碍,无法弄清楚如何调试此问题。我有制作简单应用程序的经验,但没有太多使用相机的经验。如果您能够识别错误或指出我正确的方向,我会非常满意,我的目标是学习我不知道该问题的去向。
以下是问题的堆栈跟踪:
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at com.example.tadewos.camera_seconditeration.Camera2VideoImageActivity$7.onClick(Camera2VideoImageActivity.java:312)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at android.view.View.performClick(View.java:5721)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at android.view.View$PerformClick.run(View.java:22624)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at android.os.Looper.loop(Looper.java:148)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7422)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at java.lang.reflect.Method.invoke(Native Method)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
[ 11-04 20:42:56.281 636:14652 E/ ]
Camera[ERROR] aec_process_update_exposure_params: 5310: aec_process_update_exposure_params:5310 [LLS] lc = 6593 gain = 23.828585
[ 11-04 20:42:56.281 636:14652 E/ ]
Camera[ERROR] aec_process_pack_output: 6695: aec_process_pack_output:6695 target_luma=35.000000, cur_luma=15.224384, exp_index=394, linecount=4396, sensor_gain=25.992517, aec_settled=1, iso=1000
[ 11-04 20:42:56.281 636:14652 E/ ]
Camera[ERROR] aec_process_pack_output: 6751: aec_process_pack_output:6751 ADRC: real_gain=25.992517, drc_gains=(-1.000000, -1.000000), drc_ratios=(-1.000000,-1.000000,-1.000000,-1.000000)
[ 11-04 20:42:56.281 636:14652 E/ ]
Camera[ERROR] awb_process_pack_output: 1146: awb_process_pack_output:1146 fire_for_snapshot:get_preflash_info:preflash_wb_fix[0:0:0]
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration E/MediaRecorder: start called in an invalid state: 4
11-04 20:42:56.281 14505-14505/com.example.tadewos.camera_seconditeration D/AndroidRuntime: Shutting down VM
11-04 20:42:56.291 14505-14505/com.example.tadewos.camera_seconditeration E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tadewos.camera_seconditeration, PID: 14505
java.lang.IllegalStateException
at android.media.MediaRecorder._start(Native Method)
at android.media.MediaRecorder.start(MediaRecorder.java:944)
at com.example.tadewos.camera_seconditeration.Camera2VideoImageActivity.checkWriteStoragePermission(Camera2VideoImageActivity.java:649)
at com.example.tadewos.camera_seconditeration.Camera2VideoImageActivity.access$1300(Camera2VideoImageActivity.java:55)
at com.example.tadewos.camera_seconditeration.Camera2VideoImageActivity$7.onClick(Camera2VideoImageActivity.java:312)
at android.view.View.performClick(View.java:5721)
at android.view.View$PerformClick.run(View.java:22624)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7422)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
以下是源代码:
https://github.com/TadewosBell/errorCameraApp
任何帮助表示赞赏,更深入或更好的资源更受欢迎,所以我可以了解更多
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class Camera2VideoImageActivity extends AppCompatActivity {
private static final String TAG = "Camera2VideoImageActivity";
private static final int REQUEST_CAMERA_PERMISSION_RESULT = 0;
private static final int REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT = 1;
private static final int STATE_PREVIEW = 0;
private static final int STATE_WAIT_LOCK = 1;
private int mCaptureState = STATE_PREVIEW;
private TextureView mTextureView;
private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
setupCamera(width, height);
connectCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
};
private CameraDevice mCameraDevice;
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
mCameraDevice = camera;
mMediaRecorder = new MediaRecorder();
if(mIsRecording) {
try {
createVideoFileName();
} catch (IOException e) {
e.printStackTrace();
}
startRecord();
//mMediaRecorder.start();
runOnUiThread(new Runnable() {
@Override
public void run() {
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.setVisibility(View.VISIBLE);
mChronometer.start();
}
});
} else {
startPreview();
}
// Toast.makeText(getApplicationContext(),
// "Camera connection made!", Toast.LENGTH_SHORT).show();
}
@Override
public void onDisconnected(CameraDevice camera) {
camera.close();
mCameraDevice = null;
}
@Override
public void onError(CameraDevice camera, int error) {
camera.close();
mCameraDevice = null;
}
};
private HandlerThread mBackgroundHandlerThread;
private Handler mBackgroundHandler;
private String mCameraId;
private Size mPreviewSize;
private Size mVideoSize;
private Size mImageSize;
private ImageReader mImageReader;
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new
ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
mBackgroundHandler.post(new ImageSaver(reader.acquireLatestImage()));
}
};
private class ImageSaver implements Runnable {
private final Image mImage;
public ImageSaver(Image image) {
mImage = image;
}
@Override
public void run() {
ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(mImageFileName);
fileOutputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaStoreUpdateIntent.setData(Uri.fromFile(new File(mImageFileName)));
sendBroadcast(mediaStoreUpdateIntent);
if(fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private MediaRecorder mMediaRecorder;
private Chronometer mChronometer;
private int mTotalRotation;
private CameraCaptureSession mPreviewCaptureSession;
private CameraCaptureSession.CaptureCallback mPreviewCaptureCallback = new
CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult captureResult) {
switch (mCaptureState) {
case STATE_PREVIEW:
// Do nothing
break;
case STATE_WAIT_LOCK:
mCaptureState = STATE_PREVIEW;
Integer afState = captureResult.get(CaptureResult.CONTROL_AF_STATE);
if(afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
Toast.makeText(getApplicationContext(), "AF Locked!", Toast.LENGTH_SHORT).show();
startStillCaptureRequest();
}
break;
}
}
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
process(result);
}
};
private CameraCaptureSession mRecordCaptureSession;
private CameraCaptureSession.CaptureCallback mRecordCaptureCallback = new
CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult captureResult) {
switch (mCaptureState) {
case STATE_PREVIEW:
// Do nothing
break;
case STATE_WAIT_LOCK:
mCaptureState = STATE_PREVIEW;
Integer afState = captureResult.get(CaptureResult.CONTROL_AF_STATE);
if(afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
Toast.makeText(getApplicationContext(), "AF Locked!", Toast.LENGTH_SHORT).show();
startStillCaptureRequest();
}
break;
}
}
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
process(result);
}
};
private CaptureRequest.Builder mCaptureRequestBuilder;
private ImageButton mRecordImageButton;
private ImageButton mStillImageButton;
private boolean mIsRecording = false;
//private boolean mIsTimelapse = false;
private File mVideoFolder;
private String mVideoFileName;
private File mImageFolder;
private String mImageFileName;
private static SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 0);
ORIENTATIONS.append(Surface.ROTATION_90, 90);
ORIENTATIONS.append(Surface.ROTATION_180, 180);
ORIENTATIONS.append(Surface.ROTATION_270, 270);
}
private static class CompareSizeByArea implements Comparator<Size> {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum( (long)(lhs.getWidth() * lhs.getHeight()) -
(long)(rhs.getWidth() * rhs.getHeight()));
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera2_video_image);
createVideoFolder();
createImageFolder();
mChronometer = (Chronometer) findViewById(R.id.chronometer);
mTextureView = (TextureView) findViewById(R.id.textureView);
mStillImageButton = (ImageButton) findViewById(R.id.cameraImageButton2);
mStillImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!( mIsRecording)) {
checkWriteStoragePermission();
}
lockFocus();
}
});
mRecordImageButton = (ImageButton) findViewById(R.id.videoOnlineImageButton);
mRecordImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mIsRecording) {
mChronometer.stop();
mChronometer.setVisibility(View.INVISIBLE);
mIsRecording = false;
mRecordImageButton.setImageResource(R.mipmap.btn_video_online);
// Starting the preview prior to stopping recording which should hopefully
// resolve issues being seen in Samsung devices.
startPreview();
mMediaRecorder.stop();
mMediaRecorder.reset();
Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaStoreUpdateIntent.setData(Uri.fromFile(new File(mVideoFileName)));
sendBroadcast(mediaStoreUpdateIntent);
} else {
mIsRecording = true;
mRecordImageButton.setImageResource(R.mipmap.btn_video_busy);
checkWriteStoragePermission();
}
}
});
/* mRecordImageButton.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mIsTimelapse =true;
mRecordImageButton.setImageResource(R.mipmap.btn_timelapse);
checkWriteStoragePermission();
return true;
}
});*/
}
@Override
protected void onResume() {
super.onResume();
startBackgroundThread();
if(mTextureView.isAvailable()) {
setupCamera(mTextureView.getWidth(), mTextureView.getHeight());
connectCamera();
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == REQUEST_CAMERA_PERMISSION_RESULT) {
if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(),
"Application will not run without camera services", Toast.LENGTH_SHORT).show();
}
if(grantResults[1] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(),
"Application will not have audio on record", Toast.LENGTH_SHORT).show();
}
}
if(requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if(mIsRecording ) {
mIsRecording = true;
mRecordImageButton.setImageResource(R.mipmap.btn_video_busy);
}
Toast.makeText(this,
"Permission successfully granted!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,
"App needs to save video to run", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onPause() {
closeCamera();
stopBackgroundThread();
super.onPause();
}
@Override
public void onWindowFocusChanged(boolean hasFocas) {
super.onWindowFocusChanged(hasFocas);
View decorView = getWindow().getDecorView();
if(hasFocas) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
private void setupCamera(int width, int height) {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
for(String cameraId : cameraManager.getCameraIdList()){
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
if(cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) ==
CameraCharacteristics.LENS_FACING_FRONT){
continue;
}
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
int deviceOrientation = getWindowManager().getDefaultDisplay().getRotation();
mTotalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation);
boolean swapRotation = mTotalRotation == 90 || mTotalRotation == 270;
int rotatedWidth = width;
int rotatedHeight = height;
if(swapRotation) {
rotatedWidth = height;
rotatedHeight = width;
}
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight);
mVideoSize = chooseOptimalSize(map.getOutputSizes(MediaRecorder.class), rotatedWidth, rotatedHeight);
mImageSize = chooseOptimalSize(map.getOutputSizes(ImageFormat.JPEG), rotatedWidth, rotatedHeight);
mImageReader = ImageReader.newInstance(mImageSize.getWidth(), mImageSize.getHeight(), ImageFormat.JPEG, 1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
mCameraId = cameraId;
return;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void connectCamera() {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED) {
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
} else {
if (shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA)) {
Toast.makeText(this,
"Video app required access to camera", Toast.LENGTH_SHORT).show();
}
//ADDED A PERMISSION REQUEST FOR WRITING IN STORAGE SO IT HAPPENS WHEN THE APP FIRST RUNS
requestPermissions(new String[]{android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO
, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION_RESULT);
}
}else {
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void checkWriteStoragePermission() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
try {
createVideoFileName();
} catch (IOException e) {
e.printStackTrace();
}
if(mIsRecording) {
startRecord();
mMediaRecorder.start();
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.setVisibility(View.VISIBLE);
mChronometer.start();
}
} else {
if(shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "app needs to be able to save videos", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT);
}
} else {
try {
createVideoFileName();
} catch (IOException e) {
e.printStackTrace();
}
if(mIsRecording ) {
startRecord();
mMediaRecorder.start();
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.setVisibility(View.VISIBLE);
mChronometer.start();
}
}
}