0

I have a problem with the takePicture(); method in Android Studio. I have seen many tutorials, but none of them helped me. Please help me :0 Here is my code:

Button button;
Camera cam = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    cam = Camera.open();

    button = (Button) findViewById(R.id.getrange);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            cam.startPreview();
            cam.takePicture(null, null, null, mPicture);
        }
    });

}

public static Camera.PictureCallback mPicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File dir = new File(Environment.getExternalStorageDirectory(), "Bewegungsmelder-App");
        dir.mkdirs();

        File file = new File(dir, "IMG_" + System.currentTimeMillis() + ".jpg");

        if (file == null) {
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
    }
};

@Override
protected void onPause() {
    super.onPause();

    cam.stopPreview();
    cam.release();
    cam = null;
}

@Override
protected void onResume() {
    super.onResume();

    cam = Camera.open();
}

The Manifest-Permissions:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

and here the error-code:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: degaming.bewegungsmelder, PID: 12580
              java.lang.RuntimeException: takePicture failed
                  at android.hardware.Camera.native_takePicture(Native Method)
                  at android.hardware.Camera.takePicture(Camera.java:1711)
                  at degaming.bewegungsmelder.MainActivity$1.onClick(MainActivity.java:36)
                  at android.view.View.performClick(View.java:5642)
                  at android.view.View$PerformClick.run(View.java:22338)
                  at android.os.Handler.handleCallback(Handler.java:751)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6209)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Thx for your help D:
PS: Bewegungsmelder is german. It means motion detector!

1 Answers1

0

Call startPreview in your onPictureTaken method in addition to calling it in your onClick,

public static Camera.PictureCallback mPicture = new Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        File dir = new File(Environment.getExternalStorageDirectory(), "Bewegungsmelder-App");
        dir.mkdirs();

        File file = new File(dir, "IMG_" + System.currentTimeMillis() + ".jpg");
        if (file == null) {
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }
        camera.startPreview();
    }
};

The reason is that once you take a picture, the current preview is destroyed so that the next time you take a picture you need to start it again.

EDIT: Well another important thing you've forgotten besides calling startPreview before calling takePicture is that, according to Android documentation point #5, you didn't pass a surfaceHolder to setPreviewDispaly(SurfaceHolder). First, add a SurfaceView to your XML layout and set the id to preview. Second, add a SurfaceHolder variable and a SurfaceView variable to the top of your class,

SurfaceHolder surfaceHolder;
SurfaceView surfaceView;

Then in your onCreate, initialize the variables like so,

surfaceView = (SurfaceView) findViewById(R.id.preview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(surfaceCallback);    
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

Now, make the callback for surfaceHolder,

SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback(){

    public void surfaceCreated(SurfaceHolder holder) {     
        try {        
            cam.setPreviewDisplay(surfaceHolder); 
        } catch (Throwable t) {   

        }     
    }      

    public void surfaceChanged(SurfaceHolder holder,int format, int width,int height) {
        Camera.Parameters params = cam.getParameters();       
        params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
        Camera.Size size = getBestPreviewSize(width, height, params);  
        Camera.Size pictureSize = getSmallestPictureSize(params);
        if (size != null && pictureSize != null) {      
            params.setPreviewSize(size.width, size.height);
            params.setPictureSize(pictureSize.width,
                    pictureSize.height);
            cam.setParameters(params);       
            cam.startPreview();                      

        }     
    }      

    public void surfaceDestroyed(SurfaceHolder holder) {
        cam.stopPreview();
    }   
};

After all of this, I don't believe you need the startPreview call in your onClick. However, I think in order for this to work you may have to make cam a static variable as well as other variables. Not 100% sure on this.

Chris Gong
  • 8,031
  • 4
  • 30
  • 51
  • @DEGaming does this happen specifically when you click the button for the first time? does it ever get to the point where the camera screen opens? – Chris Gong Feb 26 '17 at 18:42
  • It happened at the first time –  Feb 26 '17 at 18:45