Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android camera API app crashes at onResume

I am using camera API to write an app: show preview, and take a photo. The first version works very well. In class Preview extends SurfaceView implements SurfaceHolder.Callback

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    camera = Camera.open();
    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();

    } catch (IOException e) {
        e.printStackTrace();
    }

    hasSurface = true;
}


public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // It will be called immediately after surfaceCreated
    // I move it to Resume.
    setCameraPreviewParameters();

    camera.startPreview();

}

In the main activity:

public class CameraDemo extends Activity

I also set a member: CameraUnit ui; It is:

public class CameraUnit extends LinearLayout

In the onCreate,

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ui = new CameraUnit(this);
    setContentView((View) ui); 

    Log.d(TAG, "onCreate'd");
}

it create a LinearLayout object, which contains the surfaceView, and a camera button.

The onResume is:

    @Override
protected void onResume() {
    super.onResume();
}

Although it works, I think the onResume shouldn't be empty. I also see the surfaceCreated and surfaceChanged are empty in a famous Android app example OCRTest So I believe it is better and also feasible to move the commands in surfaceCreated and surfaceChanged to onResume.

I think the flow chat for the 1st Version of my app should be: Main activity onCreate (where the LinearLayout and its surfaceView, camera button are created), surfaceCreated and surfaceChanged are called, onResume.

So I may simply move the commands in surfaceCreated and surfaceChanged to onResume. But it doesn't work! I used Debug to find out the surface is null. I think the surfaceCreatd is not called. My app is different OCRTest, which implements SurfaceHolder.Callback in the main activity. I implement SurfaceHolder.Callback in the SurfaceView:

class Preview extends SurfaceView implements SurfaceHolder.Callback

So I add two other lines in onResume

        ui.preview.surfaceCreated(ui.preview.mHolder);
    ui.preview.surfaceChanged(ui.preview.mHolder, 0, 800, 400);

I randomly set the last three integer arguments. When I start the activity, the error window in Android phone pops out. It says “Caused by: java.lang.RuntimeException: Fail to connect to camera service”. But how to fix it???? Thanks a lot!

Errors are:

    01-07 00:27:57.173: W/dalvikvm(11625): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
01-07 00:27:57.173: E/AndroidRuntime(11625): FATAL EXCEPTION: main
01-07 00:27:57.173: E/AndroidRuntime(11625): java.lang.RuntimeException: Unable to resume activity {com.example/com.example.CameraDemo}: java.lang.RuntimeException: Fail to connect to camera service
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2460)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2481)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1847)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.access$1500(ActivityThread.java:132)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.os.Looper.loop(Looper.java:150)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.main(ActivityThread.java:4263)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at java.lang.reflect.Method.invokeNative(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at java.lang.reflect.Method.invoke(Method.java:507)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at dalvik.system.NativeStart.main(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625): Caused by: java.lang.RuntimeException: Fail to connect to camera service
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.native_setup(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.<init>(Camera.java:265)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.open(Camera.java:241)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.example.Preview.surfaceCreated(Preview.java:60)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.example.CameraDemo.onResume(CameraDemo.java:64)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1242)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.Activity.performResume(Activity.java:3904)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2450)
01-07 00:27:57.173: E/AndroidRuntime(11625):    ... 12 more
01-07 00:27:59.455: I/Process(11625): Sending signal. PID: 11625 SIG: 9
like image 404
user1914692 Avatar asked Jan 07 '13 06:01

user1914692


People also ask

Why does my camera app keep crashing android?

Clear Camera Cache and App Data If the cache hasn't been cleared in a while it can accumulate some corrupted files, leading to the camera app crashing randomly. In order to clear the cache and app data go to Settings>Apps>Camera>Storage>Clear cache/app data.

What is camera API in Android?

This package is the primary API for controlling device cameras. It can be used to take pictures or videos when you are building a camera application. Camera. This class is the older deprecated API for controlling device cameras. SurfaceView.


2 Answers

You get this

java.lang.RuntimeException: Fail to connect to camera service

Exception, when the Camera is being used by other applications. But i believe that other application is your application itself. You have to release the Camera.

These are the cases where you should release the Camera:

In the Preview class:

public void surfaceDestroyed(SurfaceHolder holder) {

    // empty. Take care of releasing the Camera preview in your activity.
    if (mCamera != null) {
        mCamera.release();
    }
}

In the Activity:

@Override
public void onBackPressed() {
    super.onBackPressed();
    if (myCamera != null) {
        myCamera.release();
    }
    finish();
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if (myCamera != null) {
        myCamera.release();
    }
}

Also on Cancel clicked, and also when you are finished using the Camera i.e.., when the Image is Captured and you come back to the Activity.

Also try this:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (mHolder.getSurface() == null) {
        return;
    }

    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        //You can ignore this, because this means the Preview doesn't Exist
        //So, no need to try stopping
    }

    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        //Catch this
    }
}
like image 188
Archie.bpgc Avatar answered Sep 27 '22 16:09

Archie.bpgc


So I Created an app that used the camera but a different Launch Icon to get to the settings page. So Every time i paused and minimised the app to change the settings and went back it also crashed with this Error. So after a lot of research I still had no answer. Then i realised this had to do with the Managing of the Life Cycle of the Camera. So went and looked at the Life Cycle, specifically at Pausing. So i Realised, we are all doing this on the wrong method. Where we are doing it on the onResume, we should be doing it onStart. AND BAM! it worked.

Here is my code for my app.

@Override
    protected void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
        if (mPreview != null) {
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer);
            preview.removeView(mPreview);
            mPreview = null;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
        if (mPreview != null) {
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer);
            preview.removeView(mPreview);
            mPreview = null;
        }
    }
    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onStart(){
        super.onStart();
//Check if the camera exists or not so it does not clash with the onCreate
        if(mCamera == null){
            dir_string =  new File("/storage/sdcard1/app");
            Log.d("TAG",dir_string.toString());
            mCamera = getCameraInstance();
            mPreview = new CameraPreview(this, mCamera);
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer);
            preview.addView(mPreview);
        }
    }

Hope this help someone at least.

like image 34
user2365554 Avatar answered Sep 27 '22 17:09

user2365554