Android camera preview vs background service - android

If I run an image processing app on Android, which will be better in terms of memory/cpu usage and heating issue?
Run camera with the preview.
Run camera in a background service. This says background service takes up a lot of memory( I used to think opposite ).
The reason I ask this is because I want to run the app 24/7, but I'm not sure which approach will be better with my purpose. I did test my app running camera with the preview and it stop due to heat after like 1 week.
Thanks.

The screen uses a lot of power, so leave it off if at all possible.
The camera API itself doesn't care if you're in a foreground app or in a background service, but the more simultaneous outputs you request, the higher the power consumption will likely be. Similarly, the higher the output resolutions you ask for are, the higher the power consumption.
You can have a foreground app with no preview, if you're using camera2; even with camera1, you can just add a dummy SurfaceTexture member to your activity/etc and set it as the preview target, so that you don't pay the cost of actual GPU activity.
That still has the overhead of the camera API pushing pointless images to that SurfaceTexture, which you can only avoid with camera2.

Obviously running camera continuously for a long time in preview mode made your device warm even if U have a high configuration device.In my suggestion You can tolerate the memory issue but not heating issue because it leads to many other harmful issue in your device(due to over heating).So go for background service,hope this will not heated your device as comparison to preview mode .

Related

ACTION_IMAGE_CAPTURE intent: Avoid Activity being destroyed / process being killed

