App crashing while trying to take new photo

2019-08-29 13:30发布

问题:

I am developing a customized camera app. when app starts camera opens there are three buttons at bottom.

  1. Capture (To take picture).
  2. Take New (return from preview to camera to take picture again.)
  3. Not using for anything.

Everything works fine. pressing capture takes the picture and previews the taken picture accurately. But when I press take new button to come into camera mode from preview mode the app crashes don't have any idea what I am doing wrong. following is the code I am using.

public class MainActivity extends Activity {


   protected static final String TAG = null;
   private Camera mCamera;
    private CameraPreview mPreview;
    public static final int MEDIA_TYPE_IMAGE = 1;
    static int result;
    static int degrees = 90;
    private Button captureButton, btn_new;
    public FrameLayout preview;
    private static File mediaFile;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Create an instance of Camera
    mCamera = getCameraInstance();

    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);
     captureButton = (Button) findViewById(R.id.button_capture);
    captureButton.setOnClickListener(
        new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // get an image from the camera
                mCamera.takePicture(null, null, mPicture);
            }
        }
    );
    btn_new = (Button) findViewById(R.id.button_new);
    btn_new.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            mCamera = getCameraInstance();

            //preview = (FrameLayout) findViewById(R.id.camera_preview);
            //preview.addView(mPreview);
        }
    });

}

private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){

            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};

/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Camera");

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

    if (type == MEDIA_TYPE_IMAGE){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");
    } 
    else {
        return null;
    }

    return mediaFile;
}
@SuppressWarnings("null")
public static Camera getCameraInstance(){
    Camera c = null;
    Context context = null; 
    try{
        c = Camera.open();
        //setCameraDisplayOrientation(MainActivity, 0, c);
        c.setDisplayOrientation(degrees);
    }
    catch (Exception e) {
        Toast.makeText(context.getApplicationContext(),"Camera is not available" ,           Toast.LENGTH_LONG).show();

    }
    return c;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

}

Thanks in Advance. Finally here is my error logcat:


02-21 18:24:01.868: E/AndroidRuntime(937): FATAL EXCEPTION: main 02-21 18:24:01.868: E/AndroidRuntime(937): java.lang.NullPointerException 02-21 18:24:01.868: E/AndroidRuntime(937): at com.example.facebooktag.MainActivity.getCameraInstance(MainActivity.java:136) 02-21 18:24:01.868: E/AndroidRuntime(937): at com.example.facebooktag.MainActivity$3.onClick(MainActivity.java:66) 02-21 18:24:01.868: E/AndroidRuntime(937): at android.view.View.performClick(View.java:4202) 02-21 18:24:01.868: E/AndroidRuntime(937): at android.view.View$PerformClick.run(View.java:17340) 02-21 18:24:01.868: E/AndroidRuntime(937): at android.os.Handler.handleCallback(Handler.java:725) 02-21 18:24:01.868: E/AndroidRuntime(937): at android.os.Handler.dispatchMessage(Handler.java:92) 02-21 18:24:01.868: E/AndroidRuntime(937): at android.os.Looper.loop(Looper.java:137) 02-21 18:24:01.868: E/AndroidRuntime(937): at android.app.ActivityThread.main(ActivityThread.java:5039) 02-21 18:24:01.868: E/AndroidRuntime(937): at java.lang.reflect.Method.invokeNative(Native Method) 02-21 18:24:01.868: E/AndroidRuntime(937): at java.lang.reflect.Method.invoke(Method.java:511) 02-21 18:24:01.868: E/AndroidRuntime(937): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 02-21 18:24:01.868: E/AndroidRuntime(937): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 02-21 18:24:01.868: E/AndroidRuntime(937): at dalvik.system.NativeStart.main(Native Method)

回答1:

It might because of You have taken the photo first time succesfully and acquire the camera object then again you are acquiring the camera object here.

First instance here below setcontentview.

// Create an instance of Camera

mCamera = getCameraInstance();

and trying to acquire camera instance again but its already acquired.

btn_new = (Button) findViewById(R.id.button_new);
btn_new.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {

        mCamera = getCameraInstance();

        //preview = (FrameLayout) findViewById(R.id.camera_preview);
        //preview.addView(mPreview);
    }
});

Before acquire the camera object again you should have release the first one it.

if(mCamera != null)
   mCamera.release();

and

Make ensure you have declare permission in manifest before application tag.



回答2:

Well the null pointer exception is coming from your exception. you have

Context context = null; 

and then you are trying to use it here:

Toast.makeText(context.getApplicationContext(),"Camera is not available" ,           Toast.LENGTH_LONG).show();

without acutally initializing it anywhere.

Also in you onPause() function you should clean up after yourself. (eg. release camera, stop surface preview, that sort of thing).