.setPreviewDisplay(holder)创建NullPointer异常

时间:2013-07-22 19:47:00

标签: java android android-camera

我创建了一个自定义相机应用程序,它几乎可以在所有设备上正常运行,但它似乎在开发人员门户中列为其他的设备上崩溃。这些用户都给我差评,我想解决这个问题,但我很难弄清楚,因为它在我拥有的所有设备上都能很好地工作。

camera.setPreviewDisplay(holder);是导致错误的原因,它在应用启动时发生。

public class CamPreview extends SurfaceView implements SurfaceHolder.Callback
{
SurfaceHolder holder;
Camera camera;
private List<Camera.Size> sizes;

public CamPreview(Context context, Camera camera)
{
    super(context);
    this.camera = camera;
    holder = this.getHolder();

           holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    holder.addCallback(this);

}

private Camera.Size getBestPreviewSize(int width, int height)
{
    Camera.Size result=null;
    Camera.Parameters p = camera.getParameters();
    for (Camera.Size size : p.getSupportedPreviewSizes()) {
        if (size.width<=width && size.height<=height) {
            if (result==null) {
                result=size;
            } else {
                int resultArea=result.width*result.height;
                int newArea=size.width*size.height;

                if (newArea>resultArea) {
                    result=size;
                }
            }
        }
    }
    return result;

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
    if (holder.getSurface() == null) return;

    Camera.Parameters parameters = camera.getParameters();

    sizes = parameters.getSupportedPreviewSizes();
    Camera.Size optimalSize = getBestPreviewSize(width, height);
    try{
    parameters.setPreviewSize(optimalSize.width,optimalSize.height);
        camera.setParameters(parameters);

    }
    catch (NullPointerException a)
    {

    }
    camera.startPreview();


}


@Override
public void surfaceCreated(SurfaceHolder holder)
{

    try
    {
        camera.setPreviewDisplay(holder);
    }
    catch (IOException e)
    {
        camera.release();
        camera=null;
        Log.d("FrontCam", "Error creating surface: " + e.getMessage());
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
    if (camera != null) {
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
    }


}
}

logcat的:

    java.lang.NullPointerException
    at com.me.frontcam.CamPreview.surfaceCreated(CamPreview.java:136)
    at android.view.SurfaceView.updateWindow(SurfaceView.java:552)
    at android.view.SurfaceView.dispatchDraw(SurfaceView.java:350)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.View.draw(View.java:6883)
    at android.widget.FrameLayout.draw(FrameLayout.java:357)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.View.draw(View.java:6883)
    at android.widget.FrameLayout.draw(FrameLayout.java:357)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1921)
    at android.view.ViewRoot.draw(ViewRoot.java:1528)
    at android.view.ViewRoot.performTraversals(ViewRoot.java:1264)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1866)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
    at dalvik.system.NativeStart.main(Native Method)

我如何打开相机

void initCamera()
{
    //check for front camera
    if(Camera.getNumberOfCameras()>1)
    {

     camera= Camera.open(1);
        try
        {
                camera.cancelAutoFocus();
        }
        catch (RuntimeException a)
        {

        }


        try{

            camera.setDisplayOrientation(90);
        }
        catch (NullPointerException a)
        {
            camera.setDisplayOrientation(90);
        }

    }

    else
    {
        new AlertDialog.Builder(this)
                .setTitle("Sorry but you cant use this app")
                .setMessage("You do not have a front camera")
                .setPositiveButton("Quit", new DialogInterface.OnClickListener() {

                    //Quits application
                    public void onClick(DialogInterface dialog, int which) {
                       finish();
                    }
                })

                .show();
    }



}

然后我调用了名为

的CamPreview构造函数的initUI方法
void initUI()
{
    white= new ImageView(this);
    imgShoot = (ImageButton) findViewById(R.id.imgShoot);
    imgShoot.setOnClickListener(imgShootOnClick);

     frmPreview = (FrameLayout) findViewById(R.id.frmPreview);
    preview = new CamPreview(this, camera);

    frmPreview.addView(white);
    white.setImageResource(R.drawable.aperture_opening);
    frmPreview.addView(preview);
    frmPreview.bringChildToFront(preview);  

}

我看过这两个并没有解决我的问题 Android - cam.setPreviewDisplay(holder) running into IOError

.setPreviewDisplay(holder) throwing null pointer exception

任何帮助都非常赞赏!

3 个答案:

答案 0 :(得分:3)

请检查您是否在清单中添加了所需的权限,这对我有用

答案 1 :(得分:2)

如果您使用上面显示的NullPointerException方法中的surfaceCreated()崩溃,那么您的问题应该很明显:cameranull

由于您将camera传递给CamPreview的构造函数,因此您需要调查如何调用此构造函数。

答案 2 :(得分:0)

如果camera对象或holder对象在surfaceCreathed方法中为空,我建议您先检查一下。 您还应该检查是否已经打开了相机:camera.open()