单击录制时,相机应用程序会发生致命异常吗?

时间:2017-11-05 01:16:30

标签: java android android-camera android-camera2

我目前正在开发一款非常简单的小工具和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();
        }
    }
}

0 个答案:

没有答案