1

I am trying to release camera on Imageview's setOnClickListener but the app crashes and shows the following error

java.lang.runtimeexception method called after release()

Can anyone help me with this? Following is my code snippet ,I don't know what the issue is with this code.

  public class ScanDispatch extends Activity {


private TextView current_office_name;

// scanning
private Camera mCamera;
private CameraPreview mPreview;
private Handler autoFocusHandler;
ImageScanner scanner;
boolean barcodeScanned = false;
boolean previewing = true;
private DrawerLayout mDrawerLayout;
ImageView img_navigation_link;

public ScanDispatch() {


@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_scan_dispatch);

    consts.pref = getSharedPreferences("pref", MODE_PRIVATE);
    consts.editor = consts.pref.edit();

    current_office_name = (TextView) findViewById(R.id.current_office_name);
    current_office_name.setText(consts.pref.getString("office_name", ""));
    // btn_scan = (ImageButton) findViewById(R.id.btn_scan);
    img_navigation_link = (ImageView) findViewById(R.id.img_navigation_link);



    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    autoFocusHandler = new Handler();
    mCamera = getCameraInstance();
    scanner = new ImageScanner();
    scanner.setConfig(0, Config.X_DENSITY, 3);
    scanner.setConfig(0, Config.Y_DENSITY, 3);

    mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);

    try {

        if (barcodeScanned) {
            barcodeScanned = false;
            // scanText.setText("Scanning...");
            mCamera.setPreviewCallback(previewCb);
            mCamera.startPreview();
            previewing = true;
            mCamera.autoFocus(autoFocusCB);
        }

    } catch (ActivityNotFoundException anfe) {
        anfe.printStackTrace();

    }

    // scnner over



    img_navigation_link.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            Intent intent = new Intent(ScanDispatch.this, MainMenu.class);
            startActivity(intent);
            mCamera.release();

            ScanDispatch.this.finish();
        }
    });

    FrameLayout preview = (FrameLayout) findViewById(R.id.relativeLayout1);
    preview.addView(mPreview);


}


@Override
protected void onPause() {
    super.onPause();
    if (mCamera != null) {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }

    if (mPreview != null) {
        preview.removeView(mPreview);
        mPreview = null;
    }
}


    @Override
    protected void onResume() {
        super.onResume();
        if (mCamera == null) {
            mCamera = getCameraInstance();
        }

        if (mPreview == null) {
            mPreview = new CameraPreview(getApplicationContext(), mCamera, previewCb, autoFocusCB);
            preview.addView(mPreview);
        }

    }




@SuppressWarnings("deprecation")
public static Camera getCameraInstance() {
    Camera c = null;
    try {
        c = Camera.open();
    } catch (Exception e) {
    }
    return c;
}

static {
    System.loadLibrary("iconv");
}

private Runnable doAutoFocus = new Runnable() {
    @SuppressWarnings("deprecation")
    public void run() {
        if (previewing)
            mCamera.autoFocus(autoFocusCB);
    }
};

// Mimic continuous auto-focusing
@SuppressWarnings("deprecation")
AutoFocusCallback autoFocusCB = new AutoFocusCallback() {
    public void onAutoFocus(boolean success, Camera camera) {
        autoFocusHandler.postDelayed(doAutoFocus, 1000);
    }
};

@SuppressWarnings("deprecation")
PreviewCallback previewCb = new PreviewCallback() {
    private String degd;

    public void onPreviewFrame(byte[] data, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        Size size = parameters.getPreviewSize();

        Image barcode = new Image(size.width, size.height, "Y800");
        barcode.setData(data);

        int result = scanner.scanImage(barcode);

        if (result != 0) {
            previewing = false;
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();

            SymbolSet syms = scanner.getResults();
            for (Symbol sym : syms) {
                // scanText.setText("barcode result " + sym.getData());
                Log.d("ooo", "Barcode result:" + sym.getData());
                String contents = sym.getData();
                consts.editor.putString("qrcode", contents);
                consts.editor.commit();

                barcodeScanned = true;



                Intent intent = new Intent(ScanDispatch.this,
                        DispatchTracking.class);
                intent.putExtra("arrow_val", "1");
                startActivity(intent);
                mCamera.release();
                ScanDispatch.this.finish();

                // Fragment fragment = new DispatchTracking();
                //
                // if (fragment != null) {
                // FragmentManager fragmentManager = getFragmentManager();
                // fragmentManager.beginTransaction()
                // .replace(R.id.content_frame, fragment).commit();

                // setTitle("Dispatch Me");
                // mDrawerLayout.closeDrawer(mDrawerList);
                //
                // }

            }
        }
    }
};



