How to keep an application active in background - android

I am writing an application which can continuously monitor the input from mic, process it (Processing algorithms are written in C++) and save (log) or playback some events of interests. I am testing my app on Android L and Android M phones.
Application works fine as per my requirement with issue in following use case:
Turn the monitoring on
Press home button to send the app in background
Ensure device is not charging
Wait for some time
After some time (About 15 min) I get following message in logcat:
Suspending all threads...
To overcome the problem I tried following:
Hold wake locks (PARTIAL_WAKE_LOCK)
Use another level of thread spawning using an asynctask
Set FLAG_KEEP_SCREEN_ON in my activity
But none of them seem to work. On iOS I can achieve the desired functionality of this use case using highlighted flag in infoplist.
Is it possible to do something similar in Android? (I believe audio players already do something similar)

I hope this won't be a complete solution for you. But i will try to give a solution that will extend the lifetime of your application. First of all it is not possible to keep an application alive all the time. It is against the Android's rule, as when the system needs resource (for foreground app) it may stop your application. But you can extend the life time of an app by pushing the functionality into the service. Below is a solution for you.
Create an Activity which has 2 button to start and stop recording.
Create a Service and place a Public static variable as a flag set to either true or false.
In activity use the above static field to check if the service is active or not and enable or disable the start recording button according to it.
Use the button to start the service, inside the service acquire a Partial Wake Lock and start a Thread and do your recording. I hope you don't want to redeliver your Intent to the service as it is used to just start a thread for recording. You can use START_NOT_STICKY which restarts the service only if there is a pending start call. If you really wanted to redeliver your intent with recording and append it with the new one, i would say it is point less as you don't know when the service would be restarted and you may miss some recording at that time.
As you hold the partial wake lock it will continue to run until the Foreground app needs resource. As the service has higher priority than the background app.
In onDestroy()Stop the Thread by using the interrupt flag (Save recording too by checking the interrupt flag), set the public static field to FALSE and release the wake lock. You may start the recording from your activity when this is done.
By using FLAG_KEEP_SCREEN_ON in your activity you are just telling the system to "Keep the screen on when i am in this activity". If you hit home or switch to another activity it will not work. I hope games or apps like video players use this to keep the screen on.
I should also point that by keeping the Partial Wake Lock for longer time it may drain your battery considerably. Also you could advice your users to stay in the activity for continuous recording if you use the FLAG_KEEP_SCREEN_ON.
I would although advice to Start an Intent Service, acquire a partial wake lock and start recording. As it will stops the overhead for creating a new thread and starting or stopping it when needed.
Also in iOS, I think the system GC the APP for resources when your application shifts to the background. That's what i remember when i was learning iOS.
I hope my solution helped you little bit to extend your application's life time. Thank you

Related

Does service.startForeground imply wakelock?

Question
I am wondering if we need to aquire the WakeLock or if the service.startForeground() command does that anyway for us? I didn't find anything in the documentation.
Goal
We want to remove unnesessary stuff which might slow down the service start as we want to start capturing the sensor data as soon as possible and as the service might be restarted frequently.
Context
We're developing an Android library to capture sensor data with ~ 200 Hz for up to a couple of hours (research environment). Right now we aquire a WakeLock and start the capturing service as ForegroundService to make sure our capturing isn't stopped when the device is not used.
To answer my own question (if no one else finds more details on this):
In my understanding "foreground" just describes that the user would notice if the app was killed e.g. when browsing a large page. For this reason the system is asked to try to avoid killing the service.
Just because a foreground service is running probably not implies
that the CPU can't go into deep sleep mode.
In order to collect sensor data all the time from user-defined start to stop we still need to aquire the WakeLock ourselves.
No, wakelock can be used to make sure your foreground services run when device goes to sleep
If you must use partial wake locks, follow these recommendations:
Make sure some portion of your app remains in the foreground. For example, if you need to run a service, start a foreground service instead. This visually indicates to the user that your app is still running.
https://developer.android.com/topic/performance/vitals/wakelock#best_practices

Android: service looses sensor focus when activity is closed

