Question

I have 2 separated Android projects, one is the implementation of the AbstractAccountAuthenticator to manage user accounts in the device and the other is a push application that should get a token from the AccountAuthenticator and use it.

The implementation of AbstractAccountAuthenticator is working and adds accounts when it's called from "Accounts and Sync" section in the "Settings" menu, but when I call addAccount() from the push app I get a "Permission denied: checkComponentPermission()" and the app dies there.

I can't provide much of the source code, since it's not in my power to allow it to go public, but I assure you that they work in a "stand-alone" way.

I've searched for examples of the correct use of AccountManager from different applications but none has been found. No luck on freenode either.

I've found that starting the activity from within the AccountAuthenticator (using Intent.FLAG_NEW_TASK and context.startActivity( intent ) ) does the trick, but that implies that addAccount() doesn't return to the AccountManager, which I think doesn't align with the developing guidelines since it breaks the flow in the usage of AccountManager. The other way is to export the Acitivity that is used when asking for user credentials. But I think that this could be a security issue, since it should be called by the AccountManager and not externally.

Thank you for any ideas you may have about this.

PS:

  • All permissions are correctly used, unless I need a special one that I'm not aware to work across apps.

  • I'll ask if I can use fragments of code to show here the lines I'm concerned about.

  • First question posted here, I hope I'm not breaking (m)any rules here (I did my search here and on google, but I asked since I found nothing of use.)

  • Thank you.


After diving deep into Google's Login Service and stumbling upon Settings class, Ive found what I think should be the solution:

  • Do not export stuff, I keep thinking it's a security issue to call something of your implementation, be a service or an activity, bypassing AccountManager.

  • Do not use Intent.FLAG_NEW_TASK and startActivity() on your implementation of the AbstractAccountAuthenticator, since it can take you to unexpected behavior.

The way to do this is quite simple, actually:

Intent i = new Intent( Settings.ACTION_ADD_ACCOUNT );
i.putExtra( Settings.EXTRA_AUTHORITIES, new String[] { "com.exaple.yourauth" } );
contextVar.startActivity( i );

This way, you are asking Settings to raise the list of possible authorities for a new account, bus since you're adding the EXTRA_AUTHORITIES param, a string with the authorities to display, it limits the options to what you want. In the case that only one matches your extra, the account manager and login activities are invoked in a proper way.

I really hope this helps any other person around.

Was it helpful?

Solution

After diving deep into Google's Login Service and stumbling upon Settings class, Ive found what I think should be the solution:

  • Do not export stuff, I keep thinking it's a security issue to call something of your implementation, be a service or an activity, bypassing AccountManager.

  • Do not use Intent.FLAG_NEW_TASK and startActivity() on your implementation of the AbstractAccountAuthenticator, since it can take you to unexpected behavior.

The way to do this is quite simple, actually:

Intent i = new Intent( Settings.ACTION_ADD_ACCOUNT );
i.putExtra( Settings.EXTRA_AUTHORITIES, new String[] { "com.exaple.yourauth" } );
contextVar.startActivity( i );

This way, you are asking Settings to raise the list of possible authorities for a new account, bus since you're adding the EXTRA_AUTHORITIES param, a string with the authorities to display, it limits the options to what you want. In the case that only one matches your extra, the account manager and login activities are invoked in a proper way.

I really hope this helps any other person around.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top