2

I am developing my own custom camera app,while running the application if I click the capture button my camera will capture the current position.what I actually need is retaking a photo whenever I need.But if I click the retake(take photo) button the app will crash.Here I attached my code below.So any one please help me to resolve the error.

MainActivity.java

package com.example.camera1;



import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

       private Camera cameraObject;
       private ShowCamera showCamera;
       private ImageView pic;
       private Button takePhotoButton;
       public static Camera isCameraAvailiable(){
          Camera object = null;
          try {

             object = Camera.open(); 
          }
          catch (Exception e){
          }
          return object; 
       }

       private PictureCallback capturedIt = new PictureCallback() {

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

          Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
          if(bitmap==null){
             Toast.makeText(getApplicationContext(), "not taken", Toast.LENGTH_SHORT).show();
          }
          else
          {
             Toast.makeText(getApplicationContext(), "taken", Toast.LENGTH_SHORT).show();       
          }
          cameraObject.release();
       }
    };

       @Override
       protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);    
          takePhotoButton = (Button)findViewById(R.id.button_takephoto);
          cameraObject = isCameraAvailiable();
          showCamera = new ShowCamera(this, cameraObject);
          FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
          preview.addView(showCamera);



          takePhotoButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                  cameraObject = isCameraAvailiable();

                  cameraObject.stopPreview();
                    showCamera = new ShowCamera(getApplicationContext(), cameraObject);
                      FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
                      preview.addView(showCamera);
            }
        });

       }
       public void snapIt(View view){
          cameraObject.takePicture(null, null, capturedIt);
       }

       @Override
       public void onPause(){
           super.onPause();
       }

       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
          getMenuInflater().inflate(R.menu.activity_main, menu);
          return true;
       }
    }

ShowCamera.java

package com.example.camera1;

import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback {

       private SurfaceHolder holdMe;
       private Camera theCamera;

       public ShowCamera(Context context,Camera camera) {
          super(context);
          theCamera = camera;
          holdMe = getHolder();
          holdMe.addCallback(this);
       }

       @Override
       public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
       }

       @Override
       public void surfaceCreated(SurfaceHolder holder) {
          try   {
              theCamera.setDisplayOrientation(90);
             theCamera.setPreviewDisplay(holder);
             theCamera.startPreview(); 
          } catch (IOException e) {
          }
       }

       @Override
       public void surfaceDestroyed(SurfaceHolder arg0) {

           theCamera.stopPreview(); 
       }

    }

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="horizontal" >

   <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="0.30"
      android:orientation="vertical" >

         <FrameLayout
            android:id="@+id/camera_preview"
            android:layout_width="fill_parent"
            android:layout_height="350dp" />

         <RelativeLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content" >

             <Button
                 android:id="@+id/button_capture"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:onClick="snapIt"
                 android:text="@string/Capture" />

             <Button
                 android:id="@+id/button_takephoto"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_below="@+id/button_capture"
                 android:text="Take Photo" />
         </RelativeLayout>

   </LinearLayout>

</LinearLayout>
Manoj
  • 3,947
  • 9
  • 46
  • 84

2 Answers2

3

I think the reason is you called cameraObject.release(); in onPictureTaken. You can remove it. And, don't forget to call startPreview() again.

Because:

This method is only valid when preview is active (after startPreview()). Preview will be stopped after the image is taken; callers must call startPreview() again if they want to re-start preview or take more pictures. This should not be called between start() and stop().

After calling this method, you must not call startPreview() or take another picture until the JPEG callback has returned.

yushulx
  • 11,695
  • 8
  • 37
  • 64
  • after I commented `cameraObject.release();` this line in `PictureCallback` and also `cameraObject.stopPreview();` in `takePhotoButton.setOnClickListener(OnClickListener l)` if i click take photo the app won't crash but no changes in app(captured image is still there in camera screen). – Manoj May 28 '14 at 06:13
  • Have you called startPreview()? After taking one picture, you have to call startPreview again for more. – yushulx May 28 '14 at 06:19
  • I am using these set of code for again capturing a image `showCamera = new ShowCamera(getApplicationContext(), cameraObject); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(showCamera);` – Manoj May 28 '14 at 06:26
  • ShowCamera.java class contains `theCamera.startPreview();` inside `surfaceCreated()` method. – Manoj May 28 '14 at 06:28
  • You don't need to write code for the new capturing. Just re-use the code you've written to activate the preview again. – yushulx May 28 '14 at 06:29
  • now I called only `cameraObject.startPreview();` for retake it is working good..I can retake many times as per I need. – Manoj May 28 '14 at 06:43
  • @ yushulx I have one question,I tried to capture a image from my front camera when press the retake button.so I called `cameraObject.open(1);` before calling `cameraObject.startPreview();` but the app crashed. – Manoj May 28 '14 at 11:31
  • could you start a new question and post your crash log? – yushulx May 29 '14 at 05:27
0
cameraObject.release();

Remove this line from tour PictureCallback. Now you know reason your app crash is quite straight to me , you are not start camera and preview also after you capture image. Preview is something stop after you call PictureCallback ,you have resume it manually.

IF you dont want to manage this thing then i can advise you to use cwac-camera library which is simply awesome. All you need to do is extend your Fragment by CameraFragment and it will take your responsibility to manage this stuff .

Enjoy !

dharmendra
  • 7,835
  • 5
  • 38
  • 71