首先,我是英语的废话。
我正在开发一个使用Android相机的项目。
我的团队正在使用CWAC相机,我的项目也是如此。
到目前为止,我认为它真的很棒。我正在显示相机的预览。 问题是,当我尝试关闭应用程序时(使用物理“返回”按钮),它会崩溃。并非总是如此。
事实上,当我在CameraPreviewFragment中的src.release()之前关闭时,它似乎崩溃了。 但是,如果我在src.release()之后关闭应用程序,它似乎运行良好。 这不是100%肯定,我说这要归功于记录器。
这是错误:
5529-5529 / net.personal.opencv_tester W / dalvikvm:threadid = 1:线程退出时未捕获异常(组= 0x41a222a0)
06-10 10:04:50.960 30241-30241 / net.personal.opencv_tester E / MINE DEBUG:开始
06-10 10:04:51.015 30241-30241 / net.personal.opencv_tester E / MINE DEBUG:发布之前
06-10 10:04:51.015 30241-30241 / net.personal.opencv_tester E / MINE DEBUG:刚发布后
06-10 10:04:51.015 30241-30241 / net.personal.opencv_tester E / MINE DEBUG:结束
06-10 10:04:51.555 30241-30241 / net.personal.opencv_tester E / AndroidRuntime:
致命的例外:主要
> 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)
这就是它的工作原理:
06-10 10:06:56.480 32508-32508 / net.personal.opencv_tester E / MINE DEBUG:开始
06-10 10:06:56.495 32508-32508 / net.personal.opencv_tester E / MINE DEBUG:发布之前
06-10 10:06:56.495 32508-32508 / net.personal.opencv_tester E / MINE DEBUG:发布后
06-10 10:06:56.495 32508-32508 / net.personal.opencv_tester E / MINE DEBUG:结束
06-10 10:06:57.225 32508-32508 / net.personal.opencv_tester E / MINE DEBUG:On detach
这是我的代码:
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;
}
}
最后,错误发生在哪里:
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");
}
}
我浏览了StackOverflow并找到了“修复”,但它无法正常工作
mCameraView.setPreviewCallback(null);
非常感谢你的耐心等待。我找不到修复方法。