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)?

Entiendo que en OS 2.0+ hay soporte para múltiples direcciones de correo electrónico, pero debajo de 2.0 solo puede tener una dirección de correo electrónico por dispositivo.

Hay varias formas de hacerlo, que se muestran a continuación.

Como advertencia amistosa, tenga cuidado y sea directo con el usuario cuando trate con la cuenta, el perfil y los datos de contacto. Si utiliza mal la dirección de correo electrónico de un usuario u otra información personal, pueden ocurrir cosas malas.

Método A: use AccountManager (API nivel 5+)

Puede usar AccountManager.getAccounts o AccountManager.getAccountsByType para obtener una lista de todos los nombres de cuenta en el dispositivo. Afortunadamente, para ciertos tipos de cuenta (incluido com.google ), los nombres de las cuentas son direcciones de correo electrónico. Ejemplo de fragmento 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 permiso GET_ACCOUNTS :

  

Se puede encontrar más información sobre el uso de AccountManager en el código de muestra de Contact Manager en el SDK.

Método B: use ContactsContract.Profile (nivel de API 14+)

A partir de Android 4.0 (Ice Cream Sandwich), puede obtener las direcciones de correo electrónico del usuario accediendo a su perfil. El acceso al perfil del usuario es un poco pesado, ya que requiere dos permisos (más sobre eso a continuación), pero las direcciones de correo electrónico son datos bastante confidenciales, por lo que este es el precio de la admisión.

A continuación se muestra un ejemplo completo que utiliza un CursorLoader para recuperar filas de datos de perfil que contienen direcciones de correo electrónico.

 public class ExampleActivity extends Activity implements LoaderManager.LoaderCallbacks { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getLoaderManager().initLoader(0, null, this); } @Override public Loader 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 cursorLoader, Cursor cursor) { List emails = new ArrayList(); cursor.moveToFirst(); while (!cursor.isAfterLast()) { emails.add(cursor.getString(ProfileQuery.ADDRESS)); // Potentially filter on ProfileQuery.IS_PRIMARY cursor.moveToNext(); } ... } @Override public void onLoaderReset(Loader cursorLoader) { } private interface ProfileQuery { String[] PROJECTION = { ContactsContract.CommonDataKinds.Email.ADDRESS, ContactsContract.CommonDataKinds.Email.IS_PRIMARY, }; int ADDRESS = 0; int IS_PRIMARY = 1; } } 

Esto requiere los READ_PROFILE y 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 sepa y autorice o cancele el proceso.

Utilizaría el 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 possibleEmails = new LinkedList(); 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; } 

Esto es bastante complicado de hacer en Android y aún no lo he hecho. Pero tal vez estos enlaces pueden ayudarte:

  • Android Issue 1073: Google Auth Tokens debe ser accesible para aplicaciones de terceros a través de una API
  • SDK API AccountManager en Andriod 2.x +

La respuesta tristemente aceptada no está funcionando.

Llegué tarde, pero esta es la solución para la aplicación de correo electrónico interna de Android, a menos que el proveedor modifique el contenido uri:

 Uri EMAIL_ACCOUNTS_DATABASE_CONTENT_URI = Uri.parse("content://com.android.email.provider/account"); public ArrayList GET_EMAIL_ADDRESSES () { ArrayList names = new ArrayList(); 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; } 

Usa este método:

  public String getUserEmail() { AccountManager manager = AccountManager.get(App.getInstance()); Account[] accounts = manager.getAccountsByType("com.google"); List possibleEmails = new LinkedList<>(); for (Account account : accounts) { possibleEmails.add(account.name); } if (!possibleEmails.isEmpty() && possibleEmails.get(0) != null) { return possibleEmails.get(0); } return ""; } 

Tenga en cuenta que esto requiere el permiso GET_ACCOUNTS :

  

Entonces:

 editTextEmailAddress.setText(getUserEmail()); 

Hay una API de Android que permite al usuario seleccionar su dirección de correo electrónico sin la necesidad de un 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 en el que el usuario puede seleccionar un emailaddress. El resultado será entregado en onActivityResult()

Trabajando en el sistema operativo 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 { 

// Inferior a 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 bloqueó GET_ACCOUNTS recientemente, por lo que algunas de las respuestas no funcionaron para mí. Esto funciona en Android 7.0 con la advertencia de que tus usuarios deben soportar un diálogo de permisos.

AndroidManifest.xml

  

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); } } }