Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
149 views
in Technique[技术] by (71.8m points)

java - Camera.open works on Android 4.2.2, but fails on 6.0.1

I have 2 devices to test my app : an Acer v370 running Android 4.2.2, and a Samsung Galaxy S6 on 6.0.1

The app works fine on the Acer, but crashes instantly on the S6. I'm using _camera = Camera.open(0); and debugging says it crashes at this point.

The error I get is :

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)

Here are the permissions in my manifest :

<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" />

I can't use camera2 because I have to keep the app compatible for at least android 4, and I don't know which direction to go. It must be something related to the new android but I can't find what. Any thoughts ?

EDIT : You can also do it manually, once the apk is installed, by going to settings>applications>application manager>{my app}>permissions> allow camera. Of course it's terrible and useless if you have the solution but it helped me for a bit while I was debugging so I'll leave it here. Thank you for your answers.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For Checking permission I created a separate class as below:

  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);
        }
    }
}

Then, for getting

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();
            }
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...