How to get Google Play Services currently connected account? - android

Many Google Applications allow you to switch between Google Accounts and show you the currently connected account.
For example Google Fit, Gmail, Google+, etc...
From the perspective of the code I call .connect() on the Google Client and enter a loop of
connection failed
launch automatic resolution
get activity result
retry connect
until I finally connect.
This is documented in many places, here for example: https://developers.google.com/android/guides/api-client
On the UX side what happens is that the user is presented with multiple dialogs asking every time something different.
One of the dialog ask to chose an Account between the ones available on the phone (it probably automatically resolve without user interaction if there's only one account configured).
How do you query the Google Client to know which account is currently connected?
I found no documentation about it anywhere.
The closest thing I found is this:
https://developers.google.com/android/reference/com/google/android/gms/common/AccountPicker
but I do not create the picker, it's something completely handled by the Play Services in the procedure I described above.

You have to request the Account resource with Google Plus API.
Add the following permission in the manifest:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Then use this API to get the account that is logged in currently.
EDIT (addressing the comment):
In .builder add login scope as shown in the example and initiate the G+ Api as well. Since you do not need social scopes, this scope will give you access to currently authenticated user's information.
Once you setAccountName through the builder, you can access the Account resource for this user which you can get at anytime through getAccountName.
EDIT 2:
So apologies for not addressing the G+ context with last edit.
Here's a class in simple Google Sign In (Identity platform) which give you access to account resource.
More information in the official documentation.

Related

Access to Google Fit Activity Data

This is a Google Fit app screenshot.
My app don't work for some user if they don't activate this in Google fit app.
Is someone knows how to activate it directly in your app ?
Try checking the Google Fit samples on GitHub on how they are authorizing their app.
Based on the documentation - Authorization on Android:
The authorization flow is the following:
Your app requests a connection, with one or more scopes of access, to the fitness service.
Google Fit prompts the user to grant your app the required permissions.
If the user consents, your app can access fitness data of the types defined by the scope.
I think you should implement your error catch when your user didn't activate this in Google fit app like (Activate Required).
Hope this helps.

Avoiding Google Drive Java REST API prompting for user account everytime on devices with multiple accounts

I have a working solution where I search for files in Google Drive and ask for Google Drive to open them using the getWebViewLink, this generates a link like this:
https://drive.google.com/file/d/0B6cgfp1Py-7SAF&SAFgASFGZGlQWEU/view?usp=drivesdk
Then I parse the link and generate an intent like this:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
startActivity(intent);
This works great on devices configured with one gmail account, but if the device happens to have 2 or more gmail accounts configured then Google Drive keeps always asking which account the user wants to use to open the file.
Is there anyway to suggest in the link which account to use to Google Drive?
P.S: I tried adding the following to the link to no avail
&approval_prompt=auto
or
&user_id=myemail#gmail.com
You may refer with this related thread. It stated that the redirect loop happens to users that have both a Gmail account and a Google Apps account. There are only one set of active Docs cookies at any given time. The workarounds are to either log out of the account that you are not currently trying to use for Docs access or use different browsers for each account.
Here's another reference which might help: How can I enforce GoogleApiClient to prompt account chooser UI each time I call connect?
...you must manage the account selection yourself as you can see here (for REST) or here (for GDAA)
Hope this helps!

Google won't sign in when Scope is added on Google Fit API

I'm trying to add scopes on my API client. However when I add any scopes, it won't let me sign in. However if I remove the scopes, I'll be able to sign in. Can anyone help me figure this out?
I'm using Fitness API.
When it's just .addApi(Fitness.API_HISTORY) it works. But when I try to add a scope, it won't go past the login/auth screen.
Thank you!
Edit: I tried two approaches
1) I left the authentication to fitness api using startResolutionForResult during which logcat reads the error as
SIGN_IN_REQUIRED (To which the accounts pop up, however after selecting nothing happens).
2) When I created a custom sign in flow through different intent and set the account in this api client it gives me error SIGN_IN_FAILED.
In both the cases when i remove scopes it works.
You can check this example. It stated that you need to have a GoogleApiClient that will authenticate the user and allow the application to connect to Fitness APIs. The scopes included should match the scopes your app needs. Authentication will occasionally fail intentionally, and in those cases, there will be a known resolution, which the OnConnectionFailedListener() can address.
You can also see here a sample code that creates a client that should ask Fitness.API for read permissions and add permissions for reading (SCOPE_LOCATION_READ) and writing (SCOPE_BODY_READ_WRITE).

In-app purchases with multiple accounts

I am facing a problem with in app purchases/subscriptions:
If there are multiple accounts on the device, I can't get the purchases, which were made with the second account.
This can sometimes be temporarily fixed, by installing the app from the Google Play web interface, but after a while, the purchases won't appear in the query, forcing the user to reinstall.
I am using the IabHelper classes from this sample.
Doing some Google searches, I found that this bug exists since a while, but unfortunately I couldn't find out if the error is in the IabHelper classes or on Google's side.
I'd like to draw attention to Google, so they provide a proper fix for this, either in the IabHelper classes or in the Play Services or to provide information, how this should be handled.
I am using the code in an app with (at the time of writing) 900.000 active user installs and I have to trigger quite a lot of refunds, due to this.
If there is a fix for this, which I missed, please let me know.
Edit:
Sometimes it's not possible at all to retrieve the purchases, even if there is only one account on the phone.
It seems like there isn't a one way road to solve this, but let's try do this.
When the user first install the app get his/her primary email or all accounts on the device
Ask the user what email will they be using for future payment/ or which account is active for google play.
you can use this code to get the account
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(context).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
...
}
}
Don't forget to ask for permission
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
After the user selects the email, you can send a link via email to confirm this email address
Lead all the payment to that specific email.
Method 2
Use the new "Send & Receive money using Gmail" future
Create a email intent and send specific data to the email intent and make payments.
Upon success, send a code to the user email
Use the code to activate whatever purchased they make.
Method 3
Use another payment library or gateway for your in app purchase instead of Google play.
As others have noted, this is a bug with the Google Play Billing Library. If it affects you, star this issue on https://issuetracker.google.com/issues/139597485 so Google can notice it (really?) and start working on a fix.
It is sure a bug in the in-app billing service apis. This is a similar question and as mentioned in one of the answers, may be you need to introduce login mechanism and store the purchases made from an account to your server or locally on the device in an encrypted file or something similar.
I had ran into same problem couple of months later.
After hours of finding solutions and all i came up with a work around something like this,
You can use OAuth 2.0.
But you also have to manage it from your backend.
I am not a backend developer so i didnt know how exactly it does in backend but at app side i have done something like this,
You can use the first Google account allowing authentication on your serve side. OAuth 2.0 is a tool that simplifies and get developers an easy way to allow users to access your application. The OAuthHmacSigner class does manages the authentication.
signer = new OAuthHmacSigner();
signer.clientSharedSecret = Constants.CONSUMER_SECRET;
Then the Android activity uses the following code to launch the OAuth flow :
launchOauth.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent().setClass(v.getContext(),
PrepareRequestTokenActivity.class));
}
});
In order to get an OAuth 2.0 access token, you simply need to call:
AccountManager.getAuthToken()
I Hope this might help :)
I have two accounts, but one does not work. What I did is I went into android's settings, and then went into account preferences. I changed my main account from the one that does not work to the working one. Then I assigned the new account to be the main one for all of my applications, including google play. That worked for me. Sometimes, if it does not work for some reason, you can also go online and access the Google Play store from the internet.
Try to get dup...duplicate dot with file signature ending in .apk or .xcode
I'm not sure if this is the answer you're searching for, but perhaps setting up a shared Google Play Family Library would suffice. It works for up to 5 users sharing the same purchases (app, music, movies, etc), if desired.
(See: https://support.google.com/googleplay/answer/7007852?hl=en)

Google Play Services - Clear allowed accounts

When using the new Google Play Services to authenticate an account, you first use the AccountPicker to allow the user to select an account. If the user has not authenticated with your application before, a UserRecoverableAuthException will be thrown which gives you an intent to show the 'Allow Access' page. You only need to allow access one time. However, for testing purposes, I need to be see the Allow Access page every time.
So, does any know how you can clear the permissions for Google Play Services? Or some other method that will show the allow access page every time?
In your Google Account Settings, there's a way to set up application-specific passwords. Sign up for 2-step verification and then you can create them. To temporarily revoke the permission, you can remove or change the password: http://support.google.com/accounts/bin/answer.py?hl=en&answer=1070455
Otherwise, change the password to your entire Google account temporarily.
Unfortunately I don't think there's an easy programmatic way to do this. It seems like quite a serious security flaw that a user/administrator can't revoke Google Account access to an installed app. From what I can tell, Google is fetching the authentication information from a server, and if something in that operation fails, it throws the UserRecoverableAuthException. That's when you normally fire off the Intent from UserException.getIntent(), which contacts the server with a request such as:
scope:oauth2:https://www.googleapis.com/auth/drive.readonly[
account:<your_account>#gmail.com,
scope:oauth2:https://www.googleapis.com/auth/drive.readonly,
extrashash:<some_number>]
Now there's no documentation I've found for instructing the server to revoke that Auth Scope requested above. It might not even be possible. However, you could try to capture the values in the Intent returned by UserException.getIntent() and use it to create a new Intent you launch whenever the user wishes to sign in with their Google account. However, the server might realize the app is already authenticated, and then send you through without the prompt.

Categories

Resources