I don't know it is the correct question or not.How can we get the lo-gin id of the user from which it has been lo-gin to the Google Play Store in Android.Is this possible or not.
As per my knowledge the user has to configure his gmail account in his android phone and then he gets access to Google Play.
You can fetch the account information as given below (from Jim Blackler):
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
/**
* This class uses the AccountManager to get the primary email address of the
* current user.
*/
public class UserEmailFetcher {
static String getEmail(Context context) {
AccountManager accountManager = AccountManager.get(context);
Account account = getAccount(accountManager);
if (account == null) {
return null;
} else {
return account.name;
}
}
private static Account getAccount(AccountManager accountManager) {
Account[] accounts = accountManager.getAccountsByType("com.google");
Account account;
if (accounts.length > 0) {
account = accounts[0];
} else {
account = null;
}
return account;
}
}
In Manifest
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
If you're after a method that doesn't require requesting a permission via AndroidManifest.xml you can use Google Play Services' AccountPicker.
Spawn a dialog that allows the user to pick their desired Google Account:
Intent intent = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null, null, null, null);
startActivityForResult(intent, SOME_REQUEST_CODE);
then handle the result in your Activity:
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
if (requestCode == SOME_REQUEST_CODE && resultCode == RESULT_OK) {
String emailAddress = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
// do something...
}
}
Remember to add compile 'com.google.android.gms:play-services-identity:8.+' to the dependencies in your build.gradle file (check here for the most recent version number to use).
Related
With the following code that retrieves the user's Google account, gmail, I was wondering why I get null from devices like mine (that of course runs on my gmail), whereas it works on my mom's devices:
public class MainActivity extends AppCompatActivity {
final String TAG = "Sample2";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String test = getEmail(getApplicationContext());
Log.d(TAG, "Email is: " + test);
TextView emailTxt = (TextView)findViewById(R.id.emailTxt);
emailTxt.setText(test);
}
private String getEmail(Context context) {
AccountManager accountManager = AccountManager.get(context);
Account account = getAccount(accountManager);
if (account == null) {
return null;
} else {
return account.name;
}
}
private static Account getAccount(AccountManager accountManager) {
Account[] accounts = accountManager.getAccountsByType("com.google");
Account account;
if (accounts.length > 0) {
account = accounts[0];
} else {
account = null;
}
return account;
}
}
I also included the following permission into my Manifest file:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Clearly, it's because of my device... But it can't be the only device that's returning null, so I don't know if this is a good approach for a unique string token when verifying payload with in-app billing.
Oh, and here's a screenshot of what I see in my Accounts & Sync settings:
... Is there anything I'm missing here?
Based on the document Set the developer payload string. When making purchase requests, you should not use the user's email address in the payload string, since the address may change.
You should pass in a string token that helps your application to identify the user who made the purchase, so that you can later verify that this is a legitimate purchase by that user. For consumable items, you can use a randomly generated string, but for non- consumable items you should use a string that uniquely identifies the user.
https://developer.android.com/about/versions/oreo/android-8.0-changes.html
Account access and discoverability
In Android 8.0 (API level 26), apps can no longer get access to user accounts unless the authenticator owns the accounts or the user grants that access. The GET_ACCOUNTS permission is no longer sufficient. To be granted access to an account, apps should either use AccountManager.newChooseAccountIntent() or an authenticator-specific method. After getting access to accounts, an app can can call AccountManager.getAccounts() to access them.
Android 8.0 deprecates LOGIN_ACCOUNTS_CHANGED_ACTION. Apps should instead use addOnAccountsUpdatedListener() to get updates about accounts during runtime.
For information about new APIs and methods added for account access and discoverability, see Account Access and Discoverability in the New APIs section of this document
Maybe you can try this
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int PICK_ACCOUNT_REQUEST = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent googlePicker = AccountManager.newChooseAccountIntent(null, null,
new String[] { "com.google"}, true, null, null, null, null);
startActivityForResult(googlePicker, PICK_ACCOUNT_REQUEST);
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
if (requestCode == PICK_ACCOUNT_REQUEST && resultCode == RESULT_OK) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
Log.d(TAG, "Account Name=" + accountName);
String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
Log.d(TAG, "Account type=" + accountType);
AccountManager accountManager = AccountManager.get(this);
Account[] accounts = accountManager.getAccounts();
for (Account a :
accounts) {
Log.d(TAG, "type--- " + a.type + " ---- name---- " + a.name);
}
}
}
}
I have read this whole article for the authentication using OAuth2.0.
But I didn't find a suitable method to do this on an android application. Please suggest a method to get the access token so that I can build a Gmail service object and access the inbox or any other method.
This is the example given by them in this link:
GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
Plus plus = new Plus.builder(new NetHttpTransport(), JacksonFactory.getDefaultInstance(), credential)
.setApplicationName("Google-PlusSample/1.0")
.build();
Invoke the below method to get the token and the google account used in mobile. This method first retrieves the google account setup in your mobile and later retrieves the token.
You can save the token and account name using preferences for later use so that you dont have to retrieve the token each time.
private void chooseAccount() {
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
new String[]{"com.google"}, false, null, null, null, null);
startActivityForResult(intent, 9009);
}
After the account is retrieved the below method is called,
public static final String MAIL_GOOGLE_COM = "https://mail.google.com";
public static final String GMAIL_COMPOSE = "https://www.googleapis.com/auth/gmail.compose";
public static final String GMAIL_MODIFY = "https://www.googleapis.com/auth/gmail.modify";
private static final String SCOPE = "oauth2:" + GMAIL_COMPOSE + " " + GMAIL_MODIFY + " " + MAIL_GOOGLE_COM;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
//accountname - google account in your mobile is retrieved
//now use the google account to retrieve the token
new GetToken(getActivity().getApplicationContext(), SCOPE, accountName).execute();
showErrorDialog(exception);
}
} else if (requestCode == Activity.RESULT_CANCELED) {
Toast.makeText(getActivity(), "Cancelled!!!", Toast.LENGTH_SHORT).show();
}
}
Below class is used to get the token.
private class GetToken extends AsyncTask<Void, Void, Void> {
Context context;
String mScope, mEmail, token;
GetToken(Context context, String scope, String email) {
this.context = context;
this.mScope = scope;
this.mEmail = email;
}
#Override
protected Void doInBackground(Void... params) {
try {
token = GoogleAuthUtil.getToken(context, mEmail, mScope);
//save the token using preference for later use or do any good stuff using token here
Log.v("ranjapp", "Token is " + token);
} catch (UserRecoverableAuthException e) {
handleException(e);
} catch (GoogleAuthException ex) {
handleException(ex);
} catch (Exception e) {
//display a error dialog
}
return null;
}
void handleException(final Exception e) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (e instanceof UserRecoverableAuthException) {
Intent intent = ((UserRecoverableAuthException) e).getIntent();
startActivityForResult(intent, 10098);
} else if (e instanceof GooglePlayServicesAvailabilityException) {
int statusCode = ((GooglePlayServicesAvailabilityException) e)
.getConnectionStatusCode();
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(statusCode, getActivity(), 10099);
dialog.show();
}
}
});
}
}
You have to register your app in google play console to get the token successfully. Also ensure you have play services setup in your app.
To register your Android app with Google Cloud Console:
Visit Google Cloud Console.
If you have an existing project to which you're adding an Android app, select the project. Otherwise, click Create project at the top, enter your project name and ID, then click Create.
Note: The name you provide for the project is the name that appears to users in the Google Settings app in the list of Connected apps.
In the left-side navigation, select APIs & auth.
Enable the API you'd like to use by setting the Status to ON.
In the left-side navigation, select Credentials.
Click Create new client ID or Create new key as appropriate for your app.
Complete the form that appears by filling in your Android app details.
To get the SHA1 fingerprint for your app, run the following command in a terminal:
keytool -exportcert -alias <keystore_alias> -keystore <keystore_path> -list -v
For example, you're using a debug-key with Eclipse, then the command looks like this:
keytool -exportcert -alias androiddebugkey-keystore ~/.android/debug.keystore -list -v
Then the keystore password is "android".
Click Create.
For more information: https://developer.android.com/google/auth/http-auth.html
This library might make it easier for you:
https://github.com/Hafiz-Waleed-Hussain/EasySocial
Additionally you can check the source for the actual implementation.
I develop an app with in app version 2 and publish it on developers Google now some one download the app and try to purchase it. On purchasing a message showed to him that "Your card is decline" now even after this message app got "unlock" . Now this is a very difficult situation that payment is not made while app got unlock. Is this issue with in app billing method(logic) in my app or its with Google.
If its in my app then is there any method which check that the person card is a "declined card" so in this method i can restrict my app not to unlock the app.
Any app will be appreciated.
I have this code in my BillingReceviver:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Consts.ACTION_PURCHASE_STATE_CHANGED.equals(action)) {
String signedData = intent.getStringExtra(Consts.INAPP_SIGNED_DATA);
String signature = intent.getStringExtra(Consts.INAPP_SIGNATURE);
purchaseStateChanged(context, signedData, signature);
} else if (Consts.ACTION_NOTIFY.equals(action)) {
String notifyId = intent.getStringExtra(Consts.NOTIFICATION_ID);
if (Consts.DEBUG) {
Log.i(TAG, "notifyId: " + notifyId);
}
notify(context, notifyId);
} else if (Consts.ACTION_RESPONSE_CODE.equals(action)) {
long requestId = intent.getLongExtra(Consts.INAPP_REQUEST_ID, -1);
int responseCodeIndex = intent.getIntExtra(Consts.INAPP_RESPONSE_CODE,
ResponseCode.RESULT_ERROR.ordinal());
checkResponseCode(context, requestId, responseCodeIndex);
} else {
Log.w(TAG, "unexpected action: " + action);
}
}
After making ACTION_PURCHASE_STATE_CHANGED matches the action the my purchsedstatechanged calls in file BillingService
private void purchaseStateChanged(int startId, String signedData, String signature) {
ArrayList<Security.VerifiedPurchase> purchases;
DatabaseHandler db=new DatabaseHandler(this);
purchases = Security.verifyPurchase(signedData, signature);
if (purchases == null) {
return;
}
ArrayList<String> notifyList = new ArrayList<String>();
for (VerifiedPurchase vp : purchases) {
if (vp.notificationId != null) {
notifyList.add(vp.notificationId);
}
ResponseHandler.purchaseResponse(this, vp.purchaseState, vp.productId,
vp.orderId, vp.purchaseTime, vp.developerPayload);
db.addUser("com.example.app", "111", "1222");
Log.i("Usgdgfer",""+db.isUserPresent("com.example.app"));
}
if (!notifyList.isEmpty()) {
String[] notifyIds = notifyList.toArray(new String[notifyList.size()]);
confirmNotifications(startId, notifyIds);
}
}
Usually, the card has to be mapped to the Google Wallet account before the purchase is made. If the card is invalid, it will show an error while you map the card to your Google account.
Seems strange that the card is being validated during purchase. Even then, if the payment is not made properly , you should get an error response
BILLING_RESPONSE_RESULT_USER_CANCELED = 1;
BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE = 3;
Check if you handle these errors properly after you receive them in the IabResult. Make sure you unlock your app only when you receive a proper response.
This question discusses it for android devices in general, but if you try to run this code on a Kindle Fire, all you get is the user's name. Is there any way to get the email address? We were hoping to pop-up a dialog with the email address already pre-filled so they wouldn't have to type it if it were correct, but it seems like the only solution is to have them re-type it.
edit: Here's the code that other threads have suggested (that doesn't work on the Kindle Fire):
Account[] accounts = AccountManager.get(this).getAccounts();
for (Account account : accounts) {
// TODO: Check possibleEmail against an email regex or treat
// account.name as an email address only for certain account.type values.
String possibleEmail = account.name;
// possibleEmail is a list of account names, hopefully including the #gmail.com address.
}
On the Kindle Fire, is it possible to get a user's email address?
Sorry, But You totally wrong.
I used to link to Google Login Dialog which show all user existed on Kindle Fire.
Please follow this code :
public class AuthAcount {
private Context context;
private AccountManager mAccountManager;
public AuthAcount(Context context) {
setContext(context);
}
public Account[] getAccount() {
mAccountManager = AccountManager.get(context);
Account[] accounts = mAccountManager
.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
return accounts;
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
}
P/s : To use GoogleAuthUtil class, might be you need google-oauth-client-1.15.0-rc.jar (Please use the lastest version).
On the Fire devices that I have available to me, this is what I did:
final static String TYPE_GOOGLE = "com.google";
final static String TYPE_AMAZON = "com.amazon";
final static String AMAZON_EMAIL = "com.amazon.pim";
public static String getAccountName(final Context context) {
boolean amazon = TextUtils.equals(Build.MANUFACTURER, "Amazon");
String type = amazon ? TYPE_AMAZON : TYPE_GOOGLE;
String email = null;
try {
Account acc[] = AccountManager.get(context).getAccountsByType(type);
if (acc.length > 0) {
email = acc[0].name;
for (int i = 0; i < acc.length; i++) {
Account account = acc[i];
if (amazon) {
// there are a lot of flags, just skip them
if (!TextUtils.equals(account.type, TYPE_AMAZON)) {
// is it an email account?
if (account.type.startsWith(AMAZON_EMAIL)) {
email = account.name;
}
}
}
}
} else {
acc = AccountManager.get(context).getAccounts();
if (acc.length > 0) {
// just return the first one...
email = acc[0].name;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return email;
}
This will also work with Google Play devices.
I'm trying to figure out how to use Google Api for accessing/editing Google SpreadSheet.
I want to have a connection always with the same spreadsheet from many devices. I got examples using the AccountManager, but i should not use the user account. There is any good turorial?
Right now i've got the following..is that right?
AccountManager accountManager = AccountManager.get(this);
ArrayList googleAccounts = new ArrayList();
// Just for the example, I am using the first google account returned.
Account account = new Account("email#gmail.com", "com.google");
// "wise" = Google Spreadheets
AccountManagerFuture<Bundle> amf = accountManager.getAuthToken(account, "wise", null, this, null, null);
try {
Bundle authTokenBundle = amf.getResult();
String authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN);
// do something with the token
//InputStream response = sgc.getFeedAsStream(feedUrl, authToken, null, "2.1");
}
catch (Exception e) {
// TODO: handle exception
}
Required permissions:
<uses-permission android:name="android.permission.ACCOUNT_MANAGER"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
Choose needed outh token type from the table:
http://code.google.com/intl/ja/apis/spreadsheets/faq_gdata.html#Authentication
Spreadsheets Data API wise
Code sample:
public class OuthTokenActivity extends Activity {
String tag = "DEBUG";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AccountManager mAccountManager = AccountManager.get(this);
for (Account account : mAccountManager.getAccountsByType("com.google")) {
mAccountManager.getAuthToken(account, "wise", savedInstanceState,
this, resultCallback, null);
}
}
AccountManagerCallback<Bundle> resultCallback = new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle result = future.getResult();
String token = (String) result.get(AccountManager.KEY_AUTHTOKEN);
String name = (String) result.get(AccountManager.KEY_ACCOUNT_NAME);
Log.d(tag, String.format("name: %s, token: %s", name, token));
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
There is an API released now, available for java script, which could be run in your app. And they show how to integrate this into an Android app in a video here.