Lisa Anne
Lisa Anne

Reputation: 4595

Android SyncAdapter: how to get notified of specific sync happened

I have the following scenario.

I use a SyncAdapter in my app to download data from a server.

When the user opens the app I call requestSync() to make sure the latest data are available.

When the user requests it I call again requestSync() passing a bundle of the specific datum I want to download.

The problem is the following:

I can use a SyncStatusObserver to get notified about the status of the download, but that will not tell me which sync is completed:

For example:

How can i do it?

Is intent broadcast the only way?

Upvotes: 2

Views: 1251

Answers (1)

Marten
Marten

Reputation: 3872

SyncStatusObserver won't tell you that, but there are multiple ways to accomplish that and it depends a lot on your architecture.

Here's one that works for us:

We're planning to let our SyncAdapter return another IBinder and return that one when binding our SyncService with a specific action. This IBinder object will provide information about the current status of the sync adapter. This works because there's only one instance of a sync service and our sync service holds exactly one instance of the sync adapter.

Here's a quick example:

At present the onBind(Intent) method of our sync service looks like this:

@Override
public IBinder onBind(Intent intent)
{
    return sSyncAdapter.getSyncAdapterBinder();
}

Where sSyncAdapter is a static instance of our sync adapter.

We're planing to change that to something like this:

public final static ACTION_SYNC_INFO = "com.example.SYNC_INFO";

@Override
public IBinder onBind(Intent intent)
{
    if (ACTION_SYNC_INFO.equals(intent.getAction())
    {
        // sync info binder has been requested
        return sSyncAdapter.getSyncInfoBinder();
    }
    // otherwise return the sync adapter binder
    return sSyncAdapter.getSyncAdapterBinder();
}

In our activity we bind our sync service and set the action SyncService.ACTION_SYNC_INFO. That tells the sync service to return the sync info binder instead of the sync adapter binder.

The binder will have an interface that could look like this:

public interface SyncInfoBinder extends IBinder
{
    public boolean isTotalSync();
}

Of course, the sync adapter still needs to implement this method which (in your case) could look like this:

private abstract class AbstractSyncInfoBinder extends Binder implements SyncInfoBinder
{
}

private final IBinder mSyncInfoBinder = new AbstractSyncInfoBinder()
{
     @Override
     public boolean isTotalSync()
     {
          // return some field that was set by your onPerformSync method
          return mCurrentSyncIsTotalSync;
     }
}

public IBinder getSyncInfoBinder()
{
    return mSyncInfoBinder
}

Of course that only works this easily if your sync adapter is set to be single threaded. For multi-threaded sync adapters you have to take additional steps to make sure you get the status of all ongoing syncs.

In any case this is a nice way of getting live results from the sync adapter to present them in your UI.

Upvotes: 1

Related Questions