调用dispatchTakePictureIntent导致摄像头错误:无法连接到摄像头 - 执行停止未恢复的活动

时间:2015-06-07 05:35:37

标签: android camera

enter image description here

当我点击操作按钮拍照时,会出现一个弹出对话框并告诉我"无法连接到相机。"堆栈跟踪:

06-06 21:45:26.753: E/ActivityThread(25688): Performing stop of activity that is not resumed: {com.example.dselfies/com.example.dselfies.MainActivity}
06-06 21:45:26.753: E/ActivityThread(25688): java.lang.RuntimeException: Performing stop of activity that is not resumed: {com.example.dselfies/com.example.dselfies.MainActivity}
06-06 21:45:26.753: E/ActivityThread(25688): at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3344)
06-06 21:45:26.753: E/ActivityThread(25688): at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3425)
06-06 21:45:26.753: E/ActivityThread(25688): at android.app.ActivityThread.access$1100(ActivityThread.java:151)
06-06 21:45:26.753: E/ActivityThread(25688): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1332)
06-06 21:45:26.753: E/ActivityThread(25688): at android.os.Handler.dispatchMessage(Handler.java:102)
06-06 21:45:26.753: E/ActivityThread(25688): at android.os.Looper.loop(Looper.java:135)
06-06 21:45:26.753: E/ActivityThread(25688): at android.app.ActivityThread.main(ActivityThread.java:5254)
06-06 21:45:26.753: E/ActivityThread(25688): at java.lang.reflect.Method.invoke(Native Method)
06-06 21:45:26.753: E/ActivityThread(25688): at java.lang.reflect.Method.invoke(Method.java:372)
06-06 21:45:26.753: E/ActivityThread(25688): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
06-06 21:45:26.753: E/ActivityThread(25688): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

https://www.pntbrother.com/fix-cant-connect-to-camera-on-nexus-5-nexus-4-camera-has-stopped-working/

按照上面提到的建议,我选择了开发者选项并选择了#34;使用AwesomePlayer代替NuPlayer进行大多数媒体播放"但错误仍然存​​在。

单击操作按钮时,将调用onOptionsItemSelected,如下所示,调用dispatchTakePictureIntent

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml
   switch (item.getItemId()) {
        case R.id.action_camera:
        dispatchTakePictureIntent();
        // mCamera.takePicture(null, null, mPicture);
         return true;
        case R.id.action_settings:
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

我没有根据以下链接中的内容编辑dispatchTakePictureIntent:http://developer.android.com/training/camera/photobasics.html

为清楚起见,这是我使用的:

private void dispatchTakePictureIntent() {
    Log.i(TAG,"dispatchTakePictureIntent entered: ");
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            Log.i(TAG,"IOException: " + ex);
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                    Uri.fromFile(photoFile));
            Log.i(TAG,"Got here: "+Uri.fromFile(photoFile));
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            Log.i(TAG,"Picture successfully saved: "+takePictureIntent);
        }
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.i(TAG,"onActivityResult entered: ");
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        mImageView.setImageBitmap(imageBitmap);
    }
}


private File createImageFile() throws IOException {
    // Create an image file name
    Log.i(TAG,"createImageFile entered: ");
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
        imageFileName,  /* prefix */
        ".jpg",         /* suffix */
        storageDir      /* directory */
    );

    if (!storageDir.exists())
        storageDir.mkdirs();

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();
    Log.i(TAG,"mCurrentPhotoPath: " + mCurrentPhotoPath);
    Log.i(TAG,"image: " + image);
    return image;
}

"图片已成功保存" (dispatchTakePictureIntent中的最后一行)由logCat显示,并且在我的divice的Images / Pictures文件夹中,我确实找到了程序生成的.jpg。但是,点击任何一个,他们都说"未找到媒体。"

这是否是我必须制作asyncTask的明确信号?我很难确定this帖子是否相关。 Handler回答延迟让我觉得我需要让活动远离UIThread,但我不确定。

其他非常相似的帖子没有答案: https://stackoverflow.com/questions/24305700/camera-error-fail-to-connect-to-camera-service Can't connect to camera

我唯一的另一个预感是它与我用于显示预览的这个字段有关吗?

private Camera mCamera;

它在surfaceChanged中收到以下值,最终导致SurfaceView显示我的美丽面孔:

mCamera = Camera.open(0);

所以我的意思是,与相机建立了某种联系。

这是我的代码,使用此Camera对象成功生成预览,以备不时之需:

// Start the preview
private void startPreview() {
    Log.i(TAG,"startPreview entered: " + capture);
    if (null != mCamera) {
        try {
            mCamera.startPreview();
            mIsPreviewing = true;
        } catch (Exception e) {
            Log.e(TAG, "Failed to start preview");
        }
    }
}

// SurfaceHolder callback Object
SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // Do nothing
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        Log.i(TAG,"surfaceChanged entered: " + capture);
        if (mSurfaceHolder.getSurface() == null) {
            return;
        }

        // Disable touches on mFrame
        //mFrame.setEnabled(false);

        // Shutdown current preview
        //stopPreview();

        if (null == mCamera) {
            try {

                // Returns first back-facing camera or null if no camera is
                // available.
                // May take a long time to complete
                // Consider moving this to an AsyncTask
                mCamera = Camera.open(0);
                Log.e(TAG, "mCamera: "+mCamera);

            } catch (RuntimeException e) {
                Log.e(TAG, "Failed to acquire camera");
            }

            // Ensure presence of camera or finish()
            if (null == mCamera)
                finish();
        }

        setCameraParameters(width, height);

        // Initialize preview display
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            Log.e(TAG, "Failed to set preview display in ");
        }

        // Start preview
        try {
            startPreview();
            //mFrame.setEnabled(true);
        } catch (RuntimeException e) {
            Log.e(TAG, "Failed to start preview in surfaceChanged()");
        }
    }

    // Change camera parameters
    private void setCameraParameters(int width, int height) {

        Log.i(TAG,"setCameraParameters entered: " + mCamera);

        // Get camera parameters object
        Camera.Parameters p = mCamera.getParameters();

        Log.i(TAG,"Camera.Parameters p: " + p);

        // Find closest supported preview size
        Camera.Size bestSize = findBestSize(p, width, height);

        // FIX - Should lock in landscape mode?

        int tmpWidth = bestSize.width;
        int tmpHeight = bestSize.height;

        if (bestSize.width < bestSize.height) {
            tmpWidth = bestSize.height;
            tmpHeight = bestSize.width;
        }

        p.setPreviewSize(tmpWidth, tmpHeight);
        mCamera.setParameters(p);
    }

    // Determine the largest supported preview size
    private Camera.Size findBestSize(Camera.Parameters parameters,
            int width, int height) {

        Log.i(TAG,"findBestSize entered: " + capture);

        List<Camera.Size> supportedSizes = parameters
                .getSupportedPreviewSizes();

        Camera.Size bestSize = supportedSizes.remove(0);

        for (Camera.Size size : supportedSizes) {
            if ((size.width * size.height) > (bestSize.width * bestSize.height)) {
                bestSize = size;
            }
        }

        return bestSize;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // Do Nothing
    }
};

但在前面提到的链接中给出的代码中没有任何Camera对象使用:http://developer.android.com/training/camera/photobasics.html。也许我只是不明白为什么在调用拍照意图时不需要Camera对象来创建与相机的连接。

所以...当我删除调用dispatchTakePictureIntent的onOptionsItemSelected中的行并将其替换为:

时,会发生什么
mCamera.takePicture(null, null, mPicture); ?

因为当我这样做时,单击操作按钮时没有收到任何错误消息。

么?

1 个答案:

答案 0 :(得分:0)

在制作这个项目时我没有使用相机对象,我只是用文件URI制作了意图并发送了它。如果那不起作用

takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);

我怀疑您的模拟器和物理设备存在问题。我使用我的网络摄像头立即使用Android Studio模拟摄像头。