SyncAdapter Without an Account

2019-03-13 10:51发布

I'm trying to create a SyncAdapter for my Android app to show YouTube videos from one specific channel. The videos are public domain so I don't want the user to login, create an account, authenticate themselves, upload data, or use the contacts database. I simply want the SyncAdapter to periodically update my app's database with the newest video metadata from that channel. I already built a ContentProvider to access my database. I do like the fact that the SyncProvider will handle the ability to turn off syncing, scheduling, and retry backoff mechanisms for updating.

I asked earlier if a SyncAdapter was a good choice for my use case, and I was told it was. I watched the Google I/O video, read the docs, read blogs... (see list below). I've been unable to get anything to work. The best I've gotten was to have the SyncAdapter account show up in the global "Accounts & sync settings" but be non-functional. Even if this worked, it would be less than ideal because I prefer the user to not see the account except from inside my app. This would be acceptable if there was no other option, so long as they don't need to access it to set it up as everything would default to automatic once a day syncing.

I even tried to use the SampleSyncAdapter as-is and put breakpoints in the Authentication code sections. Not a single breakpoint is hit so I can't see what triggers the calls or what data is contained. I would have thought I'd at least get that much.

I'm starting to think using a SyncAdapter is a bad idea despite the recommendation. I've yet to find an example that is close to what I want, let alone a tutorial or complete, organized and clear docs. This seems like it should be a common task many apps would want to do.

Please add to this post any good documentation on this use case. I can find none.
Without this, I think it's fair to recommend to everyone to not use SyncAdapters for this use case. I'm not speaking for other use cases here so don't jump on with how it worked for your use case if it's not like mine.

It would also be helpful to know what version of the API level is considered ready for primetime. There's a number of issues posted regarding version numbers. I'm trying to stay as low as possible to get the most users. My current API target is 7.

Here's list of links I've tried to no avail, others may find these more helpful:

http://developer.android.com/resources/samples/SampleSyncAdapter/index.html

http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html

http://naked-code.blogspot.com/2011/05/revenge-of-syncadapter-synchronizing.html

http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/

http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-2/

http://www.finalconcept.com.au/article/view/android-account-manager-step-by-step

http://www.finalconcept.com.au/article/view/android-account-manager-step-by-step-1

http://www.finalconcept.com.au/article/view/android-account-manager-step-by-step-2

Android SyncAdapter without Authentication vs. Android Service

Why does ContentResolver.requestSync not trigger a sync?

2条回答
淡お忘
2楼-- · 2019-03-13 10:51

As stated above, "ContentProvider, AccountManager and SyncAdapter go together". For your application you can call the following activity the first time your app is loaded to authenticate and start synching automatically:

public class LoginActivity extends AccountAuthenticatorActivity {

private final static String DUMMY_ACCOUNT_NAME = "some_name";
private final static String DUMMY_ACCOUNT_PASS = "some_pass";
private final static String AUTHORITY = "com.android.contacts"; // for example

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Account account = new Account(DUMMY_ACCOUNT_NAME, Constants.ACCOUNT_TYPE);
    AccountManager am = AccountManager.get(this);
    if (am.addAccountExplicitly(account, DUMMY_ACCOUNT_PASS, null)) {
        Bundle result = new Bundle();
        result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
        result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
        setAccountAuthenticatorResult(result);
        ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
    }

    finish();
 }
}

This works in Android API 5+.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-03-13 11:16

In short the answer is: ContentProvider, AccountManager and SyncAdapter go together. You must have these three pieces, even if they are "dumb".

查看更多
登录 后发表回答