Android cihazın birincil e-posta adresi nasıl alınır?


412

Android'in birincil e-posta adresini (veya e-posta adreslerinin listesini) nasıl alırsınız?

OS 2.0 ve üstü sürümlerde birden çok e-posta adresi desteği olduğunu biliyorum, ancak 2.0'ın altında cihaz başına yalnızca bir e-posta adresiniz olabilir.


Bir kişinin e-posta adresini almaktan mı bahsediyorsunuz?
Austyn Mahoney

1
Hayır, cihazın birincil e-posta adresi.
Brandon O'Rourke

Android cihazla ilişkilendirilmiş bir veya daha fazla e-posta adresi var değil mi? İstediğim bu.
Brandon O'Rourke

2
@ BrandonO'Rourke Android Market ile ilişkili olan "cihazın birincil e-posta Adresi" mi demek istediniz? Çünkü Android Market ile ilişkili gmail kimliği ile diğer e-postalar arasında bir fark var. Bu soruya bir göz atın stackoverflow.com/questions/10606976/…
Gaurav Agarwal

Yanıtlar:


749

Aşağıda gösterilen bunu yapmanın birkaç yolu vardır.

Dostça bir uyarı olarak, hesap, profil ve iletişim verileriyle uğraşırken kullanıcılara karşı dikkatli ve açık olun. Bir kullanıcının e-posta adresini veya diğer kişisel bilgilerini kötüye kullanırsanız, kötü şeyler olabilir.

Yöntem A: AccountManager kullanın (API düzeyi 5+)

Cihazdaki tüm hesap adlarının bir listesini almak için AccountManager.getAccountsveya tuşlarını kullanabilirsiniz AccountManager.getAccountsByType. Neyse ki, belirli hesap türleri (dahil com.google) için hesap adları e-posta adresleridir. Aşağıdaki örnek snippet.

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

Bunun GET_ACCOUNTSizin gerektirdiğini unutmayın :

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

Daha kullanımıyla ilgili AccountManagerbulunabilir İletişim Yöneticisi SDK'sında örnek kod.

Yöntem B: ContactsContract.Profile kullanın (API düzeyi 14+)

Android 4.0'dan (Ice Cream Sandwich) itibaren profiline erişerek kullanıcının e-posta adreslerini alabilirsiniz. Kullanıcı profiline erişmek, iki izin gerektirdiğinden (aşağıda daha fazlası) biraz ağırdır, ancak e-posta adresleri oldukça hassas veri parçalarıdır, bu nedenle giriş ücreti budur.

Aşağıda, CursorLoadere-posta adreslerini içeren profil veri satırlarını almak için a kullanan tam bir örnek verilmiştir .

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

Bu hem READ_PROFILEve hem de READ_CONTACTSizinleri gerektirir :

<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />

3
i kodumu kullanarak benzer bir soru var i benim telefon ile ilişkili tüm gmail kimliği elde edebiliyoruz ama birincil istiyorum. Ben 0 pozisyon com.google id alıyorsanız, bir yığına geliyor telefon ile senkronize etmek için daha fazla posta kimliği eklemek gibi bir çözüm buldum, çünkü ilk girin ve bir yığın 0 pozisyon almak . İşte benim bazı kod Account [] accounts = AccountManager.get (this) .getAccountsByType ("com.google"); Dize myEmailid = accounts [0] .toString (); Log.d ("İstediğim e-posta kimliğim", myEmailid); bunun doğru yol olmadığını biliyorum.
PiyushMishra

59
Profil yöntemi kötü bir şekilde hatalı (benim görüşüme göre). E-postamı isteyen / ihtiyacı olan bir uygulama, tüm kişilerimi okumak isteyen bir uygulamaya kıyasla büyük bir anlaşma değil, ancak her ikisinin de aynı izinleri almasını sağlamak için yaptınız. Kullanıcı olarak e-postamı okuyacak bir uygulama ile 500'den fazla kişimi okuyacak bir uygulama arasındaki farkı söyleyemem. Kişilerinizi kötüye kullanan uygulamaların sayısı arttıkça bu çok gerçek ve pratik bir sorundur!
Tom

3
@Muzikant Hiçbir şekilde resmi bir açıklama yok, ama bu değişmesi pek mümkün olmayan bir şey. Bunu söyledikten sonra, bir kullanıcının e-posta adreslerine erişmenin "doğru" yolu Yöntem B'dir. Bu daha "resmi" ve bazı ağır izinlerin arkasında olması, bu tür verilere yaklaşmanız gereken hassasiyeti göstermelidir.
Roman Nurik

15
Bu konuda @Tom ile hemfikirim. Kullanıcının sadece Adı ve Soyadı için telefondaki tüm kişilerin verileri için izin istemek saçma.
tasomaniac

3
Yöntem 4.4, tüm örnek kodu kopyalayarak Android 4.4'te benim için çalışmıyor. cursor.isAfterLast()her zaman true değerini döndürür. Herhangi bir fikir?
cprcrack

55

Bu başkaları için yararlı olabilir:

Kullanıcının e-posta adresini herhangi bir genel izin olmadan almak için AccountPicker'ı kullanma ve kullanıcının işlemi bilmesine, yetkilendirmesine veya iptal etmesine izin vermek.


1
Bu ben bu seçenek tercih olması gerektiğini düşünüyorum, bir çok yararlı cevap Ana Eposta genellikle birlikte sahip olacak çevirmek Google Hesabı anlamına gelir Google Play
Alex.F

@ Alex.F Bu, marshmellow'dan sonra / marshmellow'dan android sürümleri için çalışıyor mu?
Eswar

27

Android'in ICS'de tanıtılan AccountPicker aracını kullanırdım .

Intent googlePicker = AccountPicker.newChooseAccountIntent(null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null);
startActivityForResult(googlePicker, REQUEST_CODE);

Ve sonra sonucu bekleyin:

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

2
Oyun hizmetlerini kullanmanızı gerektirdiğini ve bazı durumlarda kullanıcının hesabı seçmesi gerektiğini belirten bir iletişim kutusu göstereceğini unutmayın.
android geliştirici

AccountManager.newChooseAccountIntent () işlevini kullanmak aynı işi yapar ve oyun hizmetleri kitaplığı gerektirmez.
Denis

Bu, en son android sürümü bağlamında hesap kimlik doğrulaması için kullanıcıya açılır mı? Evet ise, yalnızca bir hesabı olan bir cihaz için bunu nasıl atlayabilirim?
Eswar

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

Güzel ve kolay yöntem Teşekkürler :)
Talha Q

2
Bunun android.permission.GET_ACCOUNTS, 'tehlikeli' izin olarak tanımlanan (çalışma zamanı isteği gerektirir) şunu gerektirdiğine dikkat edin : developer.android.com/reference/android/…
SagiLow

@SagiLow Bunu nasıl ele aldınız? Kullanıcıdan başka bir izin istemiyorum, sadece e-posta adresini girmek için tembel hale getirmek için :)
kod

1
@codebased bilmiyordum ... bildiğim kadarıyla mümkün değil.
SagiLow

2
manager.getAccountsByType ( "com.google"); Android'in sonraki sürümleriyle çalışmaz.
powder366

8

Kullanıcının izne ihtiyaç duymadan e-posta adreslerini seçmesine izin veren bir Android API'si var. Bir göz atın: 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);
}

Bu, kullanıcının bir e-posta adresi seçebileceği bir seçici gösterecektir. Sonuç teslim edilecekonActivityResult()


Bunu kullanabildiğimi doğrulayabilirim, bulduğum tek çalışma cevabı için teşekkürler
csga5000

Tek çalışma çözümü, teşekkürler wirling
Zulqarnain

7

Ne yazık ki kabul edilen cevap çalışmıyor.

Geç kaldım, ancak içerik uri sağlayıcı tarafından değiştirilmediği sürece dahili Android E-posta uygulaması için çözüm:

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


2

Bu yöntemi kullanın:

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

Bunun GET_ACCOUNTSizin gerektirdiğini unutmayın :

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

Sonra:

editTextEmailAddress.setText(getUserEmail());

Bu sadece mevcut uygulama ile ilişkili hesapları iade gibi görünüyor - bu yüzden test "hiçbiri" elde
csga5000

manager.getAccountsByType ("com.google"), Android'in sonraki sürümlerinde çalışmaz. Ve App.getInstance () nereden geliyor?
powder366


0

Android GET_ACCOUNTSson zamanlarda kilitlendi, bu nedenle bazı cevaplar benim için çalışmadı. Android 7.0'da bu çalışmayı kullanıcılarınızın izin iletişim kutusuna katlanmak zorunda oldukları uyarısı ile aldım.

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

Bu diğer cevaplardan farklı değildir ve bu benim için çalışmıyor gibi görünüyor - görünüşe göre android yeni sürümlerinde bu sadece uygulama ile ilişkili hesapları döndürür ve artık izin gerektirmez.
csga5000

0

MarshMallow İşletim Sisteminde Çalışma

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


            }
        }
    });

<kullanımları izin android: name = "android.permission.GET_ACCOUNTS" />
Keshav Gera

1
Hesaplar yanıtları benim için işe yaramadı (0 hesap döndür) - ve bir düğme geri çağrısında kodu çağırmanın hiçbir fark yaratmadığını onaylayabilirim.
csga5000

Bu Kod çalışıyor ama son zamanlarda zaman sorun var bu yüzden lütfen bizim tarafımızı kontrol
Keshav Gera

0

Bu tek satırı manifest'e ekle ( izin için )

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

Ardından bu kodu etkinliğinize yapıştırın

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.