public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == 0) {
        if (resultCode == Activity.RESULT_OK) {

            String contents = intent.getStringExtra("SCAN_RESULT");
            String format = intent.getStringExtra("SCAN_RESULT_FORMAT");

            consts.editor.putString("qrcode", contents);
            consts.editor.commit();

            // Toast.makeText(this, "Content:" + contents + " Format:" +
            // format, Toast.LENGTH_LONG).show();

            Intent intent2 = new Intent(ScanDispatch.this,
                    DispatchTracking.class);
            intent2.putExtra("arrow_val", "1");
            startActivity(intent2);
            ScanDispatch.this.finish();

            // Fragment fragment = new DispatchTracking();
            //
            // if (fragment != null) {
            // FragmentManager fragmentManager = getFragmentManager();
            // fragmentManager.beginTransaction()
            // .replace(R.id.content_frame, fragment).commit();
            //
            // // setTitle("Dispatch Me");
            // // mDrawerLayout.closeDrawer(mDrawerList);
            //
            // }

        }
    }
}

camerapreview.java

 public class CameraPreview extends SurfaceView implements  SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private PreviewCallback previewCallback;
private AutoFocusCallback autoFocusCallback;

public CameraPreview(Context context, Camera camera,
                     PreviewCallback previewCb,
                     AutoFocusCallback autoFocusCb) {
    super(context);
    mCamera = camera;
    previewCallback = previewCb;
    autoFocusCallback = autoFocusCb;


    Camera.Parameters parameters = camera.getParameters();
    for (String f : parameters.getSupportedFocusModes()) {
        if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
            mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
            autoFocusCallback = null;
            break;
        }
    }
    */

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = getHolder();
    mHolder.addCallback(this);

    // deprecated setting, but required on Android versions prior to 3.0
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@SuppressWarnings("deprecation")
public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, now tell the camera where to draw the preview.
    try {
        mCamera.setPreviewDisplay(holder);
    } catch (IOException e) {
        Log.d("DBG", "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Camera preview released in activity

    //this.getHolder().removeCallback(this); mCamera.stopPreview(); mCamera.release();
    //mCamera.release();
}

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    /*
     * If your preview can change or rotate, take care of those events here.
     * Make sure to stop the preview before resizing or reformatting it.
     */
    if (mHolder.getSurface() == null){
      // preview surface does not exist
      return;
    }

    // stop preview before making changes
    try {
        mCamera.stopPreview();
    } catch (Exception e){
      // ignore: tried to stop a non-existent preview
    }

    try {
        // Hard code camera surface rotation 90 degs to match Activity view in portrait
        mCamera.setDisplayOrientation(90);

        mCamera.setPreviewDisplay(mHolder);
        mCamera.setPreviewCallback(previewCallback);
        mCamera.startPreview();
        mCamera.autoFocus(autoFocusCallback);
    } catch (Exception e){
        Log.d("DBG", "Error starting camera preview: " + e.getMessage());
    }
}

}

logcat

 05-22 14:34:53.793: E/AndroidRuntime(19969): FATAL EXCEPTION: main
 05-22 14:34:53.793: E/AndroidRuntime(19969): java.lang.RuntimeException:    Method called after release()
 05-22 14:34:53.793: E/AndroidRuntime(19969):   at android.hardware.Camera.setHasPreviewCallback(Native Method)
  05-22 14:34:53.793: E/AndroidRuntime(19969):  at android.hardware.Camera.access$600(Camera.java:133)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at android.hardware.Camera$EventHandler.handleMessage(Camera.java:771)
  05-22 14:34:53.793: E/AndroidRuntime(19969):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at android.os.Looper.loop(Looper.java:137)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at android.app.ActivityThread.main(ActivityThread.java:4517)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at java.lang.reflect.Method.invokeNative(Native Method)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at java.lang.reflect.Method.invoke(Method.java:511)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
05-22 14:34:53.793: E/AndroidRuntime(19969):    at dalvik.system.NativeStart.main(Native Method)
jimmy
  • 91
  • 1
  • 1
  • 9
  • Where is it crashing? – fadden May 20 '15 at 15:56
  • in set on click listner – jimmy May 21 '15 at 04:43
  • Add a comment identifying the line (since we can't see line numbers). Paste the full exception into the question (judging by the capitalization, you paraphrased the logcat output). You might also want to try setting mCamera to null after you call release() -- if the problem changes to an NPE, then you're just trying to use a camera object after releasing it, which isn't going to work. – fadden May 21 '15 at 05:02

2 Answers2

0

You need to check that if your camera is null or not.

if(mCamera!=null){
    mCamera.stopPreview();
    mPreview.getHolder().removeCallback(mPreview);
    mCamera.setPreviewCallback(null);
    mCamera.release();
    mCamera = null;
}
Piyush
  • 18,895
  • 5
  • 32
  • 63
0

Put

    mPreview.getHolder().removeCallback(mPreview);

in onPause between mCamera.setPreviewCallback(null) and mCamera.release()

It's working like a charm.

George Netu
  • 2,758
  • 4
  • 28
  • 49
Joseph Mekwan
  • 1,082
  • 1
  • 15
  • 28