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.