I am developing multiplayer game using Socket.io library. it Works Well.
But, in android 7.0 and above, system automatically suspend all network work when my app is in background. (And I must need to keep alive my socket connection).
I research about it as described here.
but, i can't understand. So, Please provide solution for that.
Unfortunately there's bad news and some good news for you on this.
Bad:
Since android marshmallow and above, there's a concept of a doze mode. If the device stays put for some time (can't confirm the duration for this and not disclosed by google), the device will go into doze mode and will suspend all network activity. There will be short maintenance windows where in you will be able to do syncs and stuff. Small workaround, do not target 23+ apis, i say small because i have observed this to not work on some phones. Another way to potentially bypass this would be to whitelist your app from battery restrictions but according to google guidelines, i don't think your app will qualify for that.
Worse news is that start from API 26, background services will also get suspended completely when app is totally backgrounded and has no visible component (a notification or a foreground service etc...). So oreo will be worse.
Good:
You might not really want to constantly keep the socket open. Instead opt for bursts of syncs. I personally have a job run every 30 - 60 mins or so to try and sync up.
You can leverage the JobScheduler apis and it will automatically handle the doze modes and stuff and you can make them run periodically when there is internet connection. While the job is running, you can connect to your server, do your thing and shut the socket. This is what google wants and is pushing all devs towards.
UPDATE 19-Apr-2021
WorkManager is the new and the best way to deal with doze mode and background limit restrictions.
Another alternative would be to have a foreground service with an active notification displayed which would constantly be connected via your socket. This will be visible to the user and it will not only annoy them that you are constantly using their data, it can also be bad for the battery. Alternative to this again is using the job scheduler to schedule and run a foreground service periodically so as to be transparent while also syncing your data every once in a while. The latter approach is what WhatsApp does, they have a job running which syncs all incoming messages with a foreground service once in a while.
In Short:
You will not be able to keep it alive always. You can try doing it in bursts using one of the methods that i described and know currently (maybe there are other alternatives that i don't know, i have tested these and they work) You will have to compromise, sorry.
Related
I am recording output from a accelerometer.
Can anyone recommend a reliable way to monitor onSensorChanged after the app has been closed (running the app in the background).
WorkManager
I have experimented with WorkManager. WorkManager appears to run only when the app is open. I read that this may be device specific as some devices force stop the app on close or otherwise prevent background tasks from executing once the app is closed.
sticky-notifications
I am curious about using sticky-notifications, although this would not be my first choice. I am now researching this option. I have noticed a few apps which implement this option. The downside is the sticky-notification can be viewed as annoying and the user may disable sticky-notifications.
Other options?
You should use a service if you want to run in the background. But probably the Android won't allow it because keep listening to a sensor in the background will consume too much battery. Mainly on Android P that is more rigorous with battery consumption.
WorkManager is not the right solution in this case as a Worker has an execution limit of 10 minutes, then it's stopped by the OS. But, time limit aside, WorkManager has been developed for other use case, so using for something like this (using some hack to reschedule a worker when you're close to the 10 minutes limit) seems a fight against the library design. To have an introduction behind the use cases that WorkManager is designed to solve you can take a look at this blog: Introducing WorkManager.
A Foreground service is an option, but I'm afraid that continuously monitoring the sensor can have a very bad impact on the battery life of the device. For more information on the available options, to run code in the background, your can check this blog: Modern background execution in Android
An alternative, depending on what you need to do with the sensor data, is to use the Activity Recognition API:
You can tell the API how to deliver results by using a PendingIntent, which removes the need to have a service constantly running in the background for activity detection purposes. Your app receives the corresponding Intents from the API, extracts the detected activities, and decides if it should take an action.
March 2021 Update
There have been a couple of updates since I originally wrote this answer:
WorkManager v2.3.0 introduced support for longer Workers with the option to "promote" them to Foreground Services using setForeground() for CoroutineWorkers and ['setGoregroundAsync()][5] for all kind of Worker`s. This is allows to overcome the 10 minutes limit and is documented in Support for long-running workers.
Android 12 is planning to introduce some changes to Foreground Services and this has some impact on WorkManager. The new v2.7.0, currently in alpha, is adding the concept of expedite work to provide support for Android 12 in a backward compatible way.
Overall, I still think that having your app monitoring the sensors while in background is going to have a bad impact on the battery of the device and you should look for alternatives.
I'm developing Android app with background service. Service is running in its own process (like com.example.app:extProccess). Service creating WebSockets connection. But after less than 1 min after service started there is a disconnection on WebSockets, but service is alive (not killed by Android). After 20-30 min a connection is recovering.
Seem like device entered in Doze, but very soon.
This is observed only on some Nougat devices.
If I prevent battery optimization (android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) for this app service and websockets working correctly without disconnects.
My question is why Android limits network so quickly if my app in foreground? So how to hold networking for background service in this case without using android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS?
Starting from Android API 21(Lollipop), Google started giving more focus on battery optimisations. The problem comes is any service. One way to overcome this is to use Job Schedulers for your background tasks(documentation available here). Also, any task that uses android resources a lot will be terminated by the Android Framework. The only solution for your particular use case is to either optimise your code or use "IGNORE BATTERY OPTIMISATIONS" as done by you.
Currently i reading in official google doc news about Android 7.0
I can not understand a few things.
They wrote Doze improve battery life by turn off network and CPU when user block the screen.
But how this works ?
1.I have Marshmallow in my device, and when my phone is blocked, i still get notifications from app with network (e.g. Messenger).
2.Second thing they wrote Nougat have improved this more by again CPU and network. So what is exacly differet ?
I have Marshmallow in my device, and when my phone is blocked, i still get notifications from app with network (e.g. Messenger).
SMS does not usually go over the Internet, assuming that is what you mean by "Messenger" (many apps use that name). Plus, high-priority FCM push messages work despite Doze mode.
Second thing they wrote Nougat have improved this more by again CPU and network. So what is exacly differet ?
There is a "Doze on the go mode" that kicks in even if the device is moving. This is covered in the documentation and in the documentation.
Push Notifications will still get through, but most services will stop running after a while if you leave your phone sitting on a table with the screen off.
For example Spotify still keeps running smoothly because it has a foreground notification. The battery savings come from when the OS can shut down most systems such as internet and geolocation as well as avoiding running other services for increasingly longer periods of time,for example reaching stretches of hours by the end of a typical user's sleep at night.
Now they're mainly doing what they were saying for a long time: background services have no guarantees of how long they will run. The biggest unintended consequence is that sometimes when they wake up there's no internet or geolocation is not available. And the time they run is less predictable.
There's still ways to wake up and perform tasks with perfect predictability using exact alarms or push notifications, depending on where the event is generated. But for most cases the recommended solution is using job schedulers.
I am using AlarmManager for repeated background process. My app repeatedly requests data from server in 5 sec interval. But after some long time, when I open my app it crashes. I can't figure out why.
How should I execute a background process repeatedly? Should I use AlarmManager,Timer` or something else?
My background process should run always even when the app does not have focus or isn't active.
My app repeatedly request server for data 5 sec interval.
Users with mobile devices, like phones and tablets, will not appreciate your behavior. They will not appreciate your consumption of battery life and your consumption of bandwidth. Device manufacturers and Google are continuing to take aggressive steps to prevent applications like yours from behaving this way, both automatically and by giving users the tools to find ill-behaving apps like yours and get rid of them.
But After some long time when i open my app its crash
Most likely, you have a bug in your app. You will need to fix the bug. Since you have provided no details of your crash, such as source code and a stack trace, nobody can really help you with that.
Which is the best for repeated background process, AlarmManager, Timer or something else?
Switch to a user-configurable and less-crazy polling period (e.g., every 15 minutes by default), then use AlarmManager in conjunction with an IntentService, so that your process can cleanly go away
Or, switch to having the server send messages to the device when the data of interest changes, such as via Google Cloud Messaging. This will allow you to drop the polling period to something infrequent (e.g., every hour by default), as a fallback mechanism in case you miss a push message for some reason.
My background process should run always though the app is not on focus or active
Your users will disagree with you. They do not want apps running all of the time, tying up system RAM. They really do not want apps that consume battery and bandwidth the way that you are proposing. The users will get rid of your background process, either by:
swiping your app off the recent-tasks list
using a third-party task manager
force-stopping your app via its entry in the application list in Settings
uninstalling your app
My company has, in essence, undertaken a project to replace some of its pagers with stock smartphones running Android. As long as they are signed in, the device should be listening on a particular socket to receive "pages" from a server. My naive implementation was to create a foreground service that 1) kicked off a listening thread, and 2) holds a PARTIAL_WAKE_LOCK.
This works fine unless the device has a long period of inactivity, 1+ hours. Then, it appears that the OS shuts down my app's process, understandably believing it to be not in use.
I completely understand their reasons for doing so, but I'm wondering if I can somehow get around this restriction. Are there ways to signal Android that my process really is important enough to keep alive/the device awake? I learned both Java and the Android API for this project, so there are plenty of areas where my knowledge is incomplete.
Failing that, given the description of my business needs, how would you suggest implementing this functionality? While the user is signed in to our custom app, the device should always be listening.
Thanks to everyone for reading this question.
The OS won't kill your process if you are using Service.startForground(). This is what things like music playback use, and you wouldn't want those to be killed after some amount of time.
That said, for this kind of thing you generally wouldn't need to make your service foreground -- when the system does kill your process because it has been sitting around or needs the memory, it still knows the service wants to remaining running so will restart the service shortly after that. This is how Google's own services work, they have one .apk that has a background service running that keeps a network connection open to a Google service which reports back when interesting things should be done like sync new e-mail, retrieve and deliver a C2DM Intent, etc.
Also you should not hold a wake lock during all of that time. You will kill the battery, especially on some devices like those with Samsung's Hummingbird processor. The right way to do this is to just leave the socket open and let the device fall asleep. If data is delivered to the socket, the CPU will wake up to deliver that data and at that point you should acquire a partial wake lock just for the time you need to read and process the data.
What you describe sounds like a job for Android Cloud to Device Messaging Framework.
It's currently not completely open but there is a signup link on that page. I signed up and was accepted within 20 minutes of my application. Worth a look IMO.