Android Sync Adapter Intervals - android

I require a data sync once per day for an Android application. I've been using Sync Adapter which has been very useful. I want to sync the data only once per day (at no specific time). I'm using the addPeriodicSync() method.
My problem is that users are only likely to enter an area with internet access for very short periods at different times of the day (sometimes not in internet access areas for days at a time). I have the sync interval at 1 day, will the sync process be run as soon as the internet becomes available? or will it only attempt to sync when the period sync timer is triggered?
Additionally, are there any options to enable/disable 3G/Mobile internet syncs?

Yes by design sync adapters will queue all sync request in absence of network , also if user asks for manual sync when auto sync is already in queue then it will handle it . That's the beauty of sync adapter design

Related

Posting data to server every 15 minutes using Sync Adapter and Alarms

Requirement - I need to get the user's location coordinates every 15 minutes roughly and post it to the server. It is necessary to post data roughly at these intervals.
Implementation - I've made a sync adapter instead of using AlarmManager as it saves battery. I've set ContentResolver.addPeriodicSync() to sync my app every 15 minutes roughly which gets the current location and posts to server.
Problem - In case there's no internet connection, I want to continue taking the user's location every 15 minutes and save them in the local sqlite database. When the internet comes back again next time then I'll post all the saved locations in one go so that server data remains consistent and after that sync will resume as normal.
The main problem is that when there's no internet then the sync stops and I stop getting periodic sync callbacks in my app and I'm not able to save data in the local database. So what I want is that even when there's no internet I keep getting callbacks at regular intervals till the internet comes back and auto sync starts again. Can the sync adapter do that?
One solution I can think of is that I get a broadcast when the Internet stops and at that moment I start using the AlarmManager to start a service every 15 minutes and get the location and save to local database. And when the internet comes back on then I stop using the AlarmManager and go back to auto syncing.
Solution 2 - Provided by David Medenjak below. It is also efficient due to AlarmManager's setInexactRepeating() behavior which tries to imitate Sync adapter's behavior by scheduling Alarms for different apps together to reduce the number of times the CPU wakes up. Also it leads to a little simpler implementation. Would this the better way than the previous solution comparing the pros and cons?
Still any better way to achieve this?
You are mixing two things:
Getting the user location every 15 minutes
Syncing the data with the server
If you start mixing those you have a service and sync adapter that are both strongly dependent on each other, you have to check for states which of those has run and which should run. You might end up with the exact thing that you want (syncing every 15 minutes, just cache it if user is offline) but it will be hard to test and maintain.
Always use a service that is run every 15 minutes to store the current user location.
Periodically sync all updates to the server. This may also happen to be every 15 minutes, but you should not depend on this.
By having one part just storing the location and the other part just synchronizing the data you will have a much easier time handling things. And you also don't have to worry about internet connection or the interval of the synchronizations (since sync adapters are not guaranteed to run at exact times).
Concerning battery life (comments)
There should be no big difference whether a SyncAdapter uses gps and posts it immediately or a service persists it for the time being until the adapter syncs it. As soon as a task has to run every x minutes the device will have to wake up.
There might be slight improvements if the synchronization is run at a slower rate compared to the service, since the gps alone might not need any internet connection.
IntentService - runs every 15 min (using AlarmManager) and saves the user location in the db and mark it as unsent.
SyncAdapter - runs every 15 min and ties to send all unsent locations to the server. On success mark the location as sent. Android will make sure it's only run when there is a internet connection.
Edit:
The key point is separating the two sub-tasks (also suggested by #David Medenjak):
1) Get a location update and store it in a db
2) Send the location updates to the server when there is a network connection.
The FusedLocationProvider has a method
requestLocationUpdates (GoogleApiClient client, LocationRequest request, PendingIntent callbackIntent)
for when your app is in the background. Link
This method is suited for the background use cases, more specifically
for receiving location updates, even when the app has been killed by
the system.
You can use a LocationRequest to set the priority, interval, power consumption. Link
When you receive the pending intent, you can insert the location in the database and request a sync using the sync adapter.

What happens if Sync Adapter fails first time sync? Does it wait for whole period to try syncing again?

