如何在setOnClickListener上發布相機?

[英]How to release camera on setOnClickListener?


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

我試圖在Imageview的setOnClickListener上發布相機,但應用程序崩潰並顯示以下錯誤

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)

2 个解决方案

#1


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

#2


0  

Put

    mPreview.getHolder().removeCallback(mPreview);

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

在mCamera.setPreviewCallback(null)和mCamera.release()之間的onPause中

It's working like a charm.

它的工作就像一個魅力。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2015/05/20/720d88feaf4130afb1f59065b3daed1.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com