I'm making an app where a background service does some stuff on some specific motion. At the moment I use a simple Service with a SensorEventListener attached to register the movement of the phone and to do the action I wanted it to do. Im also using an (optional) wakelock without any time limitations (but it gets unatached when the service is terminated) to ensure that the service is always accessable. I used the START_REDELIVER_INTENT to ensure a restart when the activity stops it when the user stops its (regularly via the ome button).
Now to my problem: When I stop the activity, the service gets terminated but only sometimes restarted (I dont know whether its not restarted or just doesnt get its sensorchanged called. I suspect last but I dont know for sure due to I only place a simple Sysout in the Sensorchanged method for testing).
Is there better and more efficient way to achive my goal (eg startForeground) and how can I ensure a continous aquiring of sensordata after an activity stop?
Services which need to run continuously have to be started with startForeground().
A positive sideeffect of this is that the user will be aware of your app using a sensor and can stop it if he runs low on battery.

Constant Android Service

I've been looking through many questions about services, but I couldn't find one that suited me.
I need a service that both starts on BOOT_COMPLETED (not bound to an Activity) and runs ALL the time (therefore I can't user AlarmReceiver). I know it might drain my battery but so far I don't care. It is just for research purposes.
I have a service that monitors sensor's data. What I managed to do so far was: either start the service as a regular Activity, but it runs only for +-20s and it is stopped (I think the SO cuts it down to release its memory); or start a service that runs in foreground. It worked to keep the process running, however the class that actually runs the service somehow was not started, besides an annoying notification which is required.
The code I refered as the one that runs the service in foreground was taken from here:
Implement startForeground method in Android
I mean, how does an app like WhatsApp run constantly? Is it running in foreground? Because looking at Settings it seems the service is very stable, and it does not show any permanent notification, since it is not possible for a foreground service run without one.
( How to startForeground() without showing notification? )
Any advice?
You can use a WakeLock. But please remember, with great power comes great responsibility (to release them again and not over-use them).
But for now, just acquire a hefty WakeLock and only release it until you are done. This should keep your device's screen and CPU awake and allow you to do whatever it is you want to do.

Android Connect to Running Thread

I am creating an app that has a UIThread and a background thread. The background thread is basically being used as a timer - every second it sends a message to the UIThread to update the UI. When the user exits the app by hitting the backbutton, the thread continues to run. I want this to happen since the user may want to open another app while the timer continues to count down.
My question is when the user comes back to my app. I want to connect to that background thread that is running to display the current state of the app - how much time is left, etc. My question is how to hook back in to the thread that is still running in the background. I have tried using Thread and AsyncTask, but the same issue occurs.
Thanks for any help that you can provide.
Your thread is still turning by sheer chance - your application is in fact still running but it and the thread will be shut down when Android decides it needs the resources.
However what you want to do is well-provided for in Android - you need to implement a Service to have a process that runs in the background separately from your application. You can even have a Service start at boot and run whether or not your application is started.
This http://developer.android.com/reference/android/app/Service.html has most of what you need to know. To communicate between the Service and a foreground Activity you'll need to bind to a service interface, which is fortunately very easily done.
First thing that comes to mind is to change your timer thread to a Service and have apps interested in it bind to that service. Based on the Android documentation and suggested app design, you cannot depend on that thread to not be killed by the OS whenever it deems necessary.
http://developer.android.com/guide/topics/fundamentals/services.html
The android system provides a broadcast event every minute, it's call TIME_TICK.
You should:
Create a service. This is the recommended way to have a part of the app running in the background
Listen to the TIME_TICK event. This will consume less battery. (It won't wake the phone, though, so use an ALARM, too)
Add an alarm (to wake the phone if necessary)
Let the UI and the service interact. You need a callback via rpc (see the last callback example on the api page)
You should also ensure that the phone can sleep during the timeframe. You thus may want to compute the state as a delta between the starting point and now, instead of updating the state all the time.

How to make a better battery-saving data update service for an android app

I am building an android app for fetching internet data and rendering it as a list. The data is changing every minute, so I made a service and used a Timer to load the data with an interval.
My question is that:
I want to know when the app (not a particular activity) goes to the background, for example, user pressed the home button, in that case, I want to pause the service in order to save battery.
I want to know when the phone is sleeping (screen dimmed), in that case, I would like to pause the service too.
Any ideas?
Pause your service in onPause (and resume in onResume).
Unless you have a wake lock, your app will not run when the phone is sleeping.
If you're bound to a foreground app, why use a service in the first place?
To elaborate on 1: I understand you're saying "app", not "a particular activity", but your best bet is to use Activity.onPause and Activity.onResume. If anything, you can add a short delay so that nothing happens if onPause is followed immediately by onResume.

Categories

Resources