Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android custom camera crashes on resume

I have this custom camera activity in my app, which is working just fine, but when I press the home button while in camera activity, and then return to the app, it crashes, and the logcat says there was a null pointer exception at the surface view creation. This setup method is called on onResume:

    public void setup()
    {

    preview = new CameraPreview(this);
    ((FrameLayout) findViewById(R.id.camera_preview)).addView(preview);
    head=(ImageView)findViewById(R.id.head);
        head.setX((float)(Shared.screenWidth/5*1.8));
        head.setY((float)(Shared.screenHeight*0.03));
        LayoutParams params = (LayoutParams) head.getLayoutParams();
        params.width = (int)((Shared.screenWidth/5*3.2)-(head.getX()));
        params.height=(int)((Shared.screenHeight/3.8)-(head.getY()));
        head.setLayoutParams(params);
    body=(ImageView)findViewById(R.id.body);
        body.setX((float)(Shared.screenWidth/7));
        body.setY((float)(Shared.screenHeight/3.8));
        LayoutParams params2 = (LayoutParams) body.getLayoutParams();
        params2.width = (int)((Shared.screenWidth/7*6)-(body.getX()));
        params2.height=(int)((Shared.screenHeight)-(body.getY()));
        body.setLayoutParams(params2);
    go=(Button)findViewById(R.id.go);
    again=(Button)findViewById(R.id.again);
    stop=(ImageButton)findViewById(R.id.stop);
    stop.setOnClickListener( new OnClickListener() {
        public void onClick(View v) {
            Intent i =new Intent(CamActivity.this,Main.class);
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
            startActivity(i);


        }
    });
    btn = (ImageButton) findViewById(R.id.takePic);
    btn.setOnClickListener( new OnClickListener() {
        public void onClick(View v) {
            preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
            btn.setVisibility(View.INVISIBLE);
            btn.setEnabled(false);
            go.setVisibility(View.VISIBLE);
            go.setEnabled(true);
            head.setVisibility(View.INVISIBLE);
            body.setVisibility(View.INVISIBLE);
            go.setOnClickListener( new OnClickListener() {
                public void onClick(View v) {
                    Shared.bm=Bitmap.createScaledBitmap(bmp, Shared.screenWidth, Shared.screenHeight, true);

                    Intent i=new Intent(CamActivity.this,IKill.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
                    startActivity(i);

                }
            });
            again.setVisibility(View.VISIBLE);
            again.setEnabled(true);
            again.setOnClickListener( new OnClickListener() {
                public void onClick(View v) {
                    if (Build.VERSION.SDK_INT >= 11) {
                        recreate();
                    } else {
                        Intent intent = getIntent();
                        overridePendingTransition(0, 0);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        finish();

                        overridePendingTransition(0, 0);
                        startActivity(intent);
                    }

                }
            });

        }
    });


}

In addition, on my onCreate method I also have this:

requestWindowFeature(Window.FEATURE_NO_TITLE);

    // hide status bar
    final Window win = getWindow();
    win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
              WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_camera);

and the logcat:

08-23 08:56:20.174: E/AndroidRuntime(835): FATAL EXCEPTION: main
08-23 08:56:20.174: E/AndroidRuntime(835): java.lang.NullPointerException
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
com.example.i_kill.CameraPreview.surfaceCreated(CameraPreview.java:38)
08-23 08:56:20.174: E/AndroidRuntime(835):  at   
android.view.SurfaceView.updateWindow(SurfaceView.java:569)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.SurfaceView.access$000(SurfaceView.java:86)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.SurfaceView$3.onPreDraw(SurfaceView.java:174)
08-23 08:56:20.174: E/AndroidRuntime(835):  at   
android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:680)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1842)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.Choreographer.doCallbacks(Choreographer.java:562)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.Choreographer.doFrame(Choreographer.java:532)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.os.Handler.handleCallback(Handler.java:725)
08-23 08:56:20.174: E/AndroidRuntime(835):  at   
android.os.Handler.dispatchMessage(Handler.java:92)
08-23 08:56:20.174: E/AndroidRuntime(835):  at android.os.Looper.loop(Looper.java:137)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
android.app.ActivityThread.main(ActivityThread.java:5041)
08-23 08:56:20.174: E/AndroidRuntime(835):  at   
java.lang.reflect.Method.invokeNative(Native Method)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
java.lang.reflect.Method.invoke(Method.java:511)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-23 08:56:20.174: E/AndroidRuntime(835):  at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-23 08:56:20.174: E/AndroidRuntime(835):  at dalvik.system.NativeStart.main(Native  
Method)
08-23 08:56:26.065: E/Trace(909): error opening trace file: No such file or directory 

and here's the entire class: package com.example.i_kill;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;


