Handling login and remember me with the AccountManager

mgv picture mgv · Mar 14, 2011 · Viewed 9.2k times · Source

I've integrated android's account management in my application and I can manage accounts from the Accounts & Sync settings.

I want to have the classic login activity that forwards the user to his home activity on successful login, having the option to remember the user's password. However, the AccountAuthenticatorActivity must return its result to the AccountManager with the credentials and the rest of the account information, calling an explicit finish() and returning the intent.

How can I give the AccountManager the info it needs without having to finish() my login activity?

Answer

jcwenger picture jcwenger · Mar 16, 2011

AccountManager is not meant to be called by an interactive application, but rather by a Sync Adapter. (A great tutorial is "Did You Win Yet? » Writing an Android Sync Provider" Part 1 and Part 2 which gives great code examples but doesn't do as great a job of explaining the data flow.) It's like this:

You develop a ContentProvider which wraps a database. You build a SyncAdapter (this is a background Service) to connect to a server and fetch data and sync the ContentProvider to match the server. Then, your UI queries to the ContentProvider to show the fetched data. There are some methods to directly query for specific information as well, if you want to search and cache results for example. See Developing RESTful Android Apps for a nice hour-long session on how the data model should look. They give three architecture examples, starting from a "naïve" implementation then progressing to the proper SyncAdapter model.

As for authentication itself, the way SyncAdapter uses the AccountManager is to obtain an authentication token. This is a (often) a big hexidecimal value, that is passed as part of the HTML headers in lieu of a username/password pair. Think of it as a one-session unique key. Posession of the key is proof of authentication, and they expire periodically. When they expire, you reauthenticate and fetch a new one. SyncAdapater asks AccountManager for an auth token for a specific account-type / username combination. AccountManager auths with the server (asking the user for a new password if necessary due to change) and returns the token to the SyncAdapter, which uses it from then on.

If this model isn't appropriate for your application, you need to manually handle login/logout in your app code instead. Kind of a pain, I know.