SyncAdapter Without an Account
Asked Answered
C

2

8

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?

Commissary answered 18/12, 2011 at 20:46 Comment(1)
Not a duplicate but related question Should I use android AccountManager?Antibiosis
A
6

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

Antibiosis answered 23/12, 2011 at 9:40 Comment(6)
And this is in my list of things that s.ck in the android frameworkAntibiosis
What I can't figure out is the Account/AccountManager side of things. I would prefer to not have the Account show up in the System Sync Settings as the user shouldn't need to see this. EVen if it has to be there (which seems to be true), what I can't have is requiring the user to enable or setup the Sync's Settings. That would kill the app's usability. I can't find a way to make an Account that is so dumb as to not show up. How do I make an account the user is unaware exists at all?Commissary
Yes, it has to be there. Why does-it bother you if the "Settings>Accounts & Sync" displays this? At least, the user can suspend the sync if he wants to save battery. Also, if the AccountManager is dumb, you don't need to ask the user to set anything. Maybe what you missed, is that you can register an Account in AccountManager programmatically.Antibiosis
Can I register it programmatically and have default settings? It would be acceptable if I can avoid forcing the user to go to the "Settings>Accounts & Sync" in order to use my app. Can I install default settings programmatically? Do you have an example/documentation on how to do this? Thanks!Commissary
Yes, the account type is provided by the application. It will be removed if the app is uninstalledAntibiosis
you can hide the account from the user by specifying android:userVisible="false" in your syncadapter.xml file. more: developer.android.com/training/sync-adapters/…Fatuity
S
5

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+.

Squama answered 2/2, 2012 at 15:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.