为什么我的应用程序在使用 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
是权限。
我正在为 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
是权限。