39

I want to implement a SyncAdapter for a content I want to synchronize with a server. It seems that to do so, you need a ContentProvider registered for the authority you specify in the SyncAdapter XML property file.

As I don't want this content to be accessible to the rest of the phone, I haven't implemented my own ContentProvider and used a personal implementation to store this content.

Do you know if it is possible to provide a synchronization using a SyncAdapter without providing a ContentProvider?

Thank you very much.

Moystard
  • 1,827
  • 2
  • 17
  • 18
  • related (later) question [Should I use android AccountManager?](http://stackoverflow.com/a/8614699/94363) – rds Dec 23 '11 at 10:09

2 Answers2

57

You always have to specify a content provider when implementing a SyncAdapter, but that's not to say it actually has to do anything.

I've written SyncAdapters that create accounts and integrate with the "Accounts & sync" framework in Android that don't necessarily store their content in a standard provider.

In your xml/syncadapter.xml:

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" 
    android:accountType="com.company.app"
    android:contentAuthority="com.company.content"
    android:supportsUploading="false" />

In your manifest:

<provider android:name="DummyProvider"
    android:authorities="com.company.content"
    android:syncable="true"
    android:label="DummyProvider" />   

And then add a dummy provider that doesn't do anything useful except exist, DummyProvider.java:

public class DummyProvider extends ContentProvider {

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
         return 0;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public boolean onCreate() {
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                    String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                    String[] selectionArgs) {
        return 0;
    }
}
Jerry Brady
  • 3,050
  • 24
  • 30
  • 2
    Thank you very much, I don't really like this idea of using a dummy provider but might have no choice. – Moystard Jan 11 '11 at 09:46
  • 3
    I looked for a long time for a better solution and found none and share your pain. – Jerry Brady Jan 11 '11 at 15:25
  • 7
    As an aside, the SampleSyncAdapter found in the SDK doesn't declare a content provider since it uses a native Android authority, com.android.contacts , which has its own provider com.android.providers.contacts . – ChaimKut Jan 31 '11 at 08:27
  • But how syncadapter is called? what are the coditions for being called? – Frederic Yesid Peña Sánchez Jun 05 '13 at 20:49
  • +1 "You always have to specify a content provider when implementing a SyncAdapter" – Zorb Jun 12 '14 at 10:31
  • @FredericYesidPeñaSánchez there are 2 conditions for syncAdapter to call 1. When user do manual sync 2. At least once in 24 hrs provided device is connected to network. – Ankit Jul 21 '14 at 05:48
  • 1
    Google's documentation suggests you do the same thing except they call it a "StubProvider." So, if you're not implementing a ContentProvider provide a "DummyProvider"/"StubProvider." There is no way around it. – ONE Jun 10 '17 at 22:13
6

Now, even the official documentation by Google suggest that you use a stub (dummy) ContentProvider.

https://developer.android.com/training/sync-adapters/index.html

Randy Sugianto 'Yuku'
  • 71,383
  • 57
  • 178
  • 228