This question is for Android developers who are familiar with the Activity Lifecycle.
I'm developing an app that performs face detection and facial landmark recognition.
The according machine learning models take a long time to be parsed from the SD storage and loaded into memory. On current average Android devices, it easily takes up to 20 seconds. By the way, all of this face analysis stuff and model loading happens in C++ native code, which is integrated using the Android NDK + JNI.
Because the model loading takes a long time, the actual parsing and loading is scheduled early in the background via AsyncTasks, so that the user does not notice a huge delay.
Before the actual face analysis is performed, the user can take a selfie via the MediaStore.ACTION_IMAGE_CAPTURE. This will call a separate camera app installed on the device and receive the picture via onActivityResult.
Now the problem starts: Almost always the whole app process will be killed while the user is in the separate camera Activity/App. Mostly it seems to happen right before returning from the Camera app (the timing seems odd). I did another test to confirm that it happens when the capture button is pressed inside the camer app. At that moment, my app is killed. When pressing the 'Accept image' button, the app is recreated. The reason given in logcat by the ActivityManager for the process kill is 'prev LAST' (I've found nothing via Google on the meaning of this, but I saw that many other apps are also killed with this reason, so it seems to happen quite often).
Thus, all of the Activities of my app need to be recreated by Android (fine by me, because it happens fast), but also the face analysis models must be loaded again from scratch, and the user will notice a huge delay before his selfie can be processed.
My question is: Is there any possibility to tell Android that an Activity/App has a legitimate reason to not be killed while being in the background temporarily to get a camera picture? After all, the ActivityManager makes a wrong decision to kill the app. Having to reload the models so frequently takes up a lot of CPU and memory resources.
It seems like an oversight in the Android lifecycle architecture. I know that few apps have the specific requirements of my app, but still, it seems stupid. The only way I can think of to 'fix' this issue is to implement my own camera Activity inside the app, but this goes counter Android's own best practices.
There is also some 'android:persistent' flag that you can stick to your Activity via AndroidManifest.xml, but the docs are totally unclear about the implications of this. See the docs on this.
By the way: onDestroy is not called when the app process is killed. I've read somewhere that there is no guarantee that onDestroy will be called, and this is actually not a problem for me. Although I wonder why the Android docs do not state this clearly.
Almost always the whole app process will be killed while the user is in the separate camera Activity/App
This is not surprising. A camera app can consume quite a bit of memory, so Android needs to free up memory by terminating background apps' processes.
After all, the ActivityManager makes a wrong decision to kill the app
Given that a likely alternative is the OS crashing, I suspect the user would agree with the OS decision to terminate your process.
Having to reload the models so frequently takes up a lot of CPU and memory resources.
Then perhaps you should not be starting another app from yours. Take the photo yourself. Use the camera APIs directly, or use libraries like Fotoapparat and CameraKit-Android as simpler wrappers around those APIs.
The only way I can think of to 'fix' this issue is to implement my own camera Activity inside the app, but this goes counter Android's own best practices.
By that argument, no devices would ever have a camera app, as writing any camera app "goes counter Android's own best practices".
Any app that needs a camera must use the camera APIs (directly or indirectly) to have any shot at reliable behavior. You are assuming that thousands of camera apps are all properly written and will correctly honor your ACTION_IMAGE_CAPTURE Intent (e.g., putting the results in the place that you designate with EXTRA_OUTPUT). Many camera apps have buggy ACTION_IMAGE_CAPTURE implementations. ACTION_IMAGE_CAPTURE is not unreasonable for cases where you and the user can live without the picture being taken (e.g., a note-taker app that has an "attach photo" feature), but that would not seem to be the case with your app.

Step Counter in Android: always on?

It is a well known issue that many Android phones switch off the accelerometer when the screen goes off. However something seems to have changed with Android Fit (the app). Fit keeps counting steps even when the screen goes off. If Fit is installed, then events are raised for step counting within the Fit environment and I am able to capture them using
Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
.setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
I have tested this on a Samsung S4 and on a Oneplus One and in both cases the steps are counted.
How do they do that? What Android classes do they use?
My understanding is that the available method introduced since Kitkat is to implement a SensorEventListener. For example theelfismike provides code that implements this. However on many phones the step counting stops when the screen goes off. Interestingly the counting does not seem to stop if the Google Fit app is installed (hence I guess they keep the accelerometer on).
Am I missing something? Is the functionality of keeping counting steps after screen off available to the mortal programmers?
Thanks!
As Ilja said, your code runs even after the screen gets turned off. But in this case I guess we need a little different answer.
They definitely use a Service that keeps a wakelock and they query the sensors for data. Important part here is holding the wakelock - you have to prevent the device from going into sleep during lifetime of your service - if you don't want to miss some data.
But this approach will be drain the battery really fast, because in order to detect steps you need to process quite a lot of data from sensors.
Thats why there is sensor batching. That allows you to get continuous sensor data even without keeping the device awake. It basically stores the sensor events in a hw based queue right in the chip itself and only sends them to your app (service,..) at predefined intervals in batches. This allows you to do a 24/7 monitoring without draining the battery significantly. Please note that only supported chipsets can do that (you can find details in Android docs), in case of older phones you need to fallback to the hideous wakelock keeping method in order to get your data.
You can also just use Google Fit APIs, but this would only work when there're both Google Fit + Google Play Services installed on the device with monitoring turned on.
Every normal Thread is keep on working when the screen goes off or when the Activity lost its focus...but when the activity gets killed then all thread are killed...
However you can use services for longrunning tasks like asking the accelerometer for example

Surfaceflinger notification

In the android displaying processes, SurfaceFlinger does an important role in that situation.
By the way, are there any methods to notice the SurfaceFlinger starting or stopping at the application level?
Or any other displaying processes to observe?
I want to know about the time difference between touching and displaying.
The SurfaceFlinger process does not start or stop while applications are running. If it does, the system restarts.
It sounds like you're interested in knowing the latency between when you touch the screen, and when the results of that touch are visible. You can use systrace to observe the various events, though this requires a fair understanding of the system. (Start with this doc.)
In general, an app can expect 2 to 2.5 frames of latency between cause and effect. On the N5, with the DispSync mechanism, this can be reduced to 1.5 - 2 frames.
There's no public API for 3rd party apps to access the surface flinger. If you are working at the platform level (your own device or custom ROM) then you'd have to add your own timing mechanism between the input subsystem and the surface flinger.

Android thread performance/priority on Galaxy Note 2 when screen is touched/released

I have an OpenGL game for Android. It runs at a good 60fps when the screen is touched. When I release my finger it goes back down to around 30fps. Does the touch event/release raise/lower a thread's priority and if so how can I replicate this to keep it at a constant 60fps. This only seems to be an issue on Galaxy Note 2 so far.
I'll assume you are using onDrawFrame and setRenderMode(RENDERMODE_CONTINUOUSLY).
30 and 60FPS indicates that your implementation of onDrawFrame is called as the device's screen refreshes. Most displays refresh at 60Hz, giving you 60FPS.
It is likely that the Galaxy Note 2 has some power saving feature that limits screen refresh to 30Hz when there are no touches on screen. Check if there's any way to disable this feature.
AFAIK, OpenGL ES does not specify a standard for screen refresh rates, you will need a throttling function to ensure that your game runs/feels the same (i.e. at the same speed) despite differences in FPS.
Yes.
The best way to observe this phenomena is to use systrace with the "freq" tag enabled. You probably need a rooted device, and you definitely need one on which systrace is enabled.
systrace will record changes in the clock frequency for various components. It varies by device, but you can usually get the per-core CPU clocks and GPU memory rate. You will likely see several of them drop significantly at the same time your frame rate drops.
The motivation for doing this is to reduce power requirements and extend battery life. The assumption is that, while your finger is in contact with the screen, you're actively doing something and the device should be as responsive as possible. After a brief period of time, the clocks will slow to a level appropriate for the current workload. The heuristics that determine how long to wait before slowing, and how much to slow down, are tuned for each device.
(This has caused some people to create a thread that just sits and spins on multi-core devices as a way to artificially prop up the CPU clock rate. Not recommended. See also this answer.)
The bottom line is that this isn't a simple matter of adjusting thread priorities. You have to choose between recognizing that the slowdown will happen and adapting to it (by making your game updates independent of frame rate), or figure out some way to fool the device into staying in a higher-power mode when you want smooth animation.
(For anyone who wants to play along at home: build a copy of Grafika and start the "Record GL app" activity. If you drag your finger around the screen all will be well, but if you leave it alone for a few seconds you may start to see the dropped-frame counter rising as the app falls behind. Seen on Nexus 5, Nexus 7 (2013), and others.)

Keep camera captured by an activity after picture taken

It is necessary for my application to keep the camera captured until released manually by an Activity (I realize this is bad practice, as no other applications will be able to use the camera). I used to be able to do this by avoiding the camera.release() call in the surfaceDestroyed function from CameraPreview, but this no longer works after 2.1.
Is there any way to keep the camera in captivity, without it being automatically released after surfaceDestroyed?
As a workaround question to answer instead of the previous one, is there any way to take a picture from within a service, without the preview view inflated?
You may be able to call camera.lock() to re-obtain the lock on the camera hardware. Failing that you can reopen the camera.
However, the drawback to this is much worse than preventing other apps from accessing the camera. This will also rapidly drain the battery, because it keeps the camera sensor and DSP powered. According to this thread, that could potentially kill a battery dead in two hours.

Categories

Resources