CWAC-camera exception "Method called after release()" after exiting

165 views Asked by At

Firstly, I'm crap at English.

I'm working on a project which uses Android camera.

My team is using CWAC-camera, so does my project.

So far I think it's really good. I'm displaying the preview of my camera. The thing is, when I try to close the application (with the physical "return" button), it crashes. Not always.

In fact it seems it's crashing when I'm closing BEFORE the src.release() in CameraPreviewFragment. However, if I close the app after the src.release(), it seems it's working well. It's not 100% sure, I said that thanks to the loggers.

Here is the error :

5529-5529/net.personal.opencv_tester W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41a222a0)

06-10 10:04:50.960 30241-30241/net.personal.opencv_tester E/MINE DEBUG﹕ Beginning

06-10 10:04:51.015 30241-30241/net.personal.opencv_tester E/MINE DEBUG﹕ Just Before Release

06-10 10:04:51.015 30241-30241/net.personal.opencv_tester E/MINE DEBUG﹕ Just After Release

06-10 10:04:51.015 30241-30241/net.personal.opencv_tester E/MINE DEBUG﹕ End

06-10 10:04:51.555 30241-30241/net.personal.opencv_tester E/AndroidRuntime﹕

FATAL EXCEPTION: main

> java.lang.RuntimeException: Method called after release()
        at android.hardware.Camera.setHasPreviewCallback(Native Method)
        at android.hardware.Camera.access$600(Camera.java:139)
        at android.hardware.Camera$EventHandler.handleMessage(Camera.java:867)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:176)
        at android.app.ActivityThread.main(ActivityThread.java:5419)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
        at dalvik.system.NativeStart.main(Native Method)

And here is when it works:

06-10 10:06:56.480 32508-32508/net.personal.opencv_tester E/MINE DEBUG﹕ Beginning

06-10 10:06:56.495 32508-32508/net.personal.opencv_tester E/MINE DEBUG﹕ Just Before Release

06-10 10:06:56.495 32508-32508/net.personal.opencv_tester E/MINE DEBUG﹕ Just After Release

06-10 10:06:56.495 32508-32508/net.personal.opencv_tester E/MINE DEBUG﹕ End

06-10 10:06:57.225 32508-32508/net.personal.opencv_tester E/MINE DEBUG﹕ On detach

Here's my code :

MainActivity.java

package net.personal.opencv_tester;

import org.opencv.android.OpenCVLoader;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import com.commonsware.cwac.camera.CameraHost;
import com.commonsware.cwac.camera.CameraHostProvider;
import com.commonsware.cwac.camera.SimpleCameraHost;

public class MainActivity
    extends Activity
    implements CameraHostProvider
{

private static final String TAG = MainActivity.class.getSimpleName();

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

    requestWindowFeature( Window.FEATURE_NO_TITLE );
    getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN );

    setContentView( R.layout.activity_main );
}

static {
    if (!OpenCVLoader.initDebug()) {
        // Handle initialization error
    }
}

@Override
public CameraHost getCameraHost()
{
    SimpleCameraHost.Builder builder =
            new SimpleCameraHost.Builder( new CustomCameraHost( this ) );
    builder.useFullBleedPreview( true );
    return builder.build();
}
}

CustomCameraHost.java

package net.personal.opencv_tester;

import java.io.File;
import android.content.Context;
import com.commonsware.cwac.camera.SimpleCameraHost;

public class CustomCameraHost
    extends SimpleCameraHost
{

private final File outFile;

public CustomCameraHost( File outFile, Context context )
{
    super( context );
    this.outFile = outFile;
}

public CustomCameraHost( Context context )
{
    super( context );
    this.outFile = new File(context.getFilesDir(), "test.jpg");
}

@Override
public boolean useSingleShotMode()
{
    return true;
}

@Override
protected File getPhotoPath()
{
    return outFile;
}

@Override
protected boolean scanSavedImage()
{
    return false;
}
}

