I was reading about background service limitation in Android 8 and from what I read it seems that you can't run your service in the background for a long time. This seems reasonable but because I use background service to keep connection to server - currently pooling new stuff, sending location and responses I am a bit confused. The responses are OK, I can respond only when interacting with the app, but the pooling new stuff is problematic because it needs to get an stuff from server and if something new come present the user with a notification to respond to it.
If I understand it correctly I can use JobScheduler to schedule some job every several seconds. I can basically schedule the pooling. For the background locations, well there are those restrictions so only foreground service is an option to get updates in requested time.
I will be migrating to websockets and then the pooling is off, the connection to server will be persistent and the app will get updates from server, I was planing to do this in the background service so something would receive stuff from server everytime. However it seems I can't since Android 8. How would you solve this? Should I use foreground service for location and server connection? Or is there a better way to do background networking in an android app on android 8?
Thanks
Here are a few options for performing background work on Android O:
Use JobScheduler. You already seem to have a good grasp on this one- the downside is that it is periodic, not persistent.
Use GCM/FCM or a similar push service to push data to your app when it is relevant instead of constantly holding a connection to your server.
Use a foreground service. This will allow you to continue performing your background work without your app being in the foreground, but will put a notification in the status bar to inform your user that you are doing that work.
Before you select one of these methods, you should take a moment to step back and look at the data that you need from your server and determine why you need a persistent connection and whether the first or second options might be sufficient.
If you absolutely need a persistent connection to your server, the last option is your best option. The idea behind the changes in O is to still allow background work such as what you are describing, but to make it painfully obvious to the user that your app is doing so. That way if they don't think your data is as important as you do, they can take action.
Related
I'm trying to build a task-manager application. Two or more client applications should be able to change (such as mark off or change the title etc) certain tasks stored in the database over the web.
While creating the requirements, the following question came up:
How is it possible to inform client applications (Android Apps, Java-Applications on a Mac) about changes in the database, without constantly checking the database? I planned on storing the data objects in a SQL-Database on a Webserver.
Should I use another database? What is the standard way to go right now in SE world? Any keywords for me or explanations would help!
Firstly, make sure you are not accessing the database directly from the client applications, that's a very dangerous route.
Secondly, as for your requirement it looks like you want a server side push notification.
As far as I know there are 3 ways to do this.
Check updates from the server every X seconds (if you don't have too many clients that needs to be notified this way is okay to go)
Use HTTP long polling.
Use WebSocket to keep a long lasting connection between server/client applications.
For mobile devices though, if you want to be notified even when the app is closed, take a look at all the push notification frameworks available out there (e.g. FCM/GCM).
I am working on small chat application which is working fine when the app is visible to user. A service class which get and send data using post every 5 second when aap is visible to user and works fine. But when app.is closed and service works in background for few minutes fine. After few minutes i.e. apprx 3 minutes it get conmection refused error and never fetch data from server until.the app is again visible to user. I cant find any solution. please help.me
I uses HttpURLConnection for posting data, and a Thread and timer for regular posting.
Android suspend applications when they get into background, to make resources available for the foreground application. If you need to sync your data on the background you should use a Background Service or SyncAdapter.
Take a look at Best Practices for Background Jobs and Transferring Data Using Sync Adapters
Some tips:
Do not use manual timed HTTP requests for chats messages, its a very bad practice,
But, if you want to keep this, use some new http request library like "Volley" or "OkHttp" (this is my favorite),
If you want more professional and highly "best practice" stuff, use the Google's Firebase Cloud Messaging for chats apps, its use native google services for send messages to others apps, highly recommended.
Connection Refused can be your client (service) sending wrong data/values, wrong URL, wrong ports and wrong query, please post a piece of your code.
I am trying to develop a mechanism for Sync data with app & server, like Google Drive/Dropbox for one of my android based application where data are stored locally on device and I would like to sync data with server.
Ways thought -
1) Observer which looks for change and call web service
2) Background service which runs in background and check for changes
3) Set Alarm which checks at particular time and sync all the data with server
I have not started to which option to go with, I would like to get experts view on this and like to get some guidance so that I can achieve the sync mechanism in best possible way for my app.
All suggestion are welcome.
Thinking on same line as you have been,the aim should be to achieve a balance between the number of times the server is queried for same set of information AND the data consistency.
for this, I would fire a GCM message from my server to the device for which the data on the server has changed, I would maintain a count for these Update Messages(No Notification genereated). If this count Exceeds the minimum-threshold-count-value, I would immediately call for an UPDATE. Or otherwise, if this count still is less than the threshold-count-value, for a certain period, that I would call the threshold-waiting-period, then too I call for an UPDATE.
The UPDATE would be using Sync Adapters and Services. This link explains its basics.
Hope this prooves to be helpful!
...so that I can achieve the sync mechanism in best possible way for my app
Well, the BEST mechanism depends completely on what kind of application, you are developing. Also, your option 1 and 2 seems very similar to me except few implementation changes. However, how frequently your device data is changing, that also matters a lot. If you have authentication mechanism, you can configure sync up, at the time, whenever you login to your app. Like in case of confidential data, sync up should happen immediately.
If data is managed well based on authentication and authorization based on user roles or so, you also need to take care of synchronization among them. For example, one user has updated an entity which is not yet sync and another user tries to update the same, then first user will see his changes are not synced or has been lost.
The best way (means having least drawbacks) to do this would be sync up trigger at a particular interval of time OR at every login time. (still as I said, depends on your app).
Hope this would clear some or all of your doubts.
If I am developing an Android application, what is the most feasible way to get near real-time notifications about an incoming email? Is there a push-like mechanism, or can I hold my IMAP connection for a long time, or do I use IDLE command?
Consider that user is authorized to use GMail services via OAuth and I don't want to poll IMAP server madly.
Update:
I'm not using the phone's configured-in Google account. There is another account set up using OAuth.
I'm using Apache Commons Net to connect to IMAP/SMTP in my app. It's a bare-bone library for IMAP, but I can perhaps modify it to add IMAP commands/extensions.
You can register a ContentObserver with GMail, anytime something changes in GMail, the observer will be called.
contentResolver.registerContentObserver(Uri.parse("content://gmail-ls"), true, myContentObserver );
Override onChange in your ContentObserver to do stuff when something in GMail changes.
Since IMAP does natively provide any sort of push notifications and the Google extensions don't either, you have to implement it yourself.
One way is to use IDLE requests, which is still a cheap way to do polling. Of course, you can't expect your app to be running all the time, so you need to use a background service. An 'always-on' service is however an anti-pattern on Android and will drain the battery quickly and likely get you many 1-stars. Additionally the system may decide to kill it at any time. The other alternative is to use AlarmManager to start the service periodically, but starting it every couple of seconds or so is just as bad. So you are basically back to square one: polling.
The other way is to get push notifications using GCM or a similar service. This does require you to have a server, and the server needs to have the authentication info for the user (which might be a problem), but there are no real constraints concerning keeping open connections and sending IDLEs each second, etc. On the Android side, if you want to implement push yourself, you need to keep an open socket to get notifications. This is not very easy to do if you are not a system app (see above), so that leaves GCM. The connection it uses is manged by the system (Google Services framework), it can do things a regular app cannot, and you basically get it for free, since it's already there. It receives small pieces of data when there is something to do, called 'tickles'. Those in turn trigger broadcasts, Google Play updates, etc.
So, take your pick. Or just give up, register the account and use GMail and its labels Android API.
I'd check out Google Cloud Messaging (GCM):
http://developer.android.com/training/cloudsync/gcm.html
My understanding is that this works without requiring the user's Google account, and lets you handle authentication.
See a tutorial here:
http://www.techrepublic.com/blog/app-builder/implementing-googles-cloud-to-device-messaging/428
You would need additional server-side code running to do this though.
I'm working on a browser game with the play framework, and I definitely need longpolling, but I don't quite understand how to use it. WebSockets would be perfect for this, but it's not supported by that many browsers yet.
Here's what I want to do: When the user logs in, and navigates to the play game controller, I want to start a connection, and keep it open. I want to do this for all users that are online, so I can show a list of them on the site, so they can play with each other. I've looked at the documentation, but I don't understand how I could implement it in my case. Because there simply isn't anything I want to calculate (in the example they're generating a pdf) I just want the connection to stay open.
What I'm also wondering is, how I should keep track of all these open connections? Right now, I just have an online column in my users table in the database, which I update. SO everytime someone connects I have to update the database. Are there better ways to do this, or is this fine?
And lastly, assuming all of the above works. When player A, selects player B to play with: how do I notify player B of this? Do I just send some JSON code, and change the page with javascript, on player B's side, or do I send him to a totally different page? I'm not sure how to communicate when the two connections are established and the game has started.
Firstly, I think you need to appreciate the difference between Websockets and Long Polling.
Websockets creates a connection and keeps it open until the browser terminates the session, via some javascript or the user moving on from the page. This would give you the desired nature of what you are requesting. Looking at the Chat example in the Play download will show you how an entire Chat application is handled using Websockets.
Further to Pere's answer regarding Play's statelessness. The Play creators have suggested that a single Websocket connection, regardless of how long it is open for and how many requests are sent back and forther, is considered to be a single transaction. Therefore, saving to the database in between each Websocket request is not needed (again, you can see that nothing is saved in the Chat example). Using this method, you would be expected to save the details when the Websocket is finally closed, or indeed all Websockets, depending on your use-case.
Long Polling on the other hand opens a connection to the server, and the server simply waits until there is something to send back to the client. If you need to push any data to the server, you would do this as a separate AJAX request, so you would effectively have two requests open at once. You don't necessarily know when a user logs off, unless you send a request just as they leave the page, to let the server know they have gone, but this is not always successful. Long Polling can work, but it is not as neat a solution as Websockets, but as you say, this is not widely supported yet.
My suggestion would be to study the Chat example (as it has a Long Polling and Websockets version). This will be the most effective way to get up and running with your requirements.
As for your final query regarding how to notify the other player. In Long Polling, you would simply respond to the suspended request with some JSON. With websockets, you would send an event back to the client. Again, both approaches can be pretty clearly figured out from the Chat example.
I have also written a Blog post on Websockets, which may help you understand this process a little better.
On the Websocket part, as you can see here (1st answer) the support is not so bad, and you have a Javascript fallback if there is some problem with the browser. This would simplify your scenario, as long polling may be more complicated to manage.
On the issue of keeping track, as Play is stateless you have to store the flag in the database and remove it when they close the connection. Otherwise you are breaking the statelessness.
About the notification, you have to send some message to B, but don't move them to another page as it may be confusing and cause bad user experience. Use Json to pop some message (in a div) alerting them of the game starting or the request to play.
I'm not using the "play" framework.
But I've been lately researching and tinkering with http-based long polling. Websockets, if available, is much more appropriate for realtime messages!
As for long-polling, I found that using a "cargo truck" analogy helped me reason about long-polling quite effectively. Here's a little note I wrote on the subject:
http://dvb.omino.com/blog/2011/http-comet-realtime-messages/
Perhaps you or future greppers may find it useful.
You might also want to take a look at the Juggernaut project which is based on node.js and Redis and gives you a "realtime connection between your servers and your client browsers". When using a Java Redis client like Jedis, you should easily be able to integrate the whole thing with the Play framework!