Как получить основной адрес электронной почты устройства Android
Как вы получаете основной адрес электронной почты Android (или список адресов электронной почты)?
Насколько я понимаю, в OS 2.0+ есть поддержка нескольких адресов электронной почты, но ниже 2.0 вы можете иметь только один адрес электронной почты на устройство.
13 ответов
Есть несколько способов сделать это, показанные ниже.
В качестве дружеского предупреждения будьте внимательны и откровенны с пользователем при работе с учетной записью, профилем и контактными данными. Если вы неправильно используете адрес электронной почты пользователя или другую личную информацию, могут произойти плохие вещи.
Способ А. Использование AccountManager (уровень API 5+)
Ты можешь использовать AccountManager.getAccounts
или же AccountManager.getAccountsByType
чтобы получить список всех имен учетных записей на устройстве. К счастью, для определенных типов счетов (в том числе com.google
), имена учетных записей являются адресами электронной почты. Пример фрагмента ниже.
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;
...
}
}
Обратите внимание, что это требует GET_ACCOUNTS
разрешение:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Подробнее об использовании AccountManager
можно найти в образце кода Contact Manager в SDK.
Способ Б. Использование ContactsContract.Profile (уровень API 14+).
Начиная с Android 4.0 (Ice Cream Sandwich), вы можете получить адреса электронной почты пользователя, зайдя в его профиль. Доступ к профилю пользователя немного тяжеловесен, поскольку для него требуется два разрешения (подробнее об этом ниже), но адреса электронной почты являются довольно конфиденциальными данными, поэтому это цена входного билета.
Ниже приведен полный пример, который использует CursorLoader
чтобы получить строки данных профиля, содержащие адреса электронной почты.
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;
}
}
Это требует как READ_PROFILE
а также READ_CONTACTS
разрешения:
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
Это может быть полезно для других:
Использование AccountPicker для получения адреса электронной почты пользователя без каких-либо глобальных разрешений, а также позволяет пользователю быть в курсе и авторизовать или отменить процесс.
Я бы использовал Android AccountPicker, представленный в ICS.
Intent googlePicker = AccountPicker.newChooseAccountIntent(null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null);
startActivityForResult(googlePicker, REQUEST_CODE);
А затем дождитесь результата:
protected void onActivityResult(final int requestCode, final int resultCode,
final Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
}
}
public String getUsername() {
AccountManager manager = AccountManager.get(this);
Account[] accounts = manager.getAccountsByType("com.google");
List<String> possibleEmails = new LinkedList<String>();
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.
possibleEmails.add(account.name);
}
if (!possibleEmails.isEmpty() && possibleEmails.get(0) != null) {
String email = possibleEmails.get(0);
String[] parts = email.split("@");
if (parts.length > 1)
return parts[0];
}
return null;
}
Существует Android API, который позволяет пользователю выбирать свой адрес электронной почты без необходимости разрешения. Взгляните на: 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);
}
Это покажет сборщик, где пользователь может выбрать адрес электронной почты. Результат будет доставлен в onActivityResult()
К сожалению, принятый ответ не работает.
Я опаздываю, но вот решение для внутреннего приложения электронной почты Android, если контент не изменен поставщиком:
Uri EMAIL_ACCOUNTS_DATABASE_CONTENT_URI =
Uri.parse("content://com.android.email.provider/account");
public ArrayList<String> GET_EMAIL_ADDRESSES ()
{
ArrayList<String> names = new ArrayList<String>();
ContentResolver cr = m_context.getContentResolver();
Cursor cursor = cr.query(EMAIL_ACCOUNTS_DATABASE_CONTENT_URI ,null,
null, null, null);
if (cursor == null) {
Log.e("TEST", "Cannot access email accounts database");
return null;
}
if (cursor.getCount() <= 0) {
Log.e("TEST", "No accounts");
return null;
}
while (cursor.moveToNext()) {
names.add(cursor.getString(cursor.getColumnIndex("emailAddress")));
Log.i("TEST", cursor.getString(cursor.getColumnIndex("emailAddress")));
}
return names;
}
Это довольно сложная вещь для Android, и я еще не сделал этого. Но, возможно, эти ссылки могут помочь вам:
Используйте этот метод:
public String getUserEmail() {
AccountManager manager = AccountManager.get(App.getInstance());
Account[] accounts = manager.getAccountsByType("com.google");
List<String> possibleEmails = new LinkedList<>();
for (Account account : accounts) {
possibleEmails.add(account.name);
}
if (!possibleEmails.isEmpty() && possibleEmails.get(0) != null) {
return possibleEmails.get(0);
}
return "";
}
Обратите внимание, что это требует GET_ACCOUNTS
разрешение:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Затем:
editTextEmailAddress.setText(getUserEmail());
Предлагаемые ответы больше не будут работать, так как начиная с Android 8 введено новое ограничение.
подробнее здесь: https://developer.android.com/about/versions/oreo/android-8.0-changes.html
Для Android 8 и выше -
Шаг 1. Добавьте следующий код в AndroidManifest.xml -
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
Шаг 2. Добавьте следующий код в свою активность, запрашивая разрешения во время выполнения.
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;
}
}
Шаг 3 - Добавьте код для 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();
}
}
Шаг 4 - Наконец, добавьте код для получения учетной записи с помощью 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);
}
}
Пожалуйста, обратитесь к следующей ссылке для изменений в android 8 - https://developer.android.com/about/versions/oreo/android-8.0-changes#aaad
Добавьте эту единственную строку в манифест (для разрешения)
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Затем вставьте этот код в свою деятельность
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;
}
Работа в операционной системе MarshMallow
btn_click=(Button) findViewById(R.id.btn_click);
btn_click.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
int permissionCheck = ContextCompat.checkSelfPermission(PermissionActivity.this,
android.Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED)
{
//showing dialog to select image
String possibleEmail=null;
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(PermissionActivity.this).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
possibleEmail = account.name;
Log.e("keshav","possibleEmail"+possibleEmail);
}
}
Log.e("keshav","possibleEmail gjhh->"+possibleEmail);
Log.e("permission", "granted Marshmallow O/S");
} else { ActivityCompat.requestPermissions(PermissionActivity.this,
new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.READ_PHONE_STATE,
Manifest.permission.GET_ACCOUNTS,
android.Manifest.permission.CAMERA}, 1);
}
} else {
// Lower then Marshmallow
String possibleEmail=null;
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(PermissionActivity.this).getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
possibleEmail = account.name;
Log.e("keshav","possibleEmail"+possibleEmail);
}
Log.e("keshav","possibleEmail gjhh->"+possibleEmail);
}
}
});
Android заблокирован GET_ACCOUNTS
недавно, поэтому некоторые ответы не сработали для меня. Я получил это работает на Android 7.0 с оговоркой, что ваши пользователи должны вынести диалог разрешения.
AndroidManifest.xml
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
MainActivity.java
package com.example.patrick.app2;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.accounts.AccountManager;
import android.accounts.Account;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.*;
public class MainActivity extends AppCompatActivity {
final static int requestcode = 4; //arbitrary constant less than 2^16
private static String getEmailId(Context context) {
AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccountsByType("com.google");
Account account;
if (accounts.length > 0) {
account = accounts[0];
} else {
return "length is zero";
}
return account.name;
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case requestcode:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
String emailAddr = getEmailId(getApplicationContext());
ShowMessage(emailAddr);
} else {
ShowMessage("Permission Denied");
}
}
}
public void ShowMessage(String email)
{
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage(email);
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getApplicationContext();
if ( ContextCompat.checkSelfPermission( context, android.Manifest.permission.GET_ACCOUNTS )
!= PackageManager.PERMISSION_GRANTED )
{
ActivityCompat.requestPermissions( this, new String[]
{ android.Manifest.permission.GET_ACCOUNTS },requestcode );
}
else
{
String possibleEmail = getEmailId(getApplicationContext());
ShowMessage(possibleEmail);
}
}
}