I have an app that sends TCP messages. I need the messages to be sent as long as the app is alive. So, I granted access to battery optimization and added all the required wake_locks and everything seems to work fine even when screen is off.
The problem is that I noticed that every time that I leave my phone with the app in the background, when I come back after few hours(or less) no messages are being sent, and when I enter my app it loads as new instance and not like an app coming from background. What can I do to have my app not being killed by Android?
I guess that this is what happens
You need to use a foreground Service; a service started via startForeground().
The service does not "re-open" your activity; it is a component of your application that may be long-lived. You might prefer to think of it as an activity without any views.
Yes, as the others mention you have to use Service for background execution.
Additionally, also, keep in mind of the Background Execution Limits for Oreo and above.
You can also look at JobScheduler for managing asynchronous tasks efficiently.
Create a 1px*1px transparent view on the desktop, such as toast.(the Android os will level up your priority as a foreground process)
Suggest your user to add your app in the white list.(in some rom)
Always put your app`s notification in the notification bar.(also need a service)
create a guard process, when your app die, send a broadcast to guard and let guard restart your app. when guard die, send a broadcast to app and let app restart your guard.
Be careful of battery consumption and don`t trouble your users too much
Related
I am building an app that is needed for a research experiment.
The experiment is entirely based on users responding to notifications that are shown at somehow random intervals.
What is the best way to do this so that each notification will definitely be shown to the user?
WHAT IS DONE SO FAR
I have used AlarmManager and broadcast receiver but notifications stop showing up after some time. Notification Channels (with id) are used too.
I suspect the operating system removes the app after it has stayed in the background for a while.
Can anyone help to explain the best way to get the app to show notifications regardless?
Since this is an app for research, users are well aware of any slow performances, or battery usage. The only priority is to ensure that notifications show up. Without this, the whole experiment will fail.
Any help or pointers will be great! Thanks!
I'm not sure what method you've used to show notifications so I'm giving a general guidance.
You will need to use a background service which keeps running even after the app has closed. A background service can be killed by the android OS if its running low on memory, so you'll have to give permission to your app to autostart.
If you want even more reliability, you should use a Foreground service. This way you can give high priority to your notification service.
But it would be much simpler to integrate Firebase Cloud Messaging into your app than implementing your own NotificationBuilder service.
I'm developing an Android app with several types of alarms and triggers.
One of these alarms trigger if you stop moving (GPS tracking) while it's active.
Now, when the app runs in the background when this triggers the client doesn't update when you switch back in, and the only notification received is a push-notification from the backend service. If I enter through the notification, the client loads the alarm correctly.
The code base is quite extensive, and due to time and resources it would be best to avoid huge refactoring tasks.
Is there an easy way to make the app go from Activity A to Activity B when it's running in the background?
You cannot change the current Activity in the background without bringing the app to the foreground (using startActivity()). However, you can surely tell the app that when it is brought to the foreground it should start a certain Activity or rearrange the back stack or whatever.
Post some of the code and maybe we can help more.
The background services are not encouraged any more from Android Oreo (>25). I want the socket to keep connected in my chat application even when the app is closed.
How can I implement new changes to android 26?
Some people says, use JobIntentService
Some people says, use JobService
Some people says, use JobScheduler
Some people says, start service as Foreground Service
Any help would be appreciated.
I faced the exact same problem working on a chat application so I know your pain. Our conclusion was:
you don't keep a connection alive 24/7, if you need to deliver a
message to an user that has no connection alive, send a push message
via Firebase.
If you want to keep a connection alive in background, you will face many problems. The first one, targeting Oreo, is that if your app is in background (definition of "background" in this context is here) it won't be allowed to run except for small time windows.
You can definitely use JobScheduler to run periodic tasks, they won't be executed at exact intervals or times to reduce battery usage (which is good) but it won't help you in keeping a connection alive. At best, you can use JobScheduler to periodically pull messages from you server. In order to use JobScheduler you need to create a JobService class.
JobIntentService is a new class introduced in API 26 of support library. It is a replacement for IntentService, it will run as a JobService on android API 26+ and as a Service (similar to IntentService in the sense that it will execute code in a background thread) on older APIs. On Oreo its background execution will still be limited so it won't help you in keeping a connection alive.
Using a foreground Service can really help you reducing the likelihood of the process being killed, but, you will need to display a permanent notification. It doesn't sound like a good solution for a chat app.
If you still think that having a 24/7 connection alive is a viable option, you need to consider also doze mode. You could ask the user to whitelist your app to run even in doze mode but you should have a very good reason to do that. Again, you would face the other bg execution limit in Oreo.
Another issue you will face is other apps. There are resources management apps that will aggressively kill other apps in bg to reduce memory and battery usage. For instance, I cursed this one quite a bit.
Another issue is created by android. When the system is running low on memory, it will start killing processes of apps in bg. There is a an order in which they're killed, if I recall correctly should take into account last time it was in fg and current memory usage. Not the worst of the problems but still, it happens.
Then, if I still haven't convinced you in giving up the idea of the permanent connection, let me share with you yet another problem you would face. Some vendors implements extremely aggressive policies when it comes to killing bg processes, so that they're battery will last longer. For instance, Xiaomi.
Last tip, unrelated, but it took us a while to figure this out so I'm going to share it. If the user force stops your app from settings, your app is dead (that is, "stopped state") until the user actively launches it again, it won't even receive Firebase push messages.
If your server is configured on XMPP, then it would be easy for you.
Actually, there isn't any need to keep the socket alive at all the time. This is very expensive for the battery and I'm sure you don't want that.
Case: You are working on a Messaging app.
If your socket is broken, then the client will receive the message in the form of Google FIREBASE notification. And the moment your client will receive a notification from firebase, just enable the socket, and you'll be back on track.
The reason I suggested you to use XMPP is because XMPP maintains a queue of undelivered/offline messages. And when your socket is connected again, you simply pull the offline messages from the server.
I don't think this will help you out, but this may make a room for some another idea for you.
Before I begin my question, I want to preface this with: I KNOW IT'S A BAD IDEA TO FORCE A SERVICE TO RUN FOREVER... I simply do not care.
This application is not for consumer use. It is not going on the app store. It is for my use only.
Alright, well I have this unused HTC Sensation running 4.0.3 (ICS) sitting around, and I have volunteered it to a local theatre for a task. The task is for it to ring on cue whenever it is needed in the show. We don't want a sim card in it because someone might accidentally call the phone during the show when it is not supposed to ring.
So I created a fake phone application that receives a signal via TCP from a server that I have set up to send signals to devices over the LAN. Right now I have the listener running in an infinite loop in a service. I am, however, still experiencing the service not responding to the TCP signals.
I would really appreciated it if some android guru's could give me some hints/tips for making this service as reliable as possible, good/bad coding techniques aside I want to do everything possible to make this service unkillable. This phone has only one job now, and that is to always be listening for incoming messages, no matter what.
Things I have done so far:
Created a Service (and launched a separate thread from that service)
Used startForeground(id, notification);
Activated DeviceAdmin and created a wakelock
anything else you guys can think of?
First idea that pops into my mind would be setting up an AlarmManager that checks every 5 seconds whether or not the service is running.
This describes a method to see whether a service is running.
And if the service is not running you can just restart it.
Using this and the startForeground()-method may work.
Kind regards
There is no way to ensure that Android will never kill a service. If you make it a foreground service it reduces the odds, but you can't insure it.
Based on this quote from the Service javadoc...
Other application components running in the same process as the service (such as an Activity) can, of course, increase the importance of the overall process beyond just the importance of the service itself.
... if you leave the activity that starts your service in the foreground, that will pretty much guarantee that the Service won't be stopped [I posted a comment starting to suggest this idea that may have been cut off.]
To add another level of reliability, hold a wake lock in your activity, using this doc as a guide:
https://developer.android.com/reference/android/os/PowerManager.WakeLock.html
Example code:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
wl.acquire();
// ..screen will stay on during this section..
wl.release();
Can i make a service which recognize voice even when phone is idle or screen off? I mean can phone listen to what the user will say even on idle state.
This is the entire program on how to make that happen.
http://developer.android.com/guide/topics/media/audio-capture.html
That shows how to record audio, the same implementation could be used to listen for audio.
Also, DEV GUIDE on what services are.
Right from developer.android.com
A service is a component that runs in the background to perform
long-running operations or to perform work for remote processes. A
service does not provide a user interface. For example, a service
might play music in the background while the user is in a different
application, or it might fetch data over the network without blocking
user interaction with an activity. Another component, such as an
activity, can start the service and let it run or bind to it in order
to interact with it. A service is implemented as a subclass of Service
and you can learn more about it in the Services developer guide.
This should give you all the information you need:
http://developer.android.com/guide/topics/fundamentals/services.html
You will have to aquire a wakelock in a service too keep the phone from sleeping so you can record audio. You can probably stick with a PARTIAL_WAKELOCK since you will not need the screen to be on.
You also need the wakelock permission.
Keeping the device active and processing sound continuously will however not be sensible for any implementation I can think of.
It is a horrible idea for most purposes since it will drain your battery in a matter of hours (tops).
I've been working at getting a background audio recorder (while screen is off), and these are the options I've found:
A full wakelock lets you keep recording, but keeps the screen on. (not ideal)
A partial wakelock would be good, except it doesn't actually work -- at least on my phone. (the cpu is kept active, but the data from the microphone becomes just 0s after a couple minutes)
Use a foreground service which starts a background thread that records the audio. This is the best since it lets the screen turn off, while still recording indefinitely.
See here for an example: https://stackoverflow.com/a/57260468/2441655