3

For scientific measurements, I would like to access the camera frames from a service. The idea is to analyze the images coming from the camera in real-time under some conditions. Since the phone might be restarted or simply locked, it should be possible to start the process from a service.

For now, I was satisfied by using a Camera.Callback and the onPreviewFrame callback, but it appears that it only works if my application is running in foreground. More precisely, the camera requires a valid SurfaceView in order to call the onPreviewFrame function. And a SurfaceView created in an Activity is destroyed when the activity is minimized / finished.

I just cannot find a way to get the frames from a background process. Actually, it works on a Galaxy Note 10.1, but the Galaxy S4 requires a valid SurfaceView.

Is there a way to achieve this?

There are many topics about this on StackOverflow, but none worked for me.

JonasVautherin
  • 7,297
  • 6
  • 49
  • 95

2 Answers2

5

You can send the preview to a SurfaceTexture instead (setPreviewTexture()). This won't disappear when the app is paused. Requires API 11+.

You can see various applications of this technique in Grafika, which is generally doing video or GLES manipulation rather than stills, but the idea is similar.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Maybe you can help me for this one. I want to take pictures using this technique. So I call `takePicture(...)`, and in the callback I `setPreviewTexture(new SurfaceTexture(0))` and `startPreview()` again to continue the preview. It does not crash, but the image is not saved and I get the following error: `dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=11 undequeudCount=0)`. Do you have any idea about this? – JonasVautherin Jun 20 '14 at 12:37
  • 1
    You should file a new question. The dequeueBuffer complaint suggests a framework bug, so be sure to include details about the device and software version, and search up in the logcat output for any "interesting" messages... the "min undequeued buffer count" complaint may be the result of an earlier unhandled failure. – fadden Jun 20 '14 at 14:36
  • I filed a new question [here](http://stackoverflow.com/questions/24361121/take-picture-while-previewing-on-surfacetexture), but it did not draw a lot of attention. Hopefully the bounty will help =/. Thanks for the help anyway! – JonasVautherin Jun 25 '14 at 08:26
-1

I use this code my Spy Application for Live camera stream. (This for Xamarin, convert it to Java)

Firstly add permission:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Put this code into the your Foreground Service. With this code, SurfaceView works independently from Lifecycle of Activity

public void CamInService()
        {
            var layoutParams = new ViewGroup.LayoutParams(100, 100);
            var view = new SurfaceView(this)
            {
                LayoutParameters = layoutParams
            };
            view.Holder.AddCallback(new Prev()); //Replace with your preview callback
            WindowManagerLayoutParams winparam = new WindowManagerLayoutParams(WindowManagerTypes.SystemAlert);
            winparam.Flags = WindowManagerFlags.NotTouchModal;
            winparam.Flags |= WindowManagerFlags.NotFocusable;
            winparam.Format = Android.Graphics.Format.Rgba8888;
            winparam.Width = 1;
            winparam.Height = 1;

            IWindowManager windowManager = GetSystemService(WindowService).JavaCast<IWindowManager>();
            windowManager.AddView(view, winparam);
        }  

and call this method in OnCreate() method of Service or anywhere in the Application. For access from anywhere declare a variable in your foreground service class like this: public static ForegroundService _globalService; and access from anywhere like this: ForegroundService._globalService.CamInService();

Note: replace "ForegroundService" word with your Service class name.

enter image description here

0x000000F4
  • 60
  • 8