1

I'm implementing an login quiet similar to the login of the Google Photo App. I'm not testing my App in Android Marshmallow. That requires the permission:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

Quiet clear no questions until here. But how does the app can read out my accounts without requesting nor granting the permission in the app settings?

When I try to use:

Account[] googleAccounts = AccountManager.get(context).getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);

I just get an empty array. What am I doing wrong?

rekire
  • 47,260
  • 30
  • 167
  • 264
  • please check this answer, http://stackoverflow.com/q/32601456/2826147 – Dhaval Parmar Oct 23 '15 at 12:37
  • 1
    @DhawalSodhaParmar how is that related? – rekire Oct 23 '15 at 12:39
  • Um, Photos has `GET_ACCOUNTS`, at least on the versions I have on Android 5.1 and 6.0 devices. What evidence do you have that Photos is doing something "without requesting nor granting the permission in the app settings?" – CommonsWare Oct 23 '15 at 12:40
  • Hey @CommonsWare, I didn't grant the photos app the accounts permissions, but the app can list my account(s) on marshmallow. I try to do the same, but I get no information anymore. A distinct call also yells that I do not own the `GET_ACCOUNTS` permissions. So I guess this is somehow related. – rekire Oct 23 '15 at 12:43
  • "I didn't grant the photos app the accounts permissions" -- you didn't grant it any permissions AFAIK, since the app was pre-installed (or derived from a pre-installed app). If you look in the app's entry in Settings, and you look at its permissions, you will see that it can "find accounts on the device", which AFAIK is the description of `GET_ACCOUNTS`. – CommonsWare Oct 23 '15 at 12:48
  • Check [this screenshot](http://i.stack.imgur.com/vf3Z3.png), that permission is disabled. Did I miss something? – rekire Oct 23 '15 at 12:54
  • I think "contacts" is not the same thing as "accounts". Contacts is the permission to view your contacts, and accounts is the permission to view the account(s) you have signed in with on the device. – nasch Oct 24 '15 at 00:52
  • @nasch when I grant this permission my code works again. So this is somehow related. – rekire Oct 24 '15 at 06:03
  • I don't know quite what you mean. When you grant your app the Contacts permission, you can read accounts? That has nothing to do with the screenshot you posted, right? – nasch Oct 24 '15 at 13:44
  • When I turn on the "contacts" switch for my app, I can read the google accounts with the code from the question. I'm now confused why the Photos app can know my accounts when I disable that permission as in the screenshot. So I guess they use another trick which I missed. – rekire Oct 24 '15 at 14:35
  • Where is this contacts switch, and what exactly does it do? I checked in system app settings on KitKat and Lollipop and didn't see any switches, so it looks like it would be something within your app. I'm thinking either it works differently than the one in the Photos app, or the Photos app has special privileges as a preinstalled app. – nasch Oct 26 '15 at 15:33
  • @nasch this was introduced in Android Marshmallow and it part of the new permission model and so part of the system. – rekire Oct 26 '15 at 15:36
  • Ah, that explains it, I don't have a Marshmallow device (and haven't set up an emulator with it either, something I should probably check out). Thanks. – nasch Oct 26 '15 at 15:37
  • Yeah that is important that may break several things if you are targeting API 23. – rekire Oct 26 '15 at 15:37

1 Answers1

1

The past week I've coded a server-side access with Google login (https://developers.google.com/identity/sign-in/android/offline-access), and you don't need GET_ACCOUNTS for it.

What happens is that the application requests Google Play Services for a token that you will send to your server. And that's all. Google Play Service will access accounts, popup UI for the user to agree/confirm, etc.

So, I'm assuming that's what Google Photos use. Another alternative valid answer is that they're a system app developed and signed by the creators of the OS and they can't do whatever they want by simply accessing protected APIs.

Budius
  • 39,391
  • 16
  • 102
  • 144
  • Interesting API and properly very helpful, but I still need to know how do you get the token you need to send to the backend? I mean when you have multiple google accounts on your device how do you select one? – rekire Oct 24 '15 at 14:40
  • If you `clone-compile` their sample app you'll see what happens. https://github.com/googlesamples/google-server-auth-android In the method `resolveSignInError` they `startResolutionForResult` which internally is calling `startActivityForResult`. The started activity is an internal from GooglePlayService. This activity asks the user which account to use and if he/she authorizes the access. – Budius Oct 26 '15 at 10:13
  • Now you are pointing it out yourself. This requires a user interaction. I want to avoid that. However this is still quiet helpful. – rekire Oct 26 '15 at 10:19
  • Oh yes. That method is certainly with user permission, just not using the marshmallow permission directly. So it's likely that it's the second suggestion from my answer. They're Google and their app can do private communications with GooglePlayServices. – Budius Oct 26 '15 at 10:52