2

I am creating an Android app and need a feature that takes photos without user interaction.

I simply want a class, for example, 'CameraService.java' that has a constructor that takes camera settings (eg. quality, res, etc) and a public function called 'takePhoto' which returns the image via type bitmap. I have been searching for a while to find out how I can do this using the Camera API 2 but have failed every time.

Most of the exemplars for doing this requires the camera to be made inside the MainActivity or in a class that extends Activity (I want to try to avoid this).

CameraService.java

I have utilized the following code found in a StackOverflow post (referenced below) which only saves the image to a hardcoded location (and uses Camera API 1) but I am experiencing errors.

package me.sam.camtest;
import android.hardware.Camera;
import android.util.Log;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CameraService {

    Camera mCamera;
    private int quality;

    public CameraService(int quality){
        this.quality = quality;
    }

    private int findBackFacingCamera() {
        int cameraId = -1;
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

    private boolean safeCameraOpen(int id) {
        boolean qOpened = false;

        try {
            releaseCamera();
            mCamera = Camera.open(id);
            qOpened = (mCamera != null);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return qOpened;
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }

    Camera.PictureCallback mCall = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outStream = null;
            try {
                outStream = new FileOutputStream("/sdcard/Image.jpg");
                outStream.write(data);
                outStream.close();
            } catch (FileNotFoundException e){
                Log.d("CAMERA", e.getMessage());
            } catch (IOException e){
                Log.d("CAMERA", e.getMessage());
            }
        }
    };

    public void takePhoto(){
        // Should return bitmap in future
        int back_cam = findBackFacingCamera();
        if(back_cam != -1){
            safeCameraOpen(1);
            mCamera.startPreview();
            mCamera.takePicture(null, null, mCall);
        }
    }
}

Runtime Error:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: me.sam.camtest, PID: 985
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{me.sam.camtest/me.sam.camtest.MainActivity}: java.lang.RuntimeException: takePicture failed
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
                      at android.app.ActivityThread.-wrap11(Unknown Source:0)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
                      at android.os.Handler.dispatchMessage(Handler.java:106)
                      at android.os.Looper.loop(Looper.java:164)
                      at android.app.ActivityThread.main(ActivityThread.java:6494)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
                   Caused by: java.lang.RuntimeException: takePicture failed
                      at android.hardware.Camera.native_takePicture(Native Method)
                      at android.hardware.Camera.takePicture(Camera.java:1588)
                      at android.hardware.Camera.takePicture(Camera.java:1530)
                      at me.sam.camtest.CameraService.takePhoto(CameraService.java:74)
                      at me.sam.camtest.Reply.<init>(Reply.java:47)
                      at me.sam.camtest.MainActivity.onCreate(MainActivity.java:80)
                      at android.app.Activity.performCreate(Activity.java:6999)
                      at android.app.Activity.performCreate(Activity.java:6990)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
                      at android.app.ActivityThread.-wrap11(Unknown Source:0) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
                      at android.os.Handler.dispatchMessage(Handler.java:106) 
                      at android.os.Looper.loop(Looper.java:164) 
                      at android.app.ActivityThread.main(ActivityThread.java:6494) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

I researched this error and it seemed that people could only fix it by adding a Surface View which required the CameraService to be an activity or passed a context (not what I want).

In conclusion, How could I achieve the following:

  • Have a simple camera class that has one public method, "takePhoto" which returns a bitmap
  • Avoid extending Activity or passing contexts in the simple camera class
  • Take the photo without user interaction (eg: intents)

PS: I am very new to the StackOverFlow community, I have tried to follow the guidelines with my best ability, please don't hate too much :)

My research:

SillySam
  • 98
  • 7

0 Answers0