Android: service looses sensor focus when activity is closed - android

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.

Related

My Service is idling when the device goes into power saving mode

I'm currently struggling to keep my service alive when trying to get information about the user for a study. We are using a foreground service, which runs a timer on a 5-sec interval checking a resource of the user. As that resource is only relevant if the screen is on, we could stop the timer whenever the screen goes off. For this, we are using a broadcast service. All in all, this works well. The problem occurs, if the user closes the app and then puts the device on standby -> screen goes off. We would like to stop the timer and restart the timer inside that service if the screen goes on again. Now theoretically that works. I tested it with a counter variable which increments each time the run is called inside the timer. After that, I update my notification and show that variable. If however I close the app and the screen goes off, this variable is no longer updated in the notification and ergo, my resource check is not running. But I found out, that once I restart the app, the variable did indeed increase every 5sec and is then updated in the notification again. Furthermore, it is working if the device is on power/getting charged. So I guess it is a power management thing.
Summary: The ForegroundService/BroadcastReceiver is not acting like I would want to if the app is closed and the screen goes off, even though a part of it is working as intended. Works completely if the device is charging.
Do you have any ideas on how to avoid this behavior and allow the service to rerun the timer correctly so that the methods inside will work again?
Best regards,
Yukko

How to keep an application active in background

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

Android KitKat: Implement a background service to do something when an application is unloaded (or loses foreground)

I want to implement a service (or similar) on Android KitKat (4.4.2) in order to detect which is the foreground app and make something depending on which app it is "foregrounded".
I have read a lot of threads about determining which is the app is the foregound ON THAT MOMENT (https://stackoverflow.com/a/14044662/1683141). But I'm not able to see any thread about keeping this service continuosly monitoring in order to detect any changes on foreground. Kind of loop? Event registering?
For example, I want to be notified when LINE (messaging app) has or loses foreground. So I suppose the service has to be registered to some kind of event (I think Broadcast here is useless) in order to be notified and then take some action.
I don't know if that is possible. I hope it is.
Thank you for your help.
You are unable to keep your service alive if system decide to kill it. You are also unable to keep your service alive if your app is "unloaded" (whatever you mean), because your service is part of your app (and APK) and will be unloaded too.

can I start a service from another service in android?

I am developing an app which will keep track of the time when a user's phone is "not used".
Basically, an app which gets activated as soon as a user presses unlock or in the event of an incoming call. I have written a BroadcastReceiver which notifies a background service to start keeping track of time during which the phone is not being used, and will show the activity as soon as the user presses to lock.
My problem is that the services sometimes gets shut down without notifying. Can I write one more service which can periodically check whether the master service is running and toggle it in case it's shutdown? Or is there any other better way to do so?
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
Yes you can start another services within your service. Actually you always do this but you are not aware of it. I mean when you call getSystemService(....) initializer in your service , you use another service which is declared by android.
i am not that experienced but yes you should be able to start another service by sending an intent to the other service if you like, service may be killed by the system if it is under heavy memory pressure according to http://developer.android.com/reference/android/app/Service.html.
You should be able to check if your service is running or not.

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