Cómo obtener la dirección de correo electrónico principal del dispositivo Android
¿Cómo se obtiene la dirección de correo electrónico principal de Android (o una lista de direcciones de correo electrónico)?
Tengo entendido que en OS 2.0+ hay soporte para múltiples direcciones de correo electrónico, pero por debajo de 2.0 solo puedes tener una dirección de correo electrónico por dispositivo.
Hay varias formas de hacer esto, que se muestran a continuación.
Como advertencia amistosa, tenga cuidado y sea sincero con el usuario cuando trate con datos de cuenta, perfil y contacto. Si hace un mal uso de la dirección de correo electrónico de un usuario u otra información personal, pueden suceder cosas malas.
Método A: utilizar AccountManager (nivel de API 5+)
Puede utilizar AccountManager.getAccounts
o AccountManager.getAccountsByType
para obtener una lista de todos los nombres de cuentas en el dispositivo. Afortunadamente, para ciertos tipos de cuentas (incluidas com.google
), los nombres de las cuentas son direcciones de correo electrónico. Fragmento de ejemplo a continuación.
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;
...
}
}
Tenga en cuenta que esto requiere el GET_ACCOUNTS
permiso:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
AccountManager
Puede encontrar más información sobre el uso en el código de muestra de Contact Manager en el SDK.
Método B: utilizar ContactsContract.Profile (nivel de API 14+)
A partir de Android 4.0 (Ice Cream Sandwich), se pueden obtener las direcciones de correo electrónico del usuario accediendo a su perfil. Acceder al perfil de usuario es un poco pesado ya que requiere dos permisos (más sobre esto a continuación), pero las direcciones de correo electrónico son datos bastante confidenciales, por lo que este es el precio de entrada.
A continuación se muestra un ejemplo completo que utiliza CursorLoader
para recuperar filas de datos de perfil que contienen direcciones de correo electrónico.
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;
}
}
Esto requiere permisos READ_PROFILE
y READ_CONTACTS
:
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
Esto podría ser útil para otros:
Usar AccountPicker para obtener la dirección de correo electrónico del usuario sin ningún permiso global y permitir que el usuario esté al tanto y autorice o cancele el proceso.
Usaría AccountPicker de Android , introducido en ICS.
Intent googlePicker = AccountPicker.newChooseAccountIntent(null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null);
startActivityForResult(googlePicker, REQUEST_CODE);
Y luego espera el resultado:
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;
}
Existe una API de Android que permite al usuario seleccionar su dirección de correo electrónico sin necesidad de permiso. Eche un vistazo a: 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);
}
Esto mostrará un selector donde el usuario puede seleccionar una dirección de correo electrónico. El resultado se entregará enonActivityResult()