My android app has a ContentProvider and stores data (strings) in a SQLite table
These rows need to eb sent up to an internet server
I want this data to be uploaded in the background when the remote host is available (WiFi on for instance)
The data should be sent asap (when network available of course)
without interfering with my app's ui
It should send even when my app does not have the main focus (user may be sms-ing or using the camera)
New data could be added to the table (out queue) every 5 seconds
Q: Should I use a background service to send the unsent rows?
It seems too frequent to use the "Alarm Service", but I could be wrong
Battery life is my main concern, but secondly is that it needs to send as soon as possible (or shortly after internet available)
Android Studio
targeting API 17+
A background service would be best to handle the request and save battery life. You could either check the connection state and send yourself and just let the service handle when there is no connection, OR better yet just use the service to always send the data and let it decide when to send it.
As for the service, see this question: How to be notified on wifi network status change?
The idea would be to use the code in that answer to implement a broadcast receiver in your service to detect when there is an available connection. When that connection is available then you could send the data.
Related
I am relatively new to developing Android apps. I have an android app that downloads several resources from the internet and keeps on generating these requests. I want to create a queue of such download requests when there is no internet connectivity and get them started as and when the connection is restored. In this case, the connectivity may be in either form both Mobile data as well as over Wifi
There are several parts to this: first, detecting whether you're online now, if you're not online detecting when you'll come online, and having the actual queue.
The queue itself can use a SQLite database. You just need to store enough information to reconstruct what the request should be when you resume.
You can see the documentation on monitoring the connection state here.
Basically, if you're targeting API less than 24, you register a broadcast receiver to receive the CONNECTIVITY_ACTIVITY broadcast. (Otherwise, you can "listen" for CONNECTIVITY_CHANGE). Your logic once you figure out what request you want to queue will probably be something like the following:
Push request onto the queue
Check to see if you have connectivity
If so: start processing the queue.
Otherwise: wait for a broadcast receiver to notify you that you have connectivity again and start your service that does the processing.
Sorry to be a little vague (I'm not sitting in front of an IDE right now) but hopefully that outline'll be at least semi-useful.
There's a number of popular "job queue" libraries that allow you to specify dependency on network being available (along with various retry policies). For example:
https://github.com/yigit/android-priority-jobqueue
https://github.com/evernote/android-job
Create a local database which should have HTTP request details, time stamp and its status. Whenever your application initiate HTTP request store it in database with HTTP request details and time stamp of its initiation and its status to non completed.
When your HTTP request is complete change its status to complete so when your Http request generates some kind of exception or error you don't have to do anything.
Now your application should have a connectivity broadcast listener so when your application connects with internet read your database and initiate your HTTP requests.
My app has a UI and a connection is made to a bluetooth device which is periodically sending barcode scan data to my app. I then want to cache this data in a sqlite db and have another process push this data up to a web server.
I have managed to get the UI and bluetooth scan process separated by using an Intent Service for the scanner component... The thread in the intent service connects to the bluetooth device and loops endlessly pulling in new scan data as it comes... communicating with the UI via broadcast messages as it needs to.
So now I need to handle storing the data in a sqlite db and pushing it up to the Internet.
I'm thinking I can insert a db row directly in the intent service loop I already have working for the bluetooth data... would I do that by firing of an async task or something like that?
Then, would I have a completely different intent service running and looping endlessly checking for new records to be processed and pushed up to my web server via an http post?
I guess the main reason I'm thinking of using intent services is that they seem to keep running even if I lock my phone and put it in my pocket... has worked so far for the bluetooth barcode scanner... can scan away happily with my phone locked and in my pocket.
I also need to handle the reality that internet won't always be available... hence the sqlite db... kind of like a safe buffer to store data until it can eventually be pushed up to the Web server.
Am I going down the right path? I'm really new to Android development and even after much research I'm still unsure about my approach.
You can store data or communicate from IntentService onHandleIntent() directly. You don't need to run it in separate thread, unless you want reading bluetooth to continue ASAP.
Handling everything in an infinite loop smells. Also keeping service alive depends on few factors. If IntentService dies, it won't be restored because by default IntentService.onStartCommand implicitly returns START_NOT_STICKY, or START_REDELIVER_INTENT if you call setIntentRedelivery(true) on this service. Check Service javadoc for more info.
If you can scan bluetooth periodically then I would consider kind of scheduler. For that you would probably need to implement Service, not IntentService and handle background thread yourself. Alternatively, you could use a Timer. These are more hints, not ready solution. Since you asked about direction, I assume you will investigate solutions yourself.
Depending on handled data you could separate DB operations and network to separate services. Think about them as modules which are decoupled. You will benefit maintaing this code in the future and in case one service goes down due to any reason, the rest will keep working. It depends on data size because it's not a good practise to push heavy data between service/activities(data is serialised and deserialised every time it is sent).
If DB is just a buffer/queue then maybe use it directly after reading bluetooth data. In other words queue data for sending. Create second service for HTTP communications. Don't push entire data to second service, just inform it about(knock the door :)) and let HTTP service access DB by itself. I would wrap DB in ContentProvider and access it from services.
There are probably different techniques out there too, but that's what I thought about it in the first place.
Detail:
I have developed an android native application on ADT.
App performs ADD , Search and update operations on SQL database hosted on Windows Azure cloud platform.
All the operations are performed by calling a Mobile Service built on Windows Azure Cloud platform.
Problem Description:
Every time I want to ADD a new record via UI of app, my app calls mobile service and get hang till the operation completes.
I want to do this operation but do not want user to wait for it to complete.
Additionally when there is no network, user addition should be kept in queue for later addition.
Ideal Scenario: I want to display Addition operation in pending status to user and make that as a background process till the time it completes.
Note: There can be many ADD operation going on by multiple users. Need to keep that in mind.
Please suggest options to do this.
Free to ask questions in case of any query regarding problem statement.
Thanks
Anshul
You have to use AsyncTask to do work in the background and update the UI for the User or Pop a notification in OnPostExecute which means background work has been done.
For Queuing when No Network:
You would have to user a Service with BroadCastReceiver which listener for Network-Connectivity. Once the BroadCast Receiver Receives that Internet is Connected, You can then start calling the mobile service.
But Let me add that the Queued Data has to be Saved so you would have to create a SQlLite database or save the Data to a file on the Phone, which you can retrieve the data from, when the BroadCastReceiver is notified that connection is back
I am developing an Android app that stores data locally in Sqlite database and sync it to a remote server (MSSQL server). The sending of data is handled through REST api.
This is the way I would like it to work and my plan to handle it:
When the app stores data in Sqlite database, the app will check if internet connection is available, if it is then the app will make a HttpPost to send the data (I use AsyncTask to handle this). Once the data sent, I will flag the row in the database as "synched" using postExecute callback.
If the internet connection is not available, then the app will continue on.
I need to make the app to listen to the event when internet connection became available and then the app will go through all rows that have not been synched and use AsyncTask again to send the data to remote server.
My questions are:
Is it achievable? and if so, is it best practices?
How to listen to the even when internet connection became available?
Thanks,
You could implement this manually, but I suggest you use a SyncAdapter instead.
Although you can design your own system for doing data transfers in
your app, you should consider using Android's sync adapter framework.
This framework helps manage and automate data transfers, and
coordinates synchronization operations across different apps. When you
use this framework, you can take advantage of several features that
aren't available to data transfer schemes you design yourself.
If you want to implement this without using a SyncAdapter anyway, then for the "detect when connection becomes available", you need to add a BroadcastListener to listen for CONNECTIVITY_ACTION broadcasts, then use a ConnectivityManager to query about the current state.
I need to open and keep long term connection with server to send messages, recieve response. Also sometimes server sends information without user request, so android device should listen to the server and react.
There are AsyncTasks, where I can implement socket connection, but main problem is that I know only one way - to send request and recieve response once. Then AsyncTask (and connection) is closed.
I have also read about services (that I never used).
Is it possible to make long term (1-4 hours) connection with server that keeps connection alive, listens for user commands (for example, need to send data to server when button is clicked) and recieves response or requests from server (and then changes UI).
Will service (and connection) be killed when phone fall asleep, needs more memmory or other? Is it big cost to the battery?
Maybe there are other ways? Thank you in advance for all your answers
P.S. sorry for poor english skills, hope you understood :)
You should probably use a Service, running in background.
Also, you really need not keep the service always alive with a network connection. You can opt for Google Cloud Messaging, which supports 2-way communication via the XMPP protocol. Using this protocol you can:
Receive notifications from server, start the service and do necessary processing.
Send notifications to server, upon which server does any necessary work.
These notifications are short 4kb messages , so they are better used as "commands" of a publish/subscribe model, which initiate other network heavy connections such as uploads and downloads. Rest of the time the service can be inactive to reduce resources consumption.
According to Android API Reference
"A Service is an application component that can perform long-running operations in the background"
And yes it consumes battery and you have to stop it by yourself:
" It's important that your application stops its services when it's done working, to avoid wasting system resources and consuming battery power"
So I think Services fit your needs.
If you need to communicate with the server when you want to send data to the server you can do it and wait for answer. If you need to send data from server to the device then take a look at push notifications.