0

I'm attempting to trigger a photo capture on a Nexus 5 (Android 4.4.3, stock) without triggering any UI or preview. I've seen several ways to do this on this site and others but they seem to be device specific or incompatible with the latest version of Android. I'm fairly new to Android development so I may be missing something rather basic and I would really appreciate any help provided.

Here's my code:

package com.example.omnisense;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.content.Intent;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Environment;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Sensor_Camera {
    private Camera mCamera;
    private Context context;
    private SurfaceView sv;
    private Parameters parameters;

    private int width;
    private int height;
    private Size size;

    public Sensor_Camera(Context c_){
        context = c_;
        sv = new SurfaceView(context);
        if (Camera.getNumberOfCameras() >= 2) {
            mCamera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
        } else {
            mCamera = Camera.open();
        }       


    }

    public void takePicture() {
        try {
            mCamera.setPreviewDisplay(sv.getHolder());
            parameters = mCamera.getParameters();
            size = parameters.getPictureSize();
            width = size.width;
            height = size.height;
            // Default picture format is NV21
            mCamera.setParameters(parameters);

            mCamera.startPreview();

            mCamera.takePicture(null,  null, mCall);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Camera.PictureCallback mCall = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(final byte[] data, Camera camera) {
                // Do Stuff
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
        }
    };      

}

Here are the questions / answers / blog posts I've found referencing this:

Invisible SurfaceView for Camera Preview

http://cell0907.blogspot.com/2014/01/android-camera-capture-without.html

Android: Take Photo Without User Interface

And here's the relevant logcat output:

06-09 01:25:22.831: D/Main(20056): onClick
06-09 01:25:22.831: D/Main(20056): testButton Click
06-09 01:25:23.111: D/Camera(20056): app passed NULL surface
06-09 01:25:23.121: D/AndroidRuntime(20056): Shutting down VM
06-09 01:25:23.121: W/dalvikvm(20056): threadid=1: thread exiting with uncaught exception (group=0x41d2bba8)
06-09 01:25:23.121: E/AndroidRuntime(20056): FATAL EXCEPTION: main
06-09 01:25:23.121: E/AndroidRuntime(20056): Process: com.example.omnisense, PID: 20056
06-09 01:25:23.121: E/AndroidRuntime(20056): java.lang.RuntimeException: takePicture failed
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.hardware.Camera.native_takePicture(Native Method)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.hardware.Camera.takePicture(Camera.java:1244)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.hardware.Camera.takePicture(Camera.java:1189)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at com.example.omnisense.Sensor_Camera.takePicture(Sensor_Camera.java:60)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at com.example.omnisense.MainActivity.testButtonPress(MainActivity.java:172)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at com.example.omnisense.MainActivity$2.onClick(MainActivity.java:235)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.view.View.performClick(View.java:4438)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.view.View$PerformClick.run(View.java:18422)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.os.Handler.handleCallback(Handler.java:733)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.os.Handler.dispatchMessage(Handler.java:95)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.os.Looper.loop(Looper.java:136)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at android.app.ActivityThread.main(ActivityThread.java:5017)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at java.lang.reflect.Method.invokeNative(Native Method)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at java.lang.reflect.Method.invoke(Method.java:515)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:133)
06-09 01:25:23.121: E/AndroidRuntime(20056):    at dalvik.system.NativeStart.main(Native Method)

In my main activity this class is used with the following code:

Sensor_Camera sense_camera = new Sensor_Camera(this);
sense_camera.takePicture();

I've added the uses-permission and uses-feature for the camera as well. I'm not really sure what the problem is, although I assume it has to do with using a null SurfaceView. Is there any workaround to this, or is it just impossible in 4.4?

If there's anything else I should post about my code, please let me know! Thanks in advance for any and all help.

Community
  • 1
  • 1

1 Answers1

0

Looking at the documentation, you're using the postview callback and they note

The postview callback occurs when a scaled, fully processed postview image is available (NOTE: not all hardware supports this).

It sounds like your device may not support that, so you'll probably need to go with the jpeg callback (the 4th optional parameter).