title: using internal camera through SurfaceView
body: <p>I am using internal camera through SurfaceView. but I have problem when I press Home Button and restart. I find a lot similar Questions. and I try many method but they can not fix.
  Maybe I miss something, So please help me. thanks
  I try method below list that can't fix NullPointerException
   1. thread method (it doesn't work)</p>
  
  <p>the LogCat show </p>
  
  <blockquote>
    <p>D/AndroidRuntime(571): Shutting down VM<br>
    W/dalvikvm(571): threadid=1: thread exiting with uncaught exception (group=0x409961f8)<br>
    E/AndroidRuntime(571): FATAL EXCEPTION: main<br>
    E/AndroidRuntime(571): java.lang.NullPointerException<br>
    E/AndroidRuntime(571):  at com.exampl.cameraexample.Preview.surfaceCreated(Preview.java:56)<br>
    E/AndroidRuntime(571):  at android.view.SurfaceView.updateWindow(SurfaceView.java:562)<br>
    E/AndroidRuntime(571):  at android.view.SurfaceView.access$000(SurfaceView.java:82)<br>
    E/AndroidRuntime(571):  at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:171)<br>
    E/AndroidRuntime(571):  at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:590)<br>
    E/AndroidRuntime(571):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1596)<br>
    E/AndroidRuntime(571):  at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)<br>
    E/AndroidRuntime(571):  at android.os.Handler.dispatchMessage(Handler.java:99)<br>
    E/AndroidRuntime(571):  at android.os.Looper.loop(Looper.java:137)<br>
    E/AndroidRuntime(571):  at android.app.ActivityThread.main(ActivityThread.java:4340)<br>
    E/AndroidRuntime(571):  at java.lang.reflect.Method.invokeNative(Native Method)<br>
    E/AndroidRuntime(571):  at java.lang.reflect.Method.invoke(Method.java:511)<br>
    E/AndroidRuntime(571):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    E/AndroidRuntime(571):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)<br>
    E/AndroidRuntime(571):  at dalvik.system.NativeStart.main(Native Method)              </p>
  </blockquote>
  
  <p>this is Mainactivity</p>
  
  <pre><code>package com.example.cameraexample;
  
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.sql.Date;
  import java.text.SimpleDateFormat;
  
  import android.annotation.SuppressLint;
  import android.app.Activity;
  import android.content.res.Configuration;
  import android.hardware.Camera;
  import android.hardware.Camera.PictureCallback;
  import android.os.Bundle;
  import android.os.Environment;
  import android.util.Log;
  import android.view.View;
  import android.widget.Button;
  import android.widget.FrameLayout;
  import android.widget.Toast;
  
  public class MainActivity extends Activity {
  private static final String TAG = "CameraDemo";
  public static final int MEDIA_TYPE_IMAGE = 1;
  public static final int MEDIA_TYPE_VIDEO = 2;
  
  private Camera mCamera;
  private Preview mPreview;
  //Button captureButton;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      setRequestedOrientation(1);
  
      //if (checkCameraHardware(this)) {
   // Create an instance of Camera
      //mCamera = getCameraInstance();
     // }
  
   // Create our Preview view and set it as the content of our activity.
     // mPreview = new Preview(this, mCamera);
     // FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
     // preview.addView(mPreview);
  
      // Add a listener to the Capture button
      Button 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);
              }
          }
      );
      Log.d(TAG, "onCreate");
  }
  
  @Override
  public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
    Log.d(TAG, "onConfigurationChanged");
  
  }
  
  
  /** A safe way to get an instance of the Camera object. */
  public static Camera getCameraInstance(){
      Camera c = null;
      try {
          c = Camera.open(); // attempt to get a Camera instance
          Log.d(TAG, "OPEN Camera!!!");
      }
      catch (Exception e){
          // Camera is not available (in use or does not exist)
          Log.d(TAG, "NULL Camera");
      }
      Log.d(TAG, "OPEN Camera");
      return c; // returns null if camera is unavailable
  
  }
  
  PictureCallback mPicture = new PictureCallback() {
      @Override
      public void onPictureTaken(byte[] data, Camera camera) {
  
          File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
          if (pictureFile == null){
              Log.d(TAG, "Error creating media file, check storage permissions: ");
              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());
          }
          mCamera.startPreview();
  
          Log.d(TAG, "onPictureTaken");
      }
  };
  
  /** Create a File for saving an image or video */
  @SuppressLint("SimpleDateFormat")
  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_PICTURES), "MyCameraApp");
      // This location works best if you want the created images to be shared
      // between applications and persist after your app has been uninstalled.
  
      // 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(type));
      File mediaFile;
      if (type == MEDIA_TYPE_IMAGE){
          mediaFile = new File(mediaStorageDir.getPath() + File.separator +
          "IMG_"+ timeStamp + ".jpg");
      } else if(type == MEDIA_TYPE_VIDEO) {
          mediaFile = new File(mediaStorageDir.getPath() + File.separator +
          "VID_"+ timeStamp + ".mp4");
      } else {
          return null;
      }
  
      return mediaFile;
  }
  
  @Override
  protected void onDestroy() {
   // TODO Auto-generated method stub
   super.onDestroy();
   Toast.makeText(this, "onDestroy", Toast.LENGTH_LONG).show();
   Log.d(TAG, "onDestroy");
  }
  
  @Override
  protected void onPause() {
      super.onPause();
      Toast.makeText(this, "onPause", Toast.LENGTH_LONG).show();
      releaseCamera();              // release the camera immediately on pause event
      Log.d(TAG, "onPause");
  }
  
  @Override
  protected void onRestart() {
   // TODO Auto-generated method stub
   super.onRestart();
   Toast.makeText(this, "onRestart", Toast.LENGTH_LONG).show();
   Log.d(TAG, "onRestart");
  }
  
  @Override
  protected void onResume() {
   // TODO Auto-generated method stub
   super.onResume();
   //if (checkCameraHardware(this)) {
   // Create an instance of Camera
      mCamera = getCameraInstance();
     // }
  
   // Create our Preview view and set it as the content of our activity.
      mPreview = new Preview(this, mCamera);
      FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
      preview.addView(mPreview);   
   Toast.makeText(this, "onResume", Toast.LENGTH_LONG).show();
   Log.d(TAG, "onResume");
  
  }
  
  @Override
  protected void onStart() {
   // TODO Auto-generated method stub
   super.onStart();
   Toast.makeText(this, "onStart", Toast.LENGTH_LONG).show();
   Log.d(TAG, "onStart");
  }
  
  @Override
  protected void onStop() {
   // TODO Auto-generated method stub
   super.onStop();
   Toast.makeText(this, "onStop", Toast.LENGTH_LONG).show();
   Log.d(TAG, "onStop");
  }
  
  private void releaseCamera(){
      if (mCamera != null){
          mCamera.release();        // release the camera for other applications
          mCamera = null;
      }
  }
  
  
  }
  </code></pre>
  
  <p>the other preview.java</p>
  
  <pre><code>package com.example.cameraexample;
  
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  
  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.os.Handler;
  import android.os.Message;
  import android.util.Log;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  import android.widget.Toast;
  
  public class Preview extends SurfaceView implements SurfaceHolder.Callback, Runnable {
  private static final String TAG = "Preview";
  
  private Thread thread;
  private boolean running;
  private SurfaceHolder mHolder;
  private Camera mCamera;
  
  @SuppressWarnings("deprecation")
  public Preview(Context context, Camera camera) {
      super(context);
      mCamera = camera;
      if(camera==null){
  
          Log.e("Camera","my camera is null...");
  
          }
      // Install a SurfaceHolder.Callback so we get notified when the
      // underlying surface is created and destroyed.
      mHolder = getHolder();
      mHolder.addCallback(this);
      // deprecated setting, but required on Android versions prior to 3.0
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      Log.d(TAG, "Preview");
  }
  
  public void surfaceCreated(SurfaceHolder holder) {
      // The Surface has been created, now tell the camera where to draw the preview.
  
  
      try {
          Log.d(TAG, "surfaceCreated STARTED");
          running = true;
          thread = new Thread(this, "himi_Thread_one");
          thread.start();
  
          mCamera.setPreviewDisplay(holder);
          mCamera.setDisplayOrientation(90);
          mCamera.startPreview();
      } catch (IOException e) {
          Log.d(TAG, "Error setting camera preview: " + e.getMessage());
      }
      Log.d(TAG, "surfaceCreated");
  }
  
  public void surfaceDestroyed(SurfaceHolder holder) {
      // empty. Take care of releasing the Camera preview in your activity.
       running = false;
      Log.d(TAG, "surfaceDestroyed");
  }
  
  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
      // If your preview can change or rotate, take care of those events here.
      // Make sure to stop the preview before resizing or reformatting it.
  
      if (mHolder.getSurface() == null){
        // preview surface does not exist
        return;
      }
  
      // stop preview before making changes
      try {
          mCamera.stopPreview();
      } catch (Exception e){
        // ignore: tried to stop a non-existent preview
      }
  
      // set preview size and make any resize, rotate or
      // reformatting changes here
  
      // start preview with new settings
      try {
          mCamera.setPreviewDisplay(mHolder);
          mCamera.setDisplayOrientation(90);
          mCamera.startPreview();
  
      } catch (Exception e){
          Log.d(TAG, "Error starting camera preview: " + e.getMessage());
      }
      Log.d(TAG, "surfaceChanged");
  }
  
  
  public void run() {
      while (running) {
          try {
              Thread.sleep(100);
          } catch (Exception ex) {
          }
      }
      Log.d(TAG, "RUN");
  }
  }
  </code></pre>
  
  <p>and AndoridMainfest.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.cameraexample"
  android:versionCode="1"
  android:versionName="1.0" &gt;
  
  &lt;uses-sdk
      android:minSdkVersion="8"
      android:targetSdkVersion="17" /&gt;
  &lt;uses-permission android:name="android.permission.CHANGE_CONFIGURATION"&gt;&lt;/uses-permission&gt;
  &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /&gt;
  &lt;uses-permission android:name="android.permission.CAMERA" /&gt;
  &lt;uses-feature android:name="android.hardware.camera" /&gt;  
  &lt;uses-feature android:name="android.hardware.camera.autofocus" /&gt; 
  &lt;application
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" &gt;
      &lt;activity
  
          android:name="com.example.cameraexample.MainActivity"
          android:label="@string/app_name" 
          android:configChanges="orientation|keyboard|keyboardHidden|screenSize"&gt;
          &lt;intent-filter&gt;
              &lt;action android:name="android.intent.action.MAIN" /&gt;
  
              &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
          &lt;/intent-filter&gt;
      &lt;/activity&gt;
  &lt;/application&gt;
  
  &lt;/manifest&gt;
  </code></pre>
  
  <p>the layout</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".MainActivity" &gt;
  
  &lt;FrameLayout
  android:id="@+id/camera_preview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:layout_weight="1"
  /&gt;
  
  &lt;Button
  android:id="@+id/button_capture"
  android:text="Capture"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center"
  /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>