I have an Android app that connects to surrounding devices currently running the same app, even if in background.
To do this, I use WiF-Direct to advertise the fact that I am currently running said application.
Therefore I need to stop advertising this as soon as the app is killed.
onDestroy() cannot be used since it is not guaranteed to be called.
onStop() and onPause() cannot be used since the app is still running.
How can I achieve this?
Currently the service is still being advertised even when the application is closed/killed.
You should be able to do this with a Service.
Start a service when your app was started.
Override the onTaskRemoved method
#Override
public void onTaskRemoved(Intent rootIntent)
{
}
In this method do what you have to do.
More detailed answer can be found here: How to know when my app has been killed? (2 answer)
The best implementation might be to have another service running that queries the your app is in foreground(i.e. running)
You can run the query to check periodically say every 60 sec. Then if the app isn't running. You can stop the WiFi Direct service and subsequently stop self.
Related
I know that there are a few reasons why android OS may kill a running foreground service. It can be a battery issue, a memory issue, or simply the user killed it by force. Not sure if there are other issues too.
Now I would like to know the reason for the kill from a callback and send it to firebase analytics for making some statistics. The foreground service that I am using sends two HTTP requests every 15sec. I know there are other ways to do this. but right now i am stuck with this code anyway.
In my research, I have found a call-back method.
public void onTaskRemoved(Intent rootIntent) {
}
This is called if the service is currently running and the user has
removed a task that comes from the service's application. If you have
set ServiceInfo.FLAG_STOP_WITH_TASK then you will not receive this
callback; instead, the service will simply be stopped.
As it says this callback only works when the user will remove the task. But what about the memory or battery issue, or other issues if there are any?
I will really appreciate any help here.
Thanks, everyone.
It always seemed some sort of black magic the way other apps keeps their services always running, but mine gets killed by the system every time.
My app should keep a TCP socket open to the server and send/receive data when it becomes available, so it has to stay always on.
This is what I have tried so far:
1) Running the service in another process using this line (also with an additional line stopWithTask):
android:process="package.name.custom_process_name"
android:stopWithTask="false"
2) Restarting the service when these methods get called:
onTaskRemoved()
onDestroy()
3) Add return START_STICKY to onStartCommand() method
4) Check if the service is still running when these events happen:
android.net.wifi.WIFI_STATE_CHANGED
android.net.conn.CONNECTIVITY_CHANGE
- Here I am stopping the socket connection to the server if the device does not have internet connection anymore and reopening it when it gets a connection.
Yet, my service always gets randomly killed (sometimes after few hours, sometimes after few days) by the system and doesn't restart automatically until I reopen the app.
How does other apps, say chat apps for example, keep their services available all the time?
P.S.: Having a persistent notification would be the least of options.
Override onDestroy() in your service, whenever your service destroys create Alarm using AlarmManager. When alarm trigger start your service again.
Second way is not recommended or proper way but create a separate service AlwaysAliveService which will do nothing but will remain available in android system.
I have an Android app that connects to surrounding devices currently running the same app, even if in background.
To do this, I use WiF-Direct to advertise the fact that I am currently running said application.
Therefore I need to stop advertising this as soon as the app is killed.
onDestroy() cannot be used since it is not guaranteed to be called.
onStop() and onPause() cannot be used since the app is still running.
How can I achieve this?
Currently the service is still being advertised even when the application is closed/killed.
You should be able to do this with a Service.
Start a service when your app was started.
Override the onTaskRemoved method
#Override
public void onTaskRemoved(Intent rootIntent)
{
}
In this method do what you have to do.
More detailed answer can be found here: How to know when my app has been killed? (2 answer)
The best implementation might be to have another service running that queries the your app is in foreground(i.e. running)
You can run the query to check periodically say every 60 sec. Then if the app isn't running. You can stop the WiFi Direct service and subsequently stop self.
My main requirement would be to have a service having its own process and trigger its own geofencing event. I'd like the user to be notified from the notification center when he enters a geofence, even if the app is killed.
I read about services and this seems pretty clear to me, the Android documentation is dense so I managed to understand how to start a service with its own process, and also how it is able to communicate with the app using Messenger.
Then there is this code sample from Google showing how to use geofencing with google play services:
Google samples geofencing
What I found so far is that we have to use an IntentService to trigger geofencing events, and from the docs I've read it states that an IntentService terminates itself when its work is done. And I tested a bit also, it looks like the Intentservice gets killed when the app gets killed, which doesn't surprise me regarding the documentation.
So my question is, how could we perform a geofencing service having its own process? Is that possible to avoid using IntentService for this matter?
EDIT:
The reason I wanna do this, is that the user can set geofence "reminders", it is based on a daily usage. For instance imagine each day you arrive at your workplace, we should be able to fire an alarm (or a notification) when we enter this geofence regarding the app is running or not. We don't want the user to worry about having the app running in background.
I actually realized this by creating a service with its own process. This service is bound with IPC communication, my activity then registers to it when needed.
Within this service, I did apply the geofencing example that I found in google samples. It uses an IntentService to trigger geofencing events. Instead of using this logic in my activity, I use it in my own service. Now I can receive notifications even when my app is killed.
You don't have to use separate process for this purpose (unless you have other features in mind which you didn't say here loud)
Use WakefulBroadcastReceiver which is indeed perfect for handling geofence transition events.
You are right about Intentservice ,It gets killed as it completes its task.
But there is a work around that can get you service working even after your app is killed.
Do remove following code from you Activity where you mentioned location code.
Remove mentioned code from you activity
check your onPause()
#Override
protected void onPause() {
super.onPause();
//Comment out below code
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
check your code in onStop()
#Override
protected void onStop() {
super.onStop();
//Comment out the below code if you have done in your activity to disconnect from google api client.
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
Put some log in your Intentservice ,You will see that when you run your app after mentioned modification you can even get location update even after you app is killed. :-)
In several apps we use local services to (for example) record locations. This is working perfect for some time (e.g. 4 hours or 150km) and then Android closes (no longer wants) the service. The service is not crashing it's Android that decides to close the service.
It's written in the docs and it's ok BUT I need to find out that a service has been closed. How can I do that?
I would like to restart our service as soon as possible. How do you guys find out that a service has been closed by Android? Do you use finalize?
Thanks in advance.
Have you tried to return Service.START_STICKY or Service.START_REDELIVER_INTENT from Service.onStartCommand() method?
Your service's onDestroy method should be called as it is destroyed by Android OS. Also you should see in logs that normally android re-boots your service after a short time period, which is shown in the logs as it is destroyed, in my experience its around 15-30 seconds before it is booted again. (Every service you have in your app will be booted in a random order so beware if some services rely on other services in your app.)