155 comments on “Write your own Android Authenticator

  1. I do not understand this. Everything I know on web is self taught. Call me illiterate. Please explain in layman’s terms

    • Hey,

      Some of the stuff here requires prior knowledge.

      Explaining every concept presented here will get this post be at least 3 times bigger.

      I’d recommend reading about OAuth2, to understand authentication methods, and also the links I refer to on this post (they provide further information about the subject).

      Good luck!

  2. Hi!
    First of all I have to say, that this piece of code is really really helpful. Thank you so much for that.

    I only stumbled across one issue.
    1. I added an account for my first app, which worked like a charm.
    2. I reused the same Service for my second app: Getting and invalidating tokens works as expected, also the invalidating part. The only thing I am struggeling with is the “Add Account” – part.
    If I press on the button nothing happens. I think there is something wrong with binding the service, but I have not figured out what the issue really is.

    Maybe you can me point me in the right direction, why I am not able to open up the “Sign – In” – page in my second app.

    Other than that, thanx for your code and the awesome explanation.
    br MikeT

      • Perfect!
        What a fast reply. That little change did the trick! Thanx, you saved me from getting millions of grey hair 🙂
        All the best. And keep up the good work.

    • Hey Mike, below it sounds like you were able to make this work by changing authenticator.xml. Could you explain what change you made?

  3. You can 2-way encrypt the password you’re storing in the AccountManager with a device-specific key. It’s recommended that you do that with the auth_token as well, for the same reason that storing the plain text password is insecure. That way, the password and auth_token are never known by the AccountManager. There’s a Android dev blog post on encryption.

  4. I’ve been searching for an explanation like this. I’ve a little question, if i want that the first time that i open the app, ask me to log in and if the log in is succesfull then open another activity, i need to put the authenticator activity like the launcher activity?

    • No, that’s what’s cool about this method.

      You can start your main activity and try to get an auth token. If there isn’t one – the framework will automatically raise the authentication activity and return the response back to your main activity after the user has successfully logged in.

      • Hi, i trying to get an auth token inside my main activity, but nothings happen

        mAccountManager.getAuthTokenByFeatures(SyncConstants.ACCOUNT_TYPE,
        SyncConstants.AUTHTOKEN_TYPE, null, this, null, null, null, null);

        the application never display the login activity automatically, what do you think?

  5. Thanks for the great explanation! It’s by far the best i found on the net.
    I do have a problem trying to use the code you provided: I get an ActivityNotFoundException for”:
    com.udinic.accounts_authenticator_example/com.udinic.accounts_authenticator_example.authentication.LoginActivity”
    – when trying to add a new account. I can’t find any place that LoginActivity is invoked, and I haven’t changed the code.
    In a previous post you suggested looking at the values in the authenticator.xml. At what values specifically ?

    • The LoginActivity is probably invoked by the AccountAuthenticator itself. Check there. You need to declare that activity in your app to make it work.

  6. “2. First in, first served ”

    I created a library project and created the full suite, the authenticator, the activity and the service (almost like the good the bad the ugly :P).

    I’m using the library (a.k.a authlib) in two different projects. I installed both apps in the device.

    Almost ALWAYS, only the first app’s “addAccount” from the Authenticator class gets called. Anytime i open the second app and try to invoke the account adding flow, it doesn’t seem to bind properly. I’m not sure why. Any help would be greatly appreciated.

    p.s: I’m trying to use 1 account for two apps. But the “adding of the user” should be possible from either of the apps and should not be dependant on the sequence of the installation.

    • The order of the selected authenticator is OS implementation and unfortunately cannot be changed.

      HOWEVER,

      I believe you can do what you need following these steps:

      1. On the authenticator project, create 2 sign-up activities, having their own log-in flow according to what you need for each app using this library.
      2. When calling the account manager to add an account, for any of the 2 apps, you can pass an “options” extra to the method. Pass “APP1” or “APP2” in the Bundle.
      3. On the authenticator’s addAccount() method – read the “options” extra and start the appropriate sign-up flow.

      I haven’t tried it, but I think it can work.

      If you do try this – please report back for other people to learn.

  7. Hi, thanks for sharing this. It helps me a lot to understand the flow.
    There is one thing I do not understand. I understand that in OAuth2.0 you have to provide an client_id to get an accesstoken. It seems that you are not using this. How can this be communicated via the account manager to the authenticator?

    • The algorithm to acquire the auth token from the server is up to you. If you need to pass a client_id, API key or a CAPTCHA – that’s your responsibility to do that on the authenticator when acquiring the auth token. After that – you just store the auth token in the account manager as any other authenticator will do.

  8. Hi. When i tried both the source code project and the google play sample, the authentication is successful, but always when i access the Udinic account configuration my phone crashes and restarts… In the Logcat it tells about some ‘Error inflating class Switchpreference’. What i am doing wrong?

    • You probably running this example on an unsupported API level device. Switchpreference exists since API 14, you’re probably running this on device <ICS.

  9. Pingback: Write your own Android Sync Adapter | udinic

  10. Hello,

    i am trying to use AccountManager in an Activty under Application (not Service), but without sucess. I use an 4.3 emulator (Intel image). I can easly liist all accounts on the emulator (added via android interface) but when I want to create one an Error comes in:

    09-14 13:21:21.863: E/AndroidRuntime(3291): FATAL EXCEPTION: main
    09-14 13:21:21.863: E/AndroidRuntime(3291): java.lang.SecurityException: caller uid 10046 is different than the authenticator’s uid
    09-14 13:21:21.863: E/AndroidRuntime(3291): at android.os.Parcel.readException(Parcel.java:1431)
    09-14 13:21:21.863: E/AndroidRuntime(3291): at android.os.Parcel.readException(Parcel.java:1385)
    09-14 13:21:21.863: E/AndroidRuntime(3291): at android.accounts.IAccountManager$Stub$Proxy.addAccountExplicitly(IAccountManager.java:719)
    09-14 13:21:21.863: E/AndroidRuntime(3291): at android.accounts.AccountManager.addAccountExplicitly(AccountManager.java:612)

    My code snippets are:

    Login.java ->

    AccountManager accountmanager = AccountManager.get(this);

    Account userAccount = new Account(“Test”, “cg.activities”);

    if (accountmanager.addAccountExplicitly(userAccount, “pass”, null))
    System.out.println(“Added success”);
    else System.out.println(“Added failed”);

    res/authenticator.xml ->

    manifest ->

    I searched trouhg Google and StackOverflow, but without result. Tried it on 2.2 Android phone and the error is the same. Your app works on my phone. Drives me wild :S

  11. Hey Thanks for your great tutorial here. can you please explain more about server part of your app. here you said you use parse.com servers. I want to implement my own server. what is the approach for returning auth token?

  12. Simply desire to say your article is as amazing. The clarity to your publish is simply great and that i could suppose you are a professional
    on this subject. Well along with your permission let me to snatch your feed to keep updated with coming near
    near post. Thank you a million and please continue the gratifying work.

  13. Hey there!

    I am just curious if it is possible to use one and the same account for multiple apps. I am able to request account information from a different account, but is it possible to add Accounts to the same AccountManager from different apps?

    Similar to what google does with their Gmail account which is used for the mail app, hangout, g+,…

    I researched a while and am still not sure if this is possible and if its good practise. I would appreciate if you could give me some input.

    best regards,
    Mike

    • You can share the account type between apps if they all share the same signing signature.

      If you install 2 apps with the same account type, but signed with different keys, you’ll get a “SecurityException: caller uid XXXX is different than the authenticator’s uid” when trying to add an account from the second app.

  14. Thanks a million……. I was here to implement sync adapter and I get to know about this post. This post is really amazing. Now I am really interested to implement it in my application.

    You’ve used the parse.com servers, the problem is I want to implement is on my own server.

    Could you please upload some server side code? Some php code?

    It would be really really big help for me, and I will be really thankful to you for this favor!

    Well worked bro. Keep this stuff coming…. We love you!

    Best Wishes!

    • Hey

      I didn’t write any server code for this example, and a server code will be different from one implementation to another. It can also be done in many different languages/platforms.

      I suggest you search the internet from some “inspirations” and then implement your own.

  15. Pingback: CopyQuery | Question & Answer Tool for your Technical Queries

  16. Pingback: Android AccountManager permission for a single custom account type | BlogoSfera

  17. It is the first day I do anything related to Android,
    The first thing to start with is authentication stuff,
    Thanks for this full covered workflow!

  18. Thank you for the full explanation!
    I would like to write my own authenticator to use between all my related apps.
    I can’t get it to work with more that one app.
    When I use your sample code, only the first installed app opens the authenticatorActivity (By clicking the “addAccount” button) and the second app does nothing when clicking this button.
    I read others commenting on the same thing. Can you please explain why? I really need this to work for me 🙂
    Thank you!

    • Using the same authenticator will require you to use a library project for the authenticator, and linking to it from any app that you wish using it.

      Regarding your problem, have you checked the logs to see if there’s any error?

      As I wrote on “Random stuff you may want to know” section 2, the first app to be installed will register its authenticator. Meaning, other apps needs to be signed with the same signing key in order for them to access the authentication data the first app saved.

      • Hi, This is what I did- The authenticator is in a library and the two apps (Signed the same) are using it.
        When I am checking your example its the same- Only the first installed app response to addAccount().

        This is what I get in the log:
        10-22 11:39:35.437: D/udinic(31466): UdinicAuthenticator> addAccount
        10-22 11:39:35.707: D/dalvikvm(31466): JDWP invocation returning with exceptObj=0x41d8f138 (Ljava/lang/NullPointerException;)10-22 11:39:35.737: D/dalvikvm(31466): JDWP invocation returning with exceptObj=0x41d8f6b8 (Ljava/lang/ClassNotFoundException;)

        I understand that the first installed app is registering the authenticator but it looks like the second app can’t reach it. Any suggestions?….

  19. Sorry but your uploaded project is slightly unclear. I cannot get the app to work on my device. Do I have to create an entire new project to test example 1 and 2. When I try and runt the main.java files in Eclipse the AuthenticatorActivity.apk is installed but nothing is launched. This is not surprising as the manifest does not include a launcher activity.

    How are you supposed to test your example apps?

  20. Hi,

    Thanks for sharing your experience with the Android AccountManager. Could you please add a link to the Article in the Android documentation where you took the picture of the getAuthToken() method from? I couldn’t find it by myself.

    Thanks!

  21. Hi

    First of all let me comment you for a very great tutorial you have put up it is very insightful and helpful. However I have a question and I think you could probably help. I want to do something that will allow the user to create account and the sign in once in an environment where there is a network communication and then stores and encrypt the user’s authentication details on the device for future sign in in the event that the user is in a place where there is no network communication. Can you please advice on how this can be done. Thanks

  22. Hi,

    great tutorial. its working like a charm.

    now i want to know if you could give me a lead.
    i will have a couple of applications, all using one type of authentication.
    What i want to do is check if the account exists in any of the applications, and if there is no account created, call the authentication module for create one.

    i almost accomplish that but i dont know why android are asking for modification permissions. in both applications. is this correct or im doing something wrong?

    regards.

    • It’s not quite clear what you are trying to do.

      When do you check that? When the app first launches? In that case just try to get an auth token and the authenticator will start the log-in activity for you in case there are no credentials stored already.

      Please clarify your question.

  23. Hi Udinic,
    Its Very very great Tutorial. Really it simplified my understanding about AccountAuthenticator. But still I have one problem regarding following :
    1. How to Check existing account validity if the user is already logged in and already that account exists. Your help will be appreciable .
    Regards.

    • Well..you can use the account’s credentials and see that they still valid against the server. If they are not – just invalidate them using invalidateAuthToken, and next the app will try to use them – it’ll ask the user for new credentials.

  24. Pingback: How to implement user login with google, facebook or twiter in android app?CopyQuery CopyQuery | Question & Answer Tool for your Technical Queries,CopyQuery, ejjuit, query, copyquery, copyquery.com, android doubt, ios question, sql query, sqlite query

  25. Thanks for the article, it was very helpful. One thing that is worth noting: you’ll need to add android:exported=”true” to the login and register activities in order to access them from the second application. Without that, you’ll get a securityexception from the second app complaining that the activity is not exported.

    • I have just implemented Android Authenticator using this blog post and I did not store the password at all. You do not have to put actual password there. I think it is optional.

      In this example, when the user token is not valid, it uses that stored password and re-authenticate immediately. If you do not store the password, you just have to ask for the password again.

  26. Hi,

    Thanks for the great tutorial. One thing I wanted to mention:

    I think it would be better if you put the explanation of “sServerAuthenticate” and “authTokenType” before the creating activity part. Because in the getAuthToken() method, both of them are used and it was a little confusing (at least for me) not having any explanation about them right after that part.

  27. Hi,

    Thanks for the great tutorial, clears up all the things, but maybe you can help with a related question.

    I need to create a client app for an OAuth2 API using a Bearer token for authentication. At the time of obtaining the token, I receive the expiry timestamp for it, but I am unclear about where to store and how to utilize it. Problem is, if I don’t want to have unnecessary trips to the server, the app would realize that the Bearer had become invalid only after it receives a HTTP 401 error from the server.

    – Should every network request in my code have a retry mechanism in case the bearer token has become invalid in meantime?
    – Can SyncAdapter somehow help with this?
    – As I am new to Android development, is there maybe anything else?

    Thanks!

    • The correct way to handle invalid auth tokens is using the invalidateAuthToken() whenever you get a 401 from server.

      Doing that, will cause the authenticator to authenticate the user again, instead of returning the auth token again.

  28. Hi,

    I want to a Switch as you have prefs.xml. I should be able to read the value from the application, who is responsible for account and not from the settings.

  29. Problem solved, I didn’t know that account type must be the package name ! I have two questions (for now) to ask : When an auth token is no longer valid (time elapsed) do I need to “refresh” it “manually” ? How to automatically detect password change ?

  30. Thanks Udinic for this great tutorial. Browsing the code on Github i saw a comment on the AccountAuthenticatorActivity where you said that ” There can only be one AuthenticatorActivity ” from witch you started a second activity (sign up activity) and i was wondering why. Can’t you just start another AuthenticatorActivity from the main activity just for the sign up?

    • Activities who are extending from “AuthenticatorActivity” has special properties. Starting a new activity like this has implications of information retrieval and status codes code returned to the Authenticator itself.

      Every AuthenticatorActivity is linked to the account authenticator and returns information it needs once the user has submitted data in it (such as username/password). You can take a look at the AuthenticatorActivity source code and learn more about its properties and the things it does.

      Because it’s a special type of activity, you cannot just start a new AuthenticatorActivity.

  31. Where do you check if the token has expired? I have a server which gives me the timestamp and expiry time. I want to store both these fields into account manager and check if the token has expired. I am not sure – how are you handling the token expiry check?

  32. Hi
    Nice tutorial. But i dont want to use oAuth. I have an own login screen and authenticate with ldap. Can you tell me how to create oauth and session id for this case

  33. Pingback: Android AccountManager no account after restarting applicationCopyQuery CopyQuery | Question & Answer Tool for your Technical Queries,CopyQuery, ejjuit, query, copyquery, copyquery.com, android doubt, ios question, sql query, sqlite query, nodejsquery

  34. Has anyone tried accessing the Authenticator from an app which is signed by a 3rd party ? Using the sample code, out of the box, I keep getting “W/Binder(461): java.lang.SecurityException: Activity to be started with KEY_INTENT must share Authenticator’s signatures”

  35. i whould like to sync contact like what’sapp .but i confuse in server side concept because i download whatsapp at first time and its show all contact which have already what’s app user please help me how to apply this concept in my application. do you have any idea and reference pls suggest me.

  36. Hi Udinic,
    I have two applications which are signed by the same signature. In order to get/set user data the AccountManager documentation specify that both apps should have the same sharedUserID in the manifest file but when i do that i cannot seem to update the applications due to different sharedUserID. the other weird thing is that when i’m not using sharedUserID at all everything works fine as opposed to the documentation.
    Will it be safe to do it without the sharedUserID?

    • You need to have the same shared user id for that to work. Try to uninstall and reinstall your apps again after you set their sharedUserId to be the same.

      • Thanks for the reply.
        I’ll try to explain more.
        i have two applications that share the same authenticator code.
        Both apps are signed with the same signature.
        UID in the manifest file is not set for any of the apps.
        I cannot uninstall and reinstall the apps or change their UID in the manifest file as they are both already published to google play.
        AccountManager.getUserData() and AccountManager.setUserData() documentation state that in order to call them the caller UID should be the same as the authenticator UID in addition to the same signature.
        If i try to call AccountManager.getUserData() from any of the apps i don’t get any exception even though they don’t share the same UID(it contradicts the documentation).

        Am I missing something here?
        Thanks.

  37. After I initially left a comment I appear to have clicked on the -Notify me when new comments are added- checkbox
    and now every time a comment is added I
    get four emails with the same comment. Perhaps there is an easy
    method you are able to remove me from that service? Thanks a lot!

  38. How does this approach work when using account types for 3rd parties? For example, lets say that I want to authenticate against LinkedIn and the LinkedIn app isn’t installed, so there is currently no LinkedIn account available. I can create the authentication logic the way you have shown in this tutorial, but then wouldn’t I have to set the icon, title, description, etc. for the LinkedIn account? Then if the user eventually does install the LinkedIn app, there would be 2 LinkedIn accounts – one official, one unofficial. Any thoughts on this situation? Thanks.

    • Well..if you want to use the other app’s logged-in account, you need it to be installed first. If you want to create *your own* account that connects to their server and retrieve an auth-token, you can do that too, but it’ll need to be a different account type than the one they are using, otherwise – installing their app will lead to a security exception.

      Linkedin is not a good example, since I know they don’t use an authenticator (at least they didn’t 6 months ago), but let’s take Dropbox as an example. If you will create an account type with exactly the same name as they did, there will be a problem installing Dropbox after your app, since they both need to share the same account type and both have different signing keys, which is a security problem.

      You can try that and see for yourself what happens in such situation.

  39. Pingback: Android: How to implement an account login system? | questions android

  40. Well done for the great work and the comprehensive tutorial. Simple, relevant and functional; as all things should be.

  41. hello udinic i cant sync my application with contact…i required to syncr contac with my apps…like whatsup install in my phone i get in all contact which one use ….so do this type of synchronization pls help me its a very important for me…

  42. Hi Udinic,
    Really thanks for this nice tutorial.
    I am able to run it.
    But I see my app in accounts only when I add it manually.
    How can I achieve it without adding manually, as other app comes.

    Thanks in advance.

  43. Grea site. A lot of ueful information here. I’m sending iit to a few buddies ans additionally sharing in delicious.
    And of course, thasnks on your effort!

  44. What’s Taking place i am new to this, I stumbled upon this I’ve found It positively
    helpful and it has aided me out loads. I’m hoping too
    give a contribution & aaid other customers lile its aided me.
    Good job.

  45. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my
    blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time and was hoping maybe
    you would have some experience with something like this.
    Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your
    new updates.

  46. Hey, thanks for this great tutorial. I hope you’re still looking at comments because I’ve been fighting with this for a couple days now.

    I’m using getAuthTokenByFeatures() as it’s supposed to encapsulate all the logic of using an account if it’s already there (and there’s only 1), or showing a picker to the user if there’s more than 1, or creating the account if there are none. I’ve found that last statement a little misleading as I still had to do the addAccountExplicitly() in my AccountAuthenticatorActivity. However, once I did that, it worked… mostly.

    If AccountManager has a token cached (and thus doesn’t even need to call my authenticator), then my callback I specify on the getAuthTokenByFeatures() gets called with the AccountManagerFuture. However, if it DOESN’T have a token cached (or I need to create a new account, both behave the same), my callback NEVER gets called. The account is added in AccountManager, and next time I come in it’ll work because the token is cached and it doesn’t call my authenticator. But any time my authenticator is in the picture, the callback isn’t called.

    This is the code I have at the end of my authenticator’s getAuthToken():

    // Didn’t find a valid token. Return a response that’ll show the login screen.
    Intent intent = new Intent(mContext, LoginActivity.class);
    intent.putExtra(Constants.KEY_AUTH_TOKEN_TYPE, authTokenType);
    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);

    Bundle result = new Bundle();
    result.putParcelable(AccountManager.KEY_INTENT, intent);
    return result;

    And this is the code I have in my AccountAuthenticatorActivity that should return the result:

    // Done. Tell the AccountManager what we got/created.
    Intent intent = new Intent();
    intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mEmail);
    intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType);
    intent.putExtra(AccountManager.KEY_AUTHTOKEN, loginResult.getAuthToken());
    intent.putExtra(KEY_LOGIN_RESULT, loginResult);
    setAccountAuthenticatorResult(intent.getExtras());
    setResult(RESULT_OK, intent);
    finish();

  47. Hy bro !
    i am new in android. How i can do drive api authorization for android application.?
    I saw google drive authorize tutorials but no thing find help full.
    plz help me I will be very thank full to you.

  48. Hi, I would know where does your variable mAccountManager come from in the login activity ?

    I tried your code by using this in finishLogin method :
    AccountManager mAccountManager = AccountManager.get(this);

    But I have a SecurityException error (caller uid different thant authenticator’s one)…

    I think I musn’t declare the variable here, but where ?

  49. I like the helpful info you provide on your articles.
    I will bookmark your blog and check once more here
    frequently. I’m fairly certain I’ll learn a lot of new stuff right right here!

    Best of luck for the following!

  50. Hi, Udinic,

    I am getting false from “getIntent().getBooleanExtra(ARG_IS_ADDING_NEW_ACCOUNT”
    when login complete succesfully .

    But the method ::

    private void finishLogin(Intent intent) {
    if (getIntent().getBooleanExtra(ARG_IS_ADDING_NEW_ACCOUNT, false)) {
    }else {
    Log.d(“Rufaida Medical”, TAG + “> finishLogin > setPassword”);
    mAccountManager.setPassword(account, accountPassword);
    }
    }

    my code always execute else block. please describe me how can I get value true of “getIntent().getBooleanExtra(ARG_IS_ADDING_NEW_ACCOUNT”

    I am waiting for your response.

    Thanks

    Hossain

  51. Hi Udinic,

    Thank you for this great sample! I would love to have latest version of this code. I download the apk which works fine but the code in github doesnt let me create new user

  52. Hi Udinic,

    Thanks for a great tutorial. I have a query. I need to know what configurations do we need to do on Parse.com side. Actually, I have to present a demonstration to someone with sync adapter and account authentication.

  53. Pingback: [转]launchAnyWhere: Activity组件权限绕过漏洞解析(Google Bug 7699048 ) | 陈影中心

  54. I’m implementing my own authenticator and I found a strange possibility and I was curious how you handle it.

    Let’s say I invalidate an auth token for account “gator”, then I show an account selector to select an account and I choose “gator”. Then I try to get gator’s auth token. The auth token doesn’t exist so Android launches my registered AccountAuthenticatorActivity.

    The thing is, once I’m in AccountAuthenticatorActivity, I can enter any username, not just “gator”. So I could end up logging in as “crocodile” and then crocodile’s auth token gets saved under gator’s account. How would you deal with this? Should the AccountAuthenticatorActivity auto-populate the username and prevent the user from entering a different username when its being used to renew a token on an existing account?

    • You don’t even need to show anything to the user. If you’re not expecting for any input from the user, just do your thing and call finish() to close the activity.

  55. hi while running this source code in android,it shows an error “Android library projects cannot be called launched “.how can i resolve this???pls kindly help me out

  56. Pingback: Android OAuth2 Bearer token best practices | Zourkos Answers

  57. Hi Udinic,

    Thanks for a great tutorial !

    could we implement authenticator same account type but diffirent auth token type for each application. I tried but as you said, first in, first serve, so i can’t get token with diffirent auth token type for second app.

    • What I would recommend is creating one authenticator to support both auth tokens, then add it as a library to both of you apps. That way, it doesn’t matter which app was installed first, they will both support the 2 auth token types.

  58. Pingback: Accountmanager vs sharedpreference for authentication and server communication | Alysa

  59. Pingback: Authenticator | Pursuing Software Ideas

  60. Pingback: Contacts | Pursuing Software Ideas

  61. great job ,
    can u have any video tutorial…because account manager in anadoid have no video on youtube…
    i hope you upload and discribe all things of Accountmanager….
    Thnks alot

  62. Hi, thanks first of all for this amazing tutorial.

    I am trying to develop a secure account authenticator which stores the users password, but i am having the following troubles.

    If two applications installing an account authenticator for the same account type, only the account authenticator of the first app is installed.
    However, if the first app is uninstalled, the account authenticator of the 2nd app takes its place. (I just tried that and even if the signature of 2nd app is different, calls like ‘AccountManager.getPassword’ which would usually crash as the UID is different, are working)

    How can i prevent that – given my app is uninstalled – no other already installed malicious app can take over my account and potentially read out my users credentials?

    • They can’t take over your account.

      They may be able to create an authenticator with the same look and feel and same account type, but it won’t be signed with the same signature as your app, so they won’t have access to the important stuff.

      • Feel free to try it:
        1) Install an app that creates an account, like whatsapp. Create an account.
        2) Write an app that installs an authenticator for the same account type as whatsapp and tries to access UID-protected methods like AccountManager#getPassword() -> your app will crash
        3) Uninstall the original app

        After 3) the account created in 1) is still around, but now your application can access that account, e.g. execute getPassword() without crashing. It seems that the ownership of the account-type was automatically transferred to your app installed in 2)

        Whatsapp does not store any password in the account, but I am sure there are plenty other apps that do.

  63. Pingback: Android Account Management – How to create different types of accounts? | 我爱源码网

  64. Pingback: how to make multiple Account And where Account Data Stored in Database? how? | 我爱源码网

  65. HI Udinic!
    Thank`s for you posts!
    Please tell me I am, in my situation:
    I start activity for sending message (ActivitySending), but before do it, i test if User has AuthToken.
    I do it with call method “getTokenForAccountCreateIfNeeded”.
    And that is great!::
    – if User has AuthToken, in “public void run(AccountManagerFuture future)” I get AuthToken and send User`s message to server
    – if User has not Account (so no AuthToken) will show AuthenticatorActivity for authenticating. And when user has made the authentication and get AuthToken, On idea, to be executed Method “public void run(AccountManagerFuture future)” and sending message. BUT in AuthenticatorActivity, when user authentication ended , is call method “finishLogin(Intent intent)”, that contains the “finish()”.
    And, So, after authentication, AuthenticatorActivity is close and for some reason close ActivitySending without sending the message!
    Please, tell me how can I avoid closing the parent ActivitySending and avoid interruption send a message.

  66. Thanks this was definitely helpful, however it still barely scratches the surface. I really wish the documentation had more info about using the confirmCredentials, updateCredentials, etc.

  67. Hi, awesome tutorial.
    One question. I tried the mAccountManager.invalidateAuthToken() method and was expecting that it removes the token from the manager. After executing this, I executed getAUthToken expecting that there is no returned authToken or at laest a different (newly generated) one. Am I incorrectly understanding the function of invalidateAuthToken?

    Background: I tried to integrate this into my app which has multiple users. My logout method calls invaliadteAuthToken but nothing happened. Ideally I want to invalidate the current token and return to the login activity so that another user can login. How would that be possible?

    Thanks a lot

    • It depends how you implemented the getAuthToken method. In my implementation, I save the user/password internally and if there’s no valid token – I authenticate using these credentials. This means, that unless the password has changed, you won’t be prompted to enter your credentials again.

      The value of the token itself depends on the server. Sometimes, the same token will be returned by the server, given the same credentials. The invalidation in the account manager will only invalidate the use of the current token in the account manager. It won’t invalidate it on the server.

      • Thanks for the quick reply.

        I studied the different getAuthToken() methods and most of them would indeed use the saved password to request the token again from the server.

        In your example I deleted the places where you store the password (i.e. wherever you add the “PARAM_USER_PASS, userPass” to a bundle) expecting the app to prompt for a new login. But it did not happen.

        Even without taking out those lines I would have thought that the app would run through the userSignIn() method in the ComServer class using the stored password to request a new token since the getAuthToken() api says:

        “If a previously generated auth token is cached for this account and type, then it is returned. Otherwise, if a saved password is available, it is sent to the server to generate a new auth token. ”

        What am I not getting here?
        Thanks again for you help!

  68. If I remember correctly, it’s not automatic. Either you need to start the authentication activity by yourself or need to call a method to do that for you. Not sure which one will do the trick though..

    If you find a solution for this – please post here for us to learn.

  69. Pingback: Download aplikasi Authenticator Sample App gratis untuk android

  70. Pingback: (翻译) Android Accounts Api使用指南 - 有Bug

  71. Hi, thanks for the great tutorial.
    I’m developing an app which has one token type and one account type.
    Can you tell me what is the right way to make sure that there is only one account connected to the app anytime.

    Thanks a lot

  72. Thanks for the great tutorial!
    There is a recommended way to add the option to skip the authentication.
    I mean that the user can log in and will get all the features.
    But if he decides not to, he will be able to use the app in restricted areas.

Leave a reply to udinic Cancel reply