I have built a simple application that accepts data entered by the user and saves it to the local sqlite database. If wifi connection is available it will transmit the data to a REST service hosted on a remote server.
I have done the above part and it is working pretty fine. If WIFI is not available it will just move on and will expect new data from the user.
When the wifi becomes available, i have registered a broadcast receiver which will hit my database and get the values stored and send them to the remote server.
I would like to know, while the broadcast receiver is trying to query my database, if the user is entering data at the same time and it is being saved in the same database, will it fire a SQLException.
As i recall, only one service can access the SQL instance at a time. If it will pose a problem what shall i do to overcome it. I have looked at ContentProviders, would that be the solution?
I am fairly new to android. Please advice.
You may want to take a look at this.
What are the best practices for SQLite on Android?
For me, I would suggest to always create a ContentProvider together with DatabaseHelper when you need Database, no matter you need to provide your data to external application or not. It is actually not difficult to do, the best reference I used to build my ContentProvider is DeskClock, the official app from Android.
Edit:
As a side note, you should consider to create a IntentService to be called by your boardcast receiver to do the work, as broadcast receiver should not be used for long running task, like sending things to server.
BroadcastReceiver#onReceive
When it runs on the main thread you should never perform long-running
operations in it (there is a timeout of 10 seconds that the system
allows before considering the receiver to be blocked and a candidate
to be killed).
Related
I am developing an app that uses a database to store the data on the server, but I am trying to save some of the data locally, and in the event of no internet connection being established, save new data locally to the device and synchronize any changes to the server when an connection is re-established. What is the best and most efficient way to do this?
I have been looking at Androids Room persistence library and it seems like the logical choice, but I am not sure how it goes about synchronizing changes to/from the local storage database. I have looked at multiple threads and forums for help, but have had no luck so far. Please help.
One way is to build your own sync adapter: https://developer.android.com/training/sync-adapters
You will need to handle most of the sync logic between the client and the server, but that allows you to use any database technology in the server. From the docs:
A sync adapter doesn't automate any data transfer tasks. If you want to download data from a server and store it in a content provider, you have to provide the code that requests the data, downloads it, and inserts it in the provider. Similarly, if you want to send data to a server, you have to read it from a file, database, or provider, and send the necessary upload request. You also have to handle network errors that occur while your data transfer is running.
A sync adapter doesn't automatically handle conflicts between data on the server and data on the device. Also, it doesn't automatically detect if the data on the server is newer than the data on the device, or vice versa. Instead, you have to provide your own algorithms for handling this situation.
Use firestore and enable offline data persistence. https://firebase.google.com/docs/firestore/manage-data/enable-offline
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 see that there's an onDisconnect() firebase method, however it looks like that method is intended to update other client devices that the current client device has gone offline. For me this isn't very useful. All of our API calls are coming from a central server which handles updates to our other client devices.
Basically, I only have 1 client device communicating with the firebase server... ever. So my question is, when that single device loses connection how will I know? This is probably the most frustrating part of all, Not only do I not know when I lose connection, but I'm still making calls as if each command is successful.
Offline Behavior
Every client sharing a Firebase maintains its own internal version of any active data. When data is updated or saved, it is written to this local version of the Firebase. The Firebase client then synchronizes that data with the Firebase servers and with other clients on a 'best-effort' basis.
As a result, all writes to Firebase will trigger local events immediately, before any data has even been written to the server. This means the app will remain responsive regardless of network latency or Internet connectivity.
Once connectivity is reestablished, we'll receive the appropriate set of events so that the client "catches up" with the current server state, without having to write any custom code.
Take a look at Detecting Connection State in the Firebase Guide. It describes the magic data location /.info/connected that you can monitor for changes in the client's authentication state.
Note: For version 3.0+ see onDisconnect
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.
I have two threads, each of which handle syncing data one way either from the server or to the server. The thread for getting data off the server needs to run once a day. The other sending data to the server needs to run every 15 mins. I am currently using an Alarm Manager to create repeating alarms for each of these threads. This is then received by a BroadcastReceiver, from which i call an activity, which then according to the data passed into the activity either runs the to server syncing thread or the from server syncing thread. I am using the activity to display a dialog box, to prevent the user from using the application until the syncing has been completed as they both access the database required by the application. Is this the correct way to accomplish this task, or are there better alternatives?
Thank you in advance
This question is not really fit for SO... This is more a debate without any details on how your app works.
Anyway I would use an Android Service to do so. You do not need to bother the user just to upload data. Also why block the use of the app for uploading? Since for uploading you only need to read, just make a snapshot of the current data and upload it. Any changes the user is making right now will be uploaded in next upload, so that's not a problem.
For downloading, you most likely do need to block the app use, but maybe not. This depends on how the app works. You could start DB transactions to avoid doing that.