1

I am having problems to understand the logcat of my application that crushes. (I am a beginner and my app just takes a picture and then saves it in a specific folder, but when I hit the button that should allow me to take a picture, it crashes and I get the famous message ( MY_APP_Name is not responding)

here is the code in MySurfaceView.java

package android.cam_bouton_save;



private SurfaceHolder holder;
private Camera camera;

public MySurfaceView(Context context, Camera camera)
{
    super(context);
    this.camera = camera;
    holder = getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceChanged(SurfaceHolder holder, 
        int format, int weight, int height)
{
    if (holder.getSurface() == null)
        return;
    try
    {
        camera.stopPreview();
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    }
    catch (Exception e){}
}

public void surfaceCreated(SurfaceHolder holder)
{
    try
    {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    }
    catch (IOException e){}
}

public void surfaceDestroyed(SurfaceHolder holder){}

}

this is the log cat :

05-14 17:15:04.216: E/AndroidRuntime(1123): FATAL EXCEPTION: main
05-14 17:15:04.216: E/AndroidRuntime(1123): java.lang.NullPointerException
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.cam_bouton_save.MySurfaceView.surfaceCreated(MySurfaceView.java:42)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.SurfaceView.updateWindow(SurfaceView.java:532)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.SurfaceView.dispatchDraw(SurfaceView.java:339)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.View.draw(View.java:6743)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.View.draw(View.java:6743)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.widget.FrameLayout.draw(FrameLayout.java:352)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1842)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewRoot.draw(ViewRoot.java:1407)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.os.Looper.loop(Looper.java:123)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at android.app.ActivityThread.main(ActivityThread.java:4627)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at java.lang.reflect.Method.invokeNative(Native Method)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at java.lang.reflect.Method.invoke(Method.java:521)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
05-14 17:15:04.216: E/AndroidRuntime(1123):     at dalvik.system.NativeStart.main(Native Method)

can you help me please?

    package android.cam_bouton_save;
      public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        Button bouton = (Button) findViewById(R.id.btn_photo);
    //  camera = Camera.open();
        mySurfaceView = new MySurfaceView(this, camera);
        final FrameLayout myPreview = (FrameLayout) findViewById(R.id.preview);
        myPreview.addView(mySurfaceView);

        bouton.setOnClickListener(new View.OnClickListener()  {
      //  @Override
         public void onClick(View actuelView)   {
            /* //camera.open();
            // camera.getParameters();*/

            camera = Camera.open();

        /*   camera = Camera.open();
             Parameters parameters = camera.getParameters();
             parameters.setPictureFormat(PixelFormat.JPEG);
             camera.setParameters(parameters);
            // camera.setPreviewDisplay(surfaceHolder);
             camera.startPreview();*/
            camera.takePicture(shutterCallback, rawCallback, myPictureCallback_JPG);
         } 
      });

    }


      // Called when shutter is opened
      ShutterCallback shutterCallback = new ShutterCallback() {
          public void onShutter() {
             //Log.d(TAG, "onShutter'd");
      }
    };

        PictureCallback rawCallback = new PictureCallback() {
            public void onPictureTaken(byte[] data, Camera camera) {
      } 
    };

        PictureCallback myPictureCallback_JPG = new PictureCallback(){
            public void onPictureTaken(byte[] arg0, Camera arg1) {

                int imageNum = 0;
                Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

                //Gets the Android external storage directory
                File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Punch");
                imagesFolder.mkdirs(); // <----
                String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
                File output = new File(imagesFolder, fileName);
                while (output.exists()){
                    imageNum++;
                    fileName = "image_" + String.valueOf(imageNum) + ".jpg";
                    output = new File(imagesFolder, fileName);
                }
                Uri uriSavedImage = Uri.fromFile(output);
                imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);


                OutputStream imageFileOS;
                try {
                    imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
                    imageFileOS.write(arg0);
                    imageFileOS.flush();
                    imageFileOS.close();

                    Toast.makeText(Cam_bouton_save_picActivity.this, 
                            "Image saved: ", 
                            Toast.LENGTH_LONG).show();
                    camera.release() ;
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

         //       camera.startPreview();
            }};
}           
Sdig Sadok
  • 11
  • 5