For example if first time there is no network connection,does it wait for whole period (pollfrequency time, addPeriodicSync) again to try syncing again (REST with local database)?

Android SyncAdapter frequency

I'm trying to build a SyncAdapter that should be run every few seconds to quick check for specific data.
I'm using following code to run SyncAdapter
ContentResolver.setIsSyncable(account, CONTENT_AUTHORITY, 1);
ContentResolver.setSyncAutomatically(account, CONTENT_AUTHORITY, true);
and the sync is trigerred correclty however I noticed that it's call only once every ten minutes.
Based on android training http://developer.android.com/training/sync-adapters/running-sync-adapter.html saying:
When a network connection is available, the Android system
sends out a message every few seconds to keep the device's TCP/IP
connection open. This message also goes to the ContentResolver of each
app. By calling setSyncAutomatically(), you can run the sync adapter
whenever the ContentResolver receives the message.
The network connection i available however it's only 3G connection, not WiFi - is this a reason on long wait?
How can I make my adapter to run every 10 seconds?
I already tried using periodic sync
ContentResolver.addPeriodicSync(account, CONTENT_AUTHORITY, new Bundle(), 10);
but it's still running every 10 minutes.
You are victim of the android SyncManager. Consider this scenario: you add a every 10 minutes sync for your application, but you have installed my application on your phone which as well asks the manager for a 10 minutes periodic sync and my application did the schedule requirement one second before than yours :) The sync operation of my application involves a transfer of big loads of data, hence using the whole ( or almost ) bandwidth of the available internet connection. The smart SyncManager will see that is not wise to start another sync process until the previous is done, and so it will wait the process to end, and only afterwards fire your sync.

How to trigger syncadapter event every day?

I'm using a syncadapter in my application. I need it to trigger an event every day, at 6 AM. Is that possible?
Is there a way to trigger a syncadapter event every day at a given time?
Thanks!
This may help:
ContentResolver.addPeriodicSync()
This, too:
Transferring Data Using Sync Adapters
Or, you can always trigger a sync yourself:
ContentResolver.requestSync()
However, I advise against doing a requestSync() unless you're dead certain that you need to sync with a server every day at 6 AM regardless of what's happened with the data. The point of a sync adapter is that the system helps you keep your device up-to-date without wasting battery. If you keep turning WiFi or data access off and on to do syncs, you're using far more battery than if you let the sync adapter framework schedule everything for you.
I feel like the accepted answer didn't really answer the question. This is what I found in the docs:
"Notice that addPeriodicSync() doesn't run the sync adapter at a particular time of day. To run your sync adapter at roughly the same time every day, use a repeating alarm as a trigger. Repeating alarms are described in more detail in the reference documentation for AlarmManager."
http://developer.android.com/training/sync-adapters/running-sync-adapter.html#RunPeriodic

Synchronization with ASyncTask on android

I am thinking about implementation of synchronization in my android application with ASyncTask and AlarmManager. Tried to do the same with SyncAdapter, but it just complicates the process and has other disadvantages (ContentProvider is needed, manual sync seems to be impossible if automated is disabled, user is needed etc.).
So, the question I have now with ASyncTask - let's say, it is started every 24 hours. But in case if there is not internet connection at this time, synchronization will not happen. Next time attempt will happen after 24 hours again. What can I do to avoid this? I.e. if 24 hours are already passed, then any time internet connection appeared, the task should be run. After this moment next 24 hours to be counted.
For ex.,
sync 1 - day 1 12:00 (successful)
sync 2 - day 2 12:00 (failed - no internet connection)
sync 3 - day 2 20:00 (successful, internet connection appeared)
sync 4 - day 3 20:00 (successful)
Believe, I can either run my task more often (for ex., each 30 minutes) and store time of last update somewhere. Or, I can listen for event when internet connection appears. What is the best approach? Or, is there some standard functionality for the same?
I would go with the BroadcastListener registered to do the syncing when internet connection is available. You could use the SharedPreferences to indicate for this listener, that sync is needed - because I guess you'd have to register this listener in the manifest, I think there's no way to handle this dynamically.
This way you can be sure that sync will happen if there's net connection available, while the 30-min-polling might miss the chance.

Categories

Resources