Alex Rivera | Logout

Why does ContentResolver.requestSync not trigger a sync?

Asked 2011-03-09T23:56:42.483
113

I am trying to implement the Content-Provider-Sync Adapter pattern as discussed at Google IO - slide 26. My content provider is working, and my sync works when I trigger it from the Dev Tools Sync Tester application, however when I call ContentResolver.requestSync(account, authority, bundle) from my ContentProvider, my sync is never triggered.

ContentResolver.requestSync(
        account, 
        AUTHORITY, 
        new Bundle());

Edit -- added manifest snippet My manifest xml contains:

<service
    android:name=".sync.SyncService"
    android:exported="true">
    <intent-filter>
        <action
            android:name="android.content.SyncAdapter" />
    </intent-filter>
    <meta-data android:name="android.content.SyncAdapter"
    android:resource="@xml/syncadapter" />
</service>

--Edit

My syncadapter.xml associated with my sync service contains:

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"  
    android:contentAuthority="AUTHORITY"
    android:accountType="myaccounttype"
    android:supportsUploading="true"
/>

Not sure what other code would be useful. The account passed to requestSync is of "myaccounttype" and the AUTHORITY passed to the call matches my syc adapter xml.

Is ContentResolver.requestSync the correct way to request a sync? It looks like the sync tester tool binds directly to the service and calls start sync, but that seems like it defeats the purpose of integrating with the sync architecture.

If that is the correct way to request a sync then why would the sync tester work, but not my call to ContentResolver.requestSync? Is there something I need to pass in the bundle?

I am testing in the e

Edit
Report

1 Answer

283

Calling requestSync() will only work on an {Account, ContentAuthority} pair that is known to the system. Your app needs to go through a number of steps to tell Android that you are capable of synchronizing a specific kind of content using a specific kind of account. It does this in the AndroidManifest.

1. Notify Android that your application package provides syncing

First off, in AndroidManifest.xml, you have to declare that you have a Sync Service:

<service android:name=".sync.mySyncService" android:exported="true">
   <intent-filter>
      <action android:name="android.content.SyncAdapter" /> 
    </intent-filter>
    <meta-data 
        android:name="android.content.SyncAdapter" 
        android:resource="@xml/sync_myapp" /> 
</service>

The name attribute of the <service> tag is the name of your class to connect up sync... I'll talk to that in a second.

Setting exported true makes it visible to other components (needed so ContentResolver can call it).

The intent filter lets it catch an intent requesting sync. (This Intent comes from ContentResolver when you call ContentResolver.requestSync() or related scheduling methods.)

The <meta-data> tag will be discussed below.

2. Provide Android a service used to find your SyncAdapter

So the class itself... Here's an example:

public class mySyncService extends Service {

    private static mySyncAdapter mSyncAdapter = null;

    public SyncService() {
        super();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (mSyncAdapter == null) {
            mSyncAdapter = new mySyncAdapter(getApplicationContext(), true);
        }
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return mS
answered 2011-03-10T04:09:54.520

Your Answer