1 Answers1

1

Your LogCat says you are getting a NullPointerException in line 36 of your activity class, inside the onClick method: m Cam_bouton_save_picActivity.java:36.

Just a guess, but perhaps your Camera instance is null. This occurs most often because of a missing permission in the androidManifest.xml, so please make sure you've included it:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Also note, that if you want to save the photos taken to the SD card, you'll need an other permission as well:

<uses-permission android:name="android.permission.CAMERA" />

Edit 1: Thans for the code!

Now it is obvious, that you need to initialize your camera member! Without initializing it that's the weak point that ends up in a NullPointerException.

In your onCreate method you should have this line:

camera = Camera.open();

If performed correctly, you won't get the NPE anymore.

Edit 2: For a camera preview: -removed-

Edit 3: Please -in future- ask new questions if you are facing a new problem and need help, instead of modifying your existing question. This answer already has nothing to do with your original question.

Keep in mind, that StackOverflow is about answers to specific problems, not about solving all the problems of particular people.

Here is a small and very focused sample application that shows how you can take consecutive camera shots and save them on the sd card:

public class AndroidCamera extends Activity implements 
    SurfaceHolder.Callback, View.OnClickListener
{
    private static final String TAG = "CS";
    private Camera camera;
    private SurfaceView surface;
    private SurfaceHolder holder;
    private boolean isPreview = false;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        surface = (SurfaceView) findViewById(R.id.preview);
        holder = surface.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        final Button shotButton = (Button) findViewById(R.id.btn_shot);
        shotButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v)
    {
        camera.takePicture(shutterCallback, rawCallback, jpgCallback);
    }

    ShutterCallback shutterCallback = new ShutterCallback()
    {
        @Override
        public void onShutter()
        {}
    };

    PictureCallback rawCallback = new PictureCallback()
    {
        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1)
        {}
    };

    PictureCallback jpgCallback = new PictureCallback()
    {
        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1)
        {
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
            {
                final String imageDir =
                        Environment.getExternalStorageDirectory() + 
                        File.separator + "Punch" + File.separator;
                int counter = 0;
                String imageName = "image_" + counter + ".jpg";
                File outputFile = new File(imageDir, imageName);
                if (!outputFile.getParentFile().exists())
                    outputFile.getParentFile().mkdirs();
                while (outputFile.exists())
                {
                    counter++;
                    imageName = "image_" + counter + ".jpg";
                    outputFile = new File(imageDir, imageName);
                }
                Uri uriSavedImage = Uri.fromFile(outputFile);
                OutputStream imageFileOS;
                try
                {
                    imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
                    imageFileOS.write(arg0);
                    imageFileOS.flush();
                    imageFileOS.close();

                    Log.w(TAG, "Image saved: " + uriSavedImage.toString());
                    camera.startPreview();
                }
                catch (FileNotFoundException e)
                {
                    Log.e(TAG, "onPictureTaken", e);
                }
                catch (IOException e)
                {
                    Log.e(TAG, "onPictureTaken", e);
                }
            }
        }
    };

    @Override
    public void surfaceChanged(SurfaceHolder sHolder, int format, int width, int height)
    {
        if (isPreview)
        {
            try
            {
                camera.stopPreview();
                isPreview = false;
            }
            catch (Exception e)
            {
                Log.e(TAG, "surfaceChanged", e);
            }
        }

        if (camera != null)
        {
            try
            {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
                isPreview = true;
            }
            catch (IOException e)
            {
                Log.e(TAG, "surfaceChanged", e);
                releaseCamera();
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        try
        {
            camera = Camera.open();
        }
        catch (Exception e)
        {
            Log.e(TAG, "surfaceCreated Camera.open()", e);
            releaseCamera();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        releaseCamera();
    }

    private void releaseCamera()
    {
        try
        {
            camera.stopPreview();
            camera.release();
            camera = null;
            isPreview = false;
        }
        catch (Exception e)
        {
            Log.e(TAG, "releaseCamera", e);
        }
    }
}

For this you only need a very simple layout (main.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <SurfaceView android:id="@+id/preview"
        android:layout_width="fill_parent" android:layout_height="wrap_content"/>
    <Button android:id="@+id/btn_shot" android:text="Shot!"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

I hope it's clear enough :)

rekaszeru
  • 19,130
  • 7
  • 59
  • 73
  • Thanks everyone for your help. I have already those permissions in my manifest.xml file, and the problem is always there. – Sdig Sadok May 14 '12 at 15:07
  • this is my line 36 where the error occurs : camera.takePicture(shutterCallback, rawCallback, myPictureCallback_JPG); – Sdig Sadok May 14 '12 at 15:08
  • I wish i had found a solution. I did not yet :( – Sdig Sadok May 14 '12 at 15:09
  • yes i ll share it on the spot. Am just having some problems to post it because of the indentation :) – Sdig Sadok May 14 '12 at 15:12
  • done ! that's my poor activity that I which to correct so that I can take a picture and save it in a a specific new folder that i create – Sdig Sadok May 14 '12 at 15:15
  • That's ok, the problem is that your `Camera` instance is null. You need a call for opening it. Please see my update. – rekaszeru May 14 '12 at 15:19
  • I have even added this line in the manifest but I am having the same error while running in my emulator – Sdig Sadok May 14 '12 at 15:20
  • Oh my god! thanks I am not taling the error anymore! but it s bizarre ! the picture can be taken just once. If I try a second time it crushes. – Sdig Sadok May 14 '12 at 15:27
  • I guess i need to release the camera so that I do not have that error. But I have another question: how can I use thesetPreviewDisplay(SurfaceHolder) because I think that without a surface, the camera will be unable to start the preview before taking a picture. – Sdig Sadok May 14 '12 at 15:30
  • I have edited the code aand the log cat so that i can share it with everybody. – Sdig Sadok May 14 '12 at 15:40
  • I have corrected it ! I just had to add this line camera.release() ; after the toast Now I can take all the pictures I want with my button, but I need to know please How to open a surface preview before taking the picture Thanks from the bottom of my heart – Sdig Sadok May 14 '12 at 15:43
  • I am working on it, but I did not really understand what you said. sorry – Sdig Sadok May 14 '12 at 16:07
  • thanks for your help, I am trying adding your code in mine right now. – Sdig Sadok May 14 '12 at 16:31
  • maybe my question is silly but who is R.id.preview in this line: final FrameLayout myPreview = (FrameLayout) findViewById(R.id.preview); – Sdig Sadok May 14 '12 at 16:37
  • it should be a `FrameLayout` with `@+id='preview'` inside your `main.xml` layout. In other words it's the placeholder for the preview. – rekaszeru May 14 '12 at 16:54
  • I have updated my code after adding the class MySurfaceView and the log cat I am having this time. I tried to correct it my self but i really need your help please – Sdig Sadok May 14 '12 at 17:14
  • you shouldn't remove your existing question, since StackOverflow is for answers not for particular people's problem, and this way your question might never be answered. :( What is the code in the `surfaceCreated(MySurfaceView.java:42`? Logcat shows there occurs a NPE. – rekaszeru May 14 '12 at 17:24
  • What is the code in the surfaceCreated(MySurfaceView.java:42? Logcat shows there occurs a NPE. – rekaszeru May 14 '12 at 17:32
  • I have udded the code of MySurfaceView.java (i have not added the import android.etc ) – Sdig Sadok May 14 '12 at 17:34
  • i will check that, this evening after the end of my courses and i will keep you in touch. thanks a lot – Sdig Sadok May 15 '12 at 11:27
  • 1
    Hello rekaszeru, I am going to check ur update right now, sorry for delay, I had a lot of exams :( – Sdig Sadok May 17 '12 at 09:06
  • I'm more than glad you made it! congrats! :) – rekaszeru May 17 '12 at 09:51