我有2个设备来测试我的应用:运行Android 4.2.2的Acer v370和6.0.1版本的Samsung Galaxy S6
该应用在Acer上工作正常,但在S6上立即崩溃。我正在使用
_camera = Camera.open(0);
并且调试说它此时崩溃了。
我得到的错误是:
09-15 11:24:33.491 15284-15284/com.user.qrReader E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.user.qrReader, PID: 15284
java.lang.RuntimeException: Unable to resume activity {com.user.qrReader/com.user.qrReader.MainActivity}:
java.lang.RuntimeException: Fail to connect to camera service
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4156)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)
at android.app.ActivityThread.access$1100(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
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)
Caused by: java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:568)
at android.hardware.Camera.open(Camera.java:405)
at com.user.qrReader.CameraPreview.openCamera(CameraPreview.java:206)
at com.user.qrReader.CameraPreview.captureStart(CameraPreview.java:288)
at com.user.qrReader.QRReaderAppManager.onResume(QRReaderAppManager.java:208)
at com.user.qrReader.MainActivity.onResume(MainActivity.java:187)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1286)
at android.app.Activity.performResume(Activity.java:6987)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4145)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)
at android.app.ActivityThread.access$1100(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
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)
以下是我的清单中的权限:
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
我不能使用camera2因为我必须保持应用程序兼容至少android 4,我不知道去哪个方向。它必须是与新的android相关的东西,但我找不到什么。有什么想法吗?
编辑:您也可以在安装apk后手动执行此操作,方法是转到设置&gt;应用程序&gt;应用程序管理器&gt; {我的应用}&gt;权限&gt;允许相机。当然,如果你有解决方案,这很糟糕也没用,但是在调试的过程中它帮了我一点,所以我会把它留在这里。 谢谢你的回答。
答案 0 :(得分:0)
“注意:如果您的应用程序定位到M及以上,并声明为使用未授予的CAMERA权限,则尝试使用此操作将导致SecurityException。”
这真的很奇怪。根本没有意义。该应用程序声明使用具有IMAGE_CAPTURE操作的意图的Camera权限,只需运行SecurityException。但是,如果您的应用未使用意图使用动作声明相机权限IMAGE_CAPTURE可以毫无问题地启动相机应用。
解决方法是检查应用程序是否包含清单中的相机权限,如果是,请在启动意图之前请求相机权限。
以下是检查清单中是否包含权限的方法,无论是否授予权限都无关紧要。
public boolean hasPermissionInManifest(Context context, String permissionName) {
final String packageName = context.getPackageName();
try {
final PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
final String[] declaredPermisisons = packageInfo.requestedPermissions;
if (declaredPermisisons != null && declaredPermisisons.length > 0) {
for (String p : declaredPermisisons) {
if (p.equals(permissionName)) {
return true;
}
}
}
} catch (NameNotFoundException e) {
}
return false;
}
答案 1 :(得分:0)
自API 21以来,不推荐使用Camera类。
建议使用新的android.hardware.camera2 API 应用
可悲的是,我还没有经历过,所以我无法帮助更多。
还有一个小机会,尝试:
Camera.open(); // Without argument
此致
答案 2 :(得分:0)
对于检查权限,我创建了一个单独的类,如下所示:
public class MarshMallowPermission {
public static final int RECORD_PERMISSION_REQUEST_CODE = 1;
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2;
public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
Activity activity;
public MarshMallowPermission(Activity activity) {
this.activity = activity;
}
public boolean checkPermissionForRecord(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public boolean checkPermissionForExternalStorage(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public boolean checkPermissionForCamera(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public void requestPermissionForRecord(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.RECORD_AUDIO)){
Toast.makeText(activity, "Microphone permission needed for recording. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.RECORD_AUDIO},RECORD_PERMISSION_REQUEST_CODE);
}
}
public void requestPermissionForExternalStorage(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(activity, "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
public void requestPermissionForCamera(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
Toast.makeText(activity, "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
}
}
}
然后,获取
MarshMallowPermission marshMallowPermission = new MarshMallowPermission(this);
public void getPhotoFromCamera() {
if (!marshMallowPermission.checkPermissionForCamera()) {
marshMallowPermission.requestPermissionForCamera();
} else {
if (!marshMallowPermission.checkPermissionForExternalStorage()) {
marshMallowPermission.requestPermissionForExternalStorage();
} else {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File mediaStorageDir = new File(
Environment.getExternalStorageDirectory()
+ File.separator
+ getString(R.string.directory_name_corp_chat)
+ File.separator
+ getString(R.string.directory_name_images)
);
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
try {
mediaFile = File.createTempFile(
"IMG_" + timeStamp, /* prefix */
".jpg", /* suffix */
mediaStorageDir /* directory */
);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
startActivityForResult(takePictureIntent, PICK_FROM_CAMERA);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
答案 3 :(得分:0)
这是在活动中。我检查权限并保存,将我的一些权限更改为CAMERA权限。这是一个有效的例子。
private static final int REQUEST_CODE_GET_ACCOUNTS = 101;
private static final int REQUEST_AUDIO_PERMISSION = 102;
@TargetApi(23)
public void checkAudioPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
playerFragment.setupVisualizerFxAndUI();
return;
}
if (this.checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager
.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO},
REQUEST_AUDIO_PERMISSION);
} else {
playerFragment.setupVisualizerFxAndUI();
}
}
@TargetApi(23)
public void checkGmailPermission() {
if (isDeviceOnline()) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
showGmailRecFragment(true);
return;
}
if (this.checkSelfPermission(Manifest.permission.GET_ACCOUNTS) != PackageManager
.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS},
REQUEST_CODE_GET_ACCOUNTS);
return;
} else {
showGmailRecFragment(true);
}
} else {
Utils.showToast(this, getString(R.string.no_internet));
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[]
grantResults) {
switch (requestCode) {
case REQUEST_CODE_GET_ACCOUNTS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showGmailRecFragment(true);
} else {
Utils.showToast(this, getString(R.string.accounts_permision_denied));
}
break;
case REQUEST_AUDIO_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
playerFragment.setupVisualizerFxAndUI();
} else {
Utils.showToast(this, getString(R.string.audio_permission_denied));
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
当我想要再次检查权限或用户拒绝它时,这是片段。这也保存了权限
private void setupViewVisualizer() {
if (!isLiveTv && !homeVideo.isVideoType()) {
((PlayerActivity) activity).checkAudioPermission();
} else {
return;
}
}