And finally, where the bug is situated:

CameraPreviewFragment.java

package net.personal.opencv_tester;

import org.opencv.core.Core;
[...] 
import com.commonsware.cwac.camera.CameraFragment;
import com.commonsware.cwac.camera.CameraView;
import com.jjoe64.graphview.BarGraphView;
import com.jjoe64.graphview.GraphView;


public class CameraPreviewFragment
    extends CameraFragment
    implements Camera.PreviewCallback, SensorEventListener, OnClickListener
{

private CameraView mCameraView;
private TextView mTextView;
private GraphView mGraphView;
private TextView mInfosTextView;

private long mLastCheck = System.currentTimeMillis();

@Override
public void onAttach( Activity activity )
{
    Log.e("MINE DEBUG", "On attach");
    super.onAttach( activity );
}

@Override
public void onDetach()
{
    Log.e("MINE DEBUG", "On detach");
    super.onDetach();
}

@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState )
{
    View view = LayoutInflater.from( getActivity() ).inflate( R.layout.fragment_preview, container, false );
    view.setOnClickListener( this );

    mTextView = ( TextView ) view.findViewById( R.id.cameraWarningTextView );

    mCameraView = ( CameraView ) view.findViewById( R.id.cameraSurfaceView );
    mCameraView.setHost( getHost() );

    //Camera.open(getHost().getCameraId()).setOneShotPreviewCallback(this);
    mCameraView.setPreviewCallback( this );
    setCameraView( mCameraView );

    FrameLayout graphLayout = ( FrameLayout ) view.findViewById( R.id.cameraHistLayout );
    mGraphView = new BarGraphView( getActivity(), "Histogram" );
    mGraphView.getGraphViewStyle().setTextSize( 17f );
    mGraphView.getGraphViewStyle().setHorizontalLabelsColor( 0xffffffff );
    mGraphView.getGraphViewStyle().setVerticalLabelsColor( 0xffffffff );
    mGraphView.setVisibility( View.GONE );
    graphLayout.addView( mGraphView );

    mInfosTextView = ( TextView ) view.findViewById( R.id.cameraInfosTextView );
    mInfosTextView.setVisibility( View.GONE );

    return view;
}

@Override
public void onClick( View v )
{
    autoFocus();
}

@Override
public void onSensorChanged( SensorEvent event )
{   
}

@Override
public void onAccuracyChanged( Sensor sensor, int accuracy )
{
}

@Override
public void onPreviewFrame( byte[] data, Camera camera )
{
    Log.e("MINE DEBUG", "Begining");
    long now = System.currentTimeMillis();

    // Check an image every 500ms
    if (mLastCheck + 500 > now) {
        return;
    }
    mLastCheck = now;
    
    int frameHeight = camera.getParameters().getPreviewSize().height;
    int frameWidth = camera.getParameters().getPreviewSize().width;

    // Create default grayscale matrix

    Mat src = new Mat( frameHeight, frameWidth, CvType.CV_8UC1 );
    src.put( 0, 0, data );

    // Resize if image is too large (for performances)
    if (src.width() > 640) {
        double ratio = ( double ) src.width() / ( double ) src.height();
        Imgproc.resize( src, src, new Size( 640, 640 / ratio ), 0, 0, Imgproc.INTER_LINEAR );
    }

    // Remove noise
    Imgproc.GaussianBlur( src, src, new Size( 3, 3 ), 0.5 );

    try {
        mTextView.setText( "Valid image" );
        mTextView.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_capture_ok), null,
                null, null);
    } finally {
        Log.e("CHECK DEBUG", "Just Before Release");
        src.release();
        Log.e("CHECK DEBUG", "Just After Release");
    }
    Log.e("MINE DEBUG", "End");
}
}

I browed StackOverflow and found a "fix", but it isn't working

 mCameraView.setPreviewCallback(null);

Thank you very much for your patience. I can't find the fix.

0

There are 0 answers