为什么我的应用程序在使用 android.hardware.Camera.Open() 时会崩溃?

Why does my app crash when using android.hardware.Camera.Open()?

我正在为 Android 的大多数版本重新编写应用程序。该应用程序设置为在启动时调用 android.hardware.Camera.Open()。应用程序启动时会出现错误 Camera Error: Could not connect to camera

AndroidManifest.xml中的权限是

<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.camera"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>`.

为什么连接不上相机?

不仅要在 manifest 中声明,而且您还需要在 运行 时间内从用户那里授予 permission Android 6.+ 使用下面的代码片段授予 camera permission

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                            if (ContextCompat.checkSelfPermission(SplashScreenActivty.this, Manifest.permission.CAMERA)
                                    != PackageManager.PERMISSION_GRANTED) {
                                ActivityCompat.requestPermissions(this,
                                        new String[]{Manifest.permission.CAMERA},
                                        1);
                            } 

                        }


 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case 1: {

                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {


                    // permission was granted, yay! Do the
                    // camera-related task you need to do.
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.

                    Toast.makeText(this, "Permission denied to read SMS", Toast.LENGTH_SHORT).show();
                    finish();
                }
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

在以前的 android 版本中,为了使用摄像头硬件,在 android 清单中声明适当的权限和使用就足够了,但是由于 Marshmallow 版本已经出现,所以 运行 应用程序了。由于这里还需要启用运行时间权限。考虑使用类似的代码,并使其适合您的项目,因为它让您有机会检查和启用权限。

  @Override
public void onRequestPermissionsResult(int requestCode,  String[] permissions, int[] grantResults) {
    if (requestCode == PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            cameraPreview.initializeCamera();
        } else {

        }
        return;
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == PERMISSION_REQUEST_CODE) {
        cameraPreview.initializeCamera();
        return;
    }
    super.onActivityResult(requestCode, resultCode, data);
}


   public void requestCameraPermission() {
    ActivityCompat.requestPermissions(this,
            new String[]{
                    Manifest.permission.CAMERA
            },
            PERMISSION_REQUEST_CODE);
}

public void requestPermissionWithRationale() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
        Snackbar.make(findViewById(android.R.id.content), R.string.no_cam_permission, Snackbar.LENGTH_INDEFINITE)
                .setAction(R.string.snackbar_action_grant, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        requestCameraPermission();
                    }
                })
                .show();
    } else {
        requestCameraPermission();
    }
}

使用相机已弃用

下面是代码

更新--->

  @Module
public class CameraModule {

    @Provides
    CameraSupport provideCameraSupport() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return new CameraNew(context);
        } else {
            return new CameraOld();
        }
    }
}

然后是旧目标:

 @SuppressWarnings("deprecation")
public class CameraOld implements CameraSupport {

    private Camera camera;

    @Override
    public CameraSupport open(final int cameraId) {
        this.camera = Camera.open(cameraId);
        return this;
    }

    @Override
    public int getOrientation(final int cameraId) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);
        return info.orientation;
    }
}

新目标:

  public class CameraNew implements CameraSupport {

    private CameraDevice camera;
    private CameraManager manager;

    public CameraNew(final Context context) {
        this.manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public CameraSupport open(final int cameraId) {
        try {
            String[] cameraIds = manager.getCameraIdList();
            if (ActivityCompat.checkSelfPermission(CameraPreview.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.

                return null;
            }
            manager.openCamera(cameraIds[cameraId], new CameraDevice.StateCallback() {
                @Override
                public void onOpened(CameraDevice camera) {
                    CameraNew.this.camera = camera;
                }

                @Override
                public void onDisconnected(CameraDevice camera) {
                    CameraNew.this.camera = camera;
                    // TODO handle
                }

                @Override
                public void onError(CameraDevice camera, int error) {
                    CameraNew.this.camera = camera;
                    // TODO handle
                }
            }, null);
        } catch (Exception e) {
            // TODO handle
        }
        return this;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public int getOrientation(final int cameraId) {
        try {
            String[] cameraIds = manager.getCameraIdList();
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
            return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
        } catch (CameraAccessException e) {
            // TODO handle
            return 0;
        }
    }
}

问题解决了!

问题只是大小写的问题。 <uses-permission android:name="android.permission.camera"/> 行实际上应该是 <uses-permission android:name="android.permission.CAMERA"/>。发生这种情况是因为 camera 是硬件功能,而 CAMERA 是权限。