0

I am trying to use a BroadcastReceiver to trigger the SyncAdapter when there are changes in the database server (using GCM).

When the receiver is told to start the sync process, I get the following error

ContentResolver.requestSync(accounts[0], AUTHORITY, null);

This is what my BroadcastReceiver looks like

public class GcmBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "GcmBroadcastReceiver";

    public static final String AUTHORITY = TournamentContract.CONTENT_AUTHORITY;
    public static final String ACCOUNT_TYPE = TournamentContract.CONTENT_AUTHORITY;
    public static final String ACCOUNT = "default_account";

    // Incoming Intent key for extended data
    public static final String KEY_SYNC_REQUEST = "com.example.android.datasync.KEY_SYNC_REQUEST";
    public static final String MESSAGE_TYPE = "gcm";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "onReceive: here");
        // Get a GCM object instance
        GoogleCloudMessaging gcm =
                GoogleCloudMessaging.getInstance(context);

        // Get the type of GCM message
        String messageType = gcm.getMessageType(intent);
        /*
         * Test the message type and examine the message contents.
         * Since GCM is a general-purpose messaging system, you
         * may receive normal messages that don't require a sync
         * adapter run.
         * The following code tests for a a boolean flag indicating
         * that the message is requesting a transfer from the device.
         */
        if (MESSAGE_TYPE.equals(messageType) && intent.getBooleanExtra(KEY_SYNC_REQUEST, true)) {
            AccountManager am = AccountManager.get(context);
            Account[] accounts = am.getAccountsByType(ACCOUNT_TYPE);

            if (accounts.length == 0) {
                // todo create account if not already there
            }

            /*
             * Signal the framework to run your sync adapter. Assume that
             * app initialization has already created the account.
             */
            ContentResolver.requestSync(accounts[0], AUTHORITY, null);
        }
    }
}

I am confident my SyncAdapter is working fine because I have not noticed any problems in the periodic sync.

How do you think I can resolve this?

Thank you in advance! :D

1 Answers1

4

You didn't post the actual error, so it's hard to say what else might be wrong, but there is definitely one thing that is wrong:

The extras parameter of requestSync(Account, String, Bundle) must not be null.

If you look into the sources you'll the that the extras value is explicitly checked for null.

Here is the relevant code snipped of ContentResolver.java

public static void requestSync(Account account, String authority, Bundle extras) {
    requestSyncAsUser(account, authority, UserHandle.myUserId(), extras);
}

public static void requestSyncAsUser(Account account, String authority, int userId,
        Bundle extras) {
    if (extras == null) {
        throw new IllegalArgumentException("Must specify extras.");
    }

So you can see that requestSync calls requestSyncAsUser which throws an IllegalArgumentException if the extras Bundle is null.

If you don't have any extras to pass you should pass Bundle.EMPTY like so:

ContentResolver.requestSync(accounts[0], AUTHORITY, Bundle.EMPTY);
Marten
  • 3,802
  • 1
  • 17
  • 26