使用 BroadcastReceiver 启动 SyncAdapter

Using BroadcastReceiver to launch SyncAdapter

我正在尝试使用 BroadcastReceiver 在数据库服务器发生变化时触发 SyncAdapter(使用 GCM)。

当接收方被告知开始同步过程时,我收到以下错误

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

这就是我的 BroadcastReceiver 的样子

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);
        }
    }
}

我相信我的 SyncAdapter 工作正常,因为我没有发现定期同步有任何问题。

你认为我可以如何解决这个问题?

提前致谢! :D

你没有post真正的错误,所以很难说还有什么问题,但肯定有一件事是错误的:

requestSync(Account, String, Bundle)extras参数不能是null

如果您查看来源,您会发现 extras 值已明确检查 null

这里是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.");
    }

所以你可以看到 requestSync 调用 requestSyncAsUser 如果 extras Bundlenull,它会抛出 IllegalArgumentException

如果你没有任何额外的东西要通过,你应该像这样通过 Bundle.EMPTY

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