public class CamActivity extends Activity {
public static final int MEDIA_TYPE_IMAGE = 1;
public static String TAG="MainActivity";
private static Camera camera;
private CameraPreview preview;
private ImageView head,body;
private ImageButton btn, stop;
private Button again,go;
private Bitmap bmp;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    // hide status bar
    final Window win = getWindow();
    win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
              WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_camera);

}
    public void setup()
    {

    preview = new CameraPreview(this);
    ((FrameLayout) findViewById(R.id.camera_preview)).addView(preview);
    head=(ImageView)findViewById(R.id.head);
        head.setX((float)(Shared.screenWidth/5*1.8));
        head.setY((float)(Shared.screenHeight*0.03));
        LayoutParams params = (LayoutParams) head.getLayoutParams();
        params.width = (int)((Shared.screenWidth/5*3.2)-(head.getX()));
        params.height=(int)((Shared.screenHeight/3.8)-(head.getY()));
        head.setLayoutParams(params);
    body=(ImageView)findViewById(R.id.body);
        body.setX((float)(Shared.screenWidth/7));
        body.setY((float)(Shared.screenHeight/3.8));
        LayoutParams params2 = (LayoutParams) body.getLayoutParams();
        params2.width = (int)((Shared.screenWidth/7*6)-(body.getX()));
        params2.height=(int)((Shared.screenHeight)-(body.getY()));
        body.setLayoutParams(params2);
    go=(Button)findViewById(R.id.go);
    again=(Button)findViewById(R.id.again);
    stop=(ImageButton)findViewById(R.id.stop);
    stop.setOnClickListener( new OnClickListener() {
        public void onClick(View v) {
            Intent i =new Intent(CamActivity.this,Main.class);
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
            startActivity(i);


        }
    });
    btn = (ImageButton) findViewById(R.id.takePic);
    btn.setOnClickListener( new OnClickListener() {
        public void onClick(View v) {
            preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
            btn.setVisibility(View.INVISIBLE);
            btn.setEnabled(false);
            go.setVisibility(View.VISIBLE);
            go.setEnabled(true);
            head.setVisibility(View.INVISIBLE);
            body.setVisibility(View.INVISIBLE);
            go.setOnClickListener( new OnClickListener() {
                public void onClick(View v) {
                    Shared.bm=Bitmap.createScaledBitmap(bmp, Shared.screenWidth, Shared.screenHeight, true);

                    Intent i=new Intent(CamActivity.this,IKill.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
                    startActivity(i);

                }
            });
            again.setVisibility(View.VISIBLE);
            again.setEnabled(true);
            again.setOnClickListener( new OnClickListener() {
                public void onClick(View v) {
                    if (Build.VERSION.SDK_INT >= 11) {
                        recreate();
                    } else {
                        Intent intent = getIntent();
                        overridePendingTransition(0, 0);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        finish();

                        overridePendingTransition(0, 0);
                        startActivity(intent);
                    }

                }
            });

        }
    });


}

ShutterCallback shutterCallback = new ShutterCallback() {
    public void onShutter() {
        Log.d(TAG, "onShutter'd");
    }
};

PictureCallback rawCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.d(TAG, "onPictureTaken - raw");
    }
};

/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        bmp=BitmapFactory.decodeByteArray(data, 0, data.length );
        System.out.println(bmp.getHeight());
        System.out.println(bmp.getWidth());
};
};


public void onPause(){
super.onPause();
if(camera!=null){
    camera.stopPreview();
    camera.setPreviewCallback(null);

    camera.release();
    camera = null;
}


}


public void onResume()
 {
super.onResume();
setup();
    }
}

and camera preview class:

package com.example.i_kill;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
public Camera camera;
public static String TAG="CameraPreview";
public CameraPreview(Context context) {
    super(context);

    holder=getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.

camera = getCameraInstance();

  try {

        camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {

    public void onPreviewFrame(byte[] data, Camera arg1) {
        FileOutputStream outStream = null;
        try {
            outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));  
            outStream.write(data);
            outStream.close();
            Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
            CameraPreview.this.invalidate();
    }
});
   } catch (IOException e) {
e.printStackTrace();
}

}

public void surfaceDestroyed(SurfaceHolder holder) {

if(camera!=null){
    camera.stopPreview();
    camera.setPreviewCallback(null);

    camera.release();
    camera = null;
}

}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = camera.getParameters();
  List<Size> previewSizes = parameters.getSupportedPreviewSizes();
  Size bestSize = null;
  int bestDiff = 0;
 int diff = 0;
  for (Size size : previewSizes) {
      diff = Math.abs(h - size.height) + Math.abs(w - size.width);
  if (bestSize == null || diff < bestDiff) {
          bestSize = size;
          bestDiff = diff;
  }
  parameters.setPreviewSize(bestSize.width, bestSize.height);
  camera.setParameters(parameters);
  }

      //start preview of camera
camera.startPreview();
}

@Override
public void draw(Canvas canvas) {
    super.draw(canvas);
    Paint p= new Paint(Color.RED);
    Log.d(TAG,"draw");
    canvas.drawText("PREVIEW", canvas.getWidth()/2, canvas.getHeight()/2, p );
}

private Camera getCameraInstance(){
Camera c = null;
try {
    c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
    // Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
}

Thanks for your help :)

like image 557
Misha Avatar asked Jan 13 '23 13:01

Misha


1 Answers

I solved it by calling setContentView on resume. Thank you all!

like image 100
Misha Avatar answered Jan 17 '23 06:01

Misha