5

The only code I have been able to get working to take a picture with the camera runs from an activity. I am fairly certain that it is possible to take a photo from within a service, or from an AsyncTask launched by the service.

It seems to me that the camera API needs a SurfaceView which must be tied into a UI. Maybe I am wrong. Has anyone written code where a photo can be taken from a service?

Johann
  • 27,536
  • 39
  • 165
  • 279

3 Answers3

5

It's possible by using WindowManager in Android.

https://stackoverflow.com/a/10268650/3047840

I should say yes you need SurfaceView to take a picture but it does not have to be tied to a certain xml layout. You can add it to the WindowManager class which works even in the Service. So the WindowManager here opens a 'window' for you to do any floating effect in Android.

Specifically,

You can add a SurfaceView into the WindowManager and set the parameters as following.

mPreview = new CameraPreview(this, mCamera, jpegCallback);
WindowManager wm = (WindowManager) this
        .getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
        PixelFormat.TRANSPARENT);

params.height = 1;
params.width = 1;

wm.addView(mPreview, params);

Android has this functionality while iOS doesn't. This is why you can have Facebook chathead active on the home screen in Android rather than iOS.

Show facebook like chat head from a broadcast receiver in android

Community
  • 1
  • 1
Fanglin
  • 2,132
  • 1
  • 21
  • 26
  • 4
    It's important to note that this method requires the android.permission.SYSTEM_ALERT_WINDOW permission, which users may take issue with. – yincrash Jan 15 '14 at 19:26
  • This worked for me, although your code sample is missing some essential parts. – Sam Nov 22 '14 at 23:09
  • @Sam care to add the missing essential parts? – Gichamba Aug 14 '16 at 19:20
  • @Ben, I can't remember what they were. But see my answer to the original question for a complete example: http://stackoverflow.com/a/27083867/238753 – Sam Aug 15 '16 at 00:20
3

Here's some more complete code if you are still looking. Works in a service (tested):

private void takePhoto() {

    System.out.println( "Preparing to take photo");
    Camera camera = null;

    int cameraCount = 0;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
        SystemClock.sleep(1000);

        Camera.getCameraInfo(camIdx, cameraInfo);

            try {
                camera = Camera.open(camIdx);
            } catch (RuntimeException e) {
                System.out.println("Camera not available: " + camIdx);
                camera = null;
                //e.printStackTrace();
            }
        try{
            if (null == camera) {
                System.out.println("Could not get camera instance");
            }else{
                System.out.println("Got the camera, creating the dummy surface texture");
                //SurfaceTexture dummySurfaceTextureF = new SurfaceTexture(0);
                try {
                    //camera.setPreviewTexture(dummySurfaceTextureF);
                    camera.setPreviewTexture(new SurfaceTexture(0));
                    camera.startPreview();
                } catch (Exception e) {
                    System.out.println("Could not set the surface preview texture");
                    e.printStackTrace();
                }
                camera.takePicture(null, null, new Camera.PictureCallback() {

                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        File pictureFileDir = getDir();
                        if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
                            return;
                        }
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
                        String date = dateFormat.format(new Date());
                        String photoFile = "PictureFront_" + "_" + date + ".jpg";
                        String filename = pictureFileDir.getPath() + File.separator + photoFile;
                        File mainPicture = new File(filename);
                        addImageFile(mainPicture);

                        try {
                            FileOutputStream fos = new FileOutputStream(mainPicture);
                            fos.write(data);
                            fos.close();
                            System.out.println("image saved");
                        } catch (Exception error) {
                            System.out.println("Image could not be saved");
                        }
                        camera.release();
                    }
                });
            }
        }catch (Exception e){
            camera.release();
        }


    }
john
  • 1,561
  • 3
  • 20
  • 44
Josh
  • 39
  • 2
  • From my experiments, the dummy `SurfaceTexture` workaround worked on Nexus 4 and HTC One m8 but it failed on Nexus 5 :( – dzeikei Jun 04 '14 at 05:57
  • What was the issue you were getting while trying in Nexus 5? – venkat Nov 19 '14 at 22:01
  • This doesn't work on my Sony Xperia M running Android 4.3 because of the dummy `SurfaceTexture` technique. – Sam Nov 22 '14 at 23:08
-3

I don't think this is possible as the camera needs a preview screen. See similar question here

Community
  • 1
  • 1
Gridtestmail
  • 1,459
  • 9
  • 10
  • It is possible to do it with *effectively* no preview, as shown in the question you linked. – Sam Nov 22 '14 at 23:07
  • @Gridtestmail then how the app taking picture without user knowledge? . They started a service to take picture and using dummy surface view/ Surface texture . https://play.google.com/store/apps/details?id=com.zenaapps.backgroundcamera . How can we achieve the same ? could you provide any code sample , if you have any? – Karthikeyan Ve Aug 18 '15 at 12:44