Android 调用DispatchTakePictureContent会导致摄像头错误:无法连接到摄像头-正在停止未恢复的活动

Android 调用DispatchTakePictureContent会导致摄像头错误:无法连接到摄像头-正在停止未恢复的活动,android,camera,Android,Camera,当我单击“操作”按钮拍照时,会出现一个弹出对话框,告诉我“无法连接到相机”。堆栈跟踪: 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.

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

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)

按照上面链接的建议,我转到开发人员选项并选择“使用AwesomePlayer而不是NuPlayer进行大多数媒体播放”,但错误仍然存在

单击操作按钮时,将调用OnOptions ItemSelected,正如您在下面看到的,将调用DispatchTakePictureContent

@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);
    }
}
我没有从以下链接中编辑DispatchTakePictureContent:

为清楚起见,我使用了以下内容:

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;
}
“Picture successfully saved”(DispatchTakePictureContent中的最后一行)由logCat显示,在我所在部门的…Images/Pictures文件夹中,我确实找到了程序生成的.jpg。然而,点击任何一个,他们都会说“找不到媒体”

这是我必须完成一项任务的明确迹象吗?我很难弄清楚这篇文章是否相关。带有延迟的处理程序回答使我认为需要使活动远离UIThread,但我不确定

其他非常类似的帖子没有答案:

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

private Camera mCamera;
它在surfaceChanged中接收到以下值,最终导致SurfaceView显示我美丽的脸:

mCamera = Camera.open(0);
所以我的意思是,某种程度上是和摄像机联系在一起的

以下是我的代码,它成功地使用此摄影机对象生成预览,以备您需要:

// 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
    }
};
因为当我这样做的时候,当我点击操作按钮时,我没有收到错误消息


建议

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

takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
我怀疑你的模拟器和物理设备有问题。我让Android Studio模拟摄像头立即与我的网络摄像头一起工作

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