0

目标:在相机预览上绘制一个可调整大小的矩形。

对于空指针异常问题,我找不到任何明确的答案。所以我希望通过发布问题来解决我的问题。我已经拥有的:

  • 正确的 Android 清单文件(相机权限等)
  • 正确的xml文件
  • 类似问题的答案之一需要添加我尝试过的 getBestPreviewSize() 方法

    这是代码:

预览.java

public class Preview extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder;
    private Camera mCamera;

    public Preview(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mHolder = getHolder();
        mHolder.addCallback(this);
        // mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    // without this constructor, xml which uses this class, will throw this
    // error: class cannot be instantiated
    public Preview(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // TODO Auto-generated method stub

        Camera.Parameters params = mCamera.getParameters();
        Camera.Size size = getBestPreviewSize(params, w, h);

        if (size != null) {
            params.setPreviewSize(size.width, size.height);
        }
        if (mHolder.getSurface() == null) {
            return;
        }

        mCamera.startPreview();

        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.d("CameraView",
                    "Error setting camera preview: " + e.getMessage());

        }

    }

    private Size getBestPreviewSize(Parameters params, int w, int h) {
        // TODO Auto-generated method stub
        Camera.Size result = null;

        for (Camera.Size size : params.getSupportedPreviewSizes()) {
            if (size.width <= w && size.height <= h) {
                if (result == null) {
                    result = size;
                } else {
                    int resultDelta = w - result.width + h - result.height;
                    int newDelta = w - size.width + h - size.height;

                    if (newDelta < resultDelta) {
                        result = size;
                    }
                }
            }
        }
        return result;
    }

    public void onPause() {
        mCamera.release();
        mCamera = null;
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        if (mCamera == null) {
            mCamera = Camera.open();

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.d("", "Error setting camera preview: " + e.getMessage());
            }
        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub
        if (mCamera != null) {

            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

}

CameraPreview.java 与 MainActivity()

public class CameraPreview extends Activity {

    private Preview mPreview;
    private ImageView mTakePicture, cameraIcon;
    private DrawView dV;
    private boolean mAutoFocus = true;
    private boolean mFlashBoolean = false;
    private Button bDisplayText;
    private RelativeLayout rl;
    private FrameLayout fl;
    Camera c;

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

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

        setContentView(R.layout.activity_main);


        mTakePicture = (ImageView) findViewById(R.id.cameraButton);
        bDisplayText = (Button) findViewById(R.id.bDispText);
        fl = (FrameLayout) findViewById(R.id.preview);
        rl = (RelativeLayout) findViewById(R.id.rl);
        c = getCameraInstance();

        dV = new DrawView(this);
        dV.invalidate();
        rl.addView(dV);

        mPreview = new Preview(this, c);

        fl.addView(mPreview);

    }

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

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();

    }

    private static Camera getCameraInstance() {
        // TODO Auto-generated method stub
        Camera c = null;
        c = Camera.open();

        return c;
    }

}

编辑:LogCat

09-06 20:23:15.739: E/AndroidRuntime(2352): FATAL EXCEPTION: main
09-06 20:23:15.739: E/AndroidRuntime(2352): java.lang.NullPointerException
09-06 20:23:15.739: E/AndroidRuntime(2352):     at com.example.textrecognize.Preview.surfaceCreated(Preview.java:94)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.SurfaceView.updateWindow(SurfaceView.java:543)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.SurfaceView.access$000(SurfaceView.java:81)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:169)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:671)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1820)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer.doFrame(Choreographer.java:525)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.os.Handler.handleCallback(Handler.java:615)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.os.Looper.loop(Looper.java:137)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at android.app.ActivityThread.main(ActivityThread.java:4778)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at java.lang.reflect.Method.invokeNative(Native Method)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at java.lang.reflect.Method.invoke(Method.java:511)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-06 20:23:15.739: E/AndroidRuntime(2352):     at dalvik.system.NativeStart.main(Native Method)
4

2 回答 2

1

尝试使用以下代码检查空异常:

public void surfaceCreated(SurfaceHolder arg0) {
        if (mCamera == null) {
            mCamera = Camera.open();

            // is mCamera null?
            if (mCamera == null) {
                Log.e("camera", "cannot open camera");
                return;
            }

            // is mHolder null? 
            if (mHolder == null) {
                Log.e("camera", "mHolder == null");
                mHolder = getHolder();
            }

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                Log.d("", "Error setting camera preview: " + e.getMessage());
            }
        }

    }
于 2013-09-11T01:43:37.780 回答
1

知道了!

相机对象本身为空。由于我的平板电脑只有一个摄像头,因此我使用了 Camera.open(0),瞧!

我希望在每个相机预览示例/教程/开发人员指南中都提到这一点。

谢谢你们的帮助。

于 2013-09-11T13:24:53.810 回答