How do you get the Android's primary e-mail address (or a list of e-mail addresses)?
It's my understanding that on OS 2.0+ there's support for multiple e-mail addresses, but below 2.0 you can only have one e-mail address per device.
How do you get the Android's primary e-mail address (or a list of e-mail addresses)?
It's my understanding that on OS 2.0+ there's support for multiple e-mail addresses, but below 2.0 you can only have one e-mail address per device.
There are several ways to do this, shown below.
As a friendly warning, be careful and up-front to the user when dealing with account, profile, and contact data. If you misuse a user's email address or other personal information, bad things can happen.
You can use AccountManager.getAccounts or AccountManager.getAccountsByType to get a list of all account names on the device. Fortunately, for certain account types (including com.google), the account names are email addresses. Example snippet below.
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;
...
}
}
Note that this requires the GET_ACCOUNTS permission:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
More on using AccountManager can be found at the Contact Manager sample code in the SDK.
As of Android 4.0 (Ice Cream Sandwich), you can get the user's email addresses by accessing their profile. Accessing the user profile is a bit heavyweight as it requires two permissions (more on that below), but email addresses are fairly sensitive pieces of data, so this is the price of admission.
Below is a full example that uses a CursorLoader to retrieve profile data rows containing email addresses.
public class ExampleActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arguments) {
return new CursorLoader(this,
// Retrieve data rows for the device user's 'profile' contact.
Uri.withAppendedPath(
ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY),
ProfileQuery.PROJECTION,
// Select only email addresses.
ContactsContract.Contacts.Data.MIMETYPE + " = ?",
new String[]{ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE},
// Show primary email addresses first. Note that there won't be
// a primary email address if the user hasn't specified one.
ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
}
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
List<String> emails = new ArrayList<String>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
emails.add(cursor.getString(ProfileQuery.ADDRESS));
// Potentially filter on ProfileQuery.IS_PRIMARY
cursor.moveToNext();
}
...
}
@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
}
private interface ProfileQuery {
String[] PROJECTION = {
ContactsContract.CommonDataKinds.Email.ADDRESS,
ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
};
int ADDRESS = 0;
int IS_PRIMARY = 1;
}
}
This requires both the READ_PROFILE and READ_CONTACTS permissions:
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
There is an Android api that allows the user to select their email address without the need for a permission. Take a look at: https://developers.google.com/identity/smartlock-passwords/android/retrieve-hints
HintRequest hintRequest = new HintRequest.Builder()
.setHintPickerConfig(new CredentialPickerConfig.Builder()
.setShowCancelButton(true)
.build())
.setEmailAddressIdentifierSupported(true)
.setAccountTypes(IdentityProviders.GOOGLE)
.build();
PendingIntent intent = mCredentialsClient.getHintPickerIntent(hintRequest);
try {
startIntentSenderForResult(intent.getIntentSender(), RC_HINT, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Could not start hint picker Intent", e);
}
This will show a picker where the user can select an emailaddress. The result will be delivered in onActivityResult()
This is quite the tricky thing to do in Android and I haven't done it yet. But maybe these links may help you:
Add this single line in manifest (for permission)
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Then paste this code in your activity
private ArrayList<String> getPrimaryMailId() {
ArrayList<String> accountsList = new ArrayList<String>();
try {
Account[] accounts = AccountManager.get(this).getAccountsByType("com.google");
for (Account account : accounts) {
accountsList.add(account.name);
Log.e("GetPrimaryMailId ", account.name);
}
} catch (Exception e) {
Log.e("GetPrimaryMailId", " Exception : " + e);
}
return accountsList;
}
The suggested answers won't work anymore as there is a new restriction imposed from android 8 onwards.
more info here: https://developer.android.com/about/versions/oreo/android-8.0-changes.html#aaad
Step 1 - Add the following code in AndroidManifest.xml -
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
Step 2 - Add the following code in your activity asking for permissions at runtime.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if ((ActivityCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED) && (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)) {
getGoogleAccounts();
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.READ_CONTACTS}, 1);
//return false;
}
}
Step 3 - Add code for onRequestPermissionsResult -
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
getGoogleAccounts();
}
}
Step 4 - Finally add code to retrieve account using AccountManager
private void getGoogleAccounts(){
AccountManager am = AccountManager.get(this); // "this" references the current Context
Account[] accounts = am.getAccountsByType("com.google");
for (Account acc : accounts){
System.out.println("http accounts " + acc);
}
}
Please refer to following link for changes in android 8 - https://developer.android.com/about/versions/oreo/android-8.0-changes#aaad