如何获取 Android 设备的主要电子邮件地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2112965/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:34:53  来源:igfitidea点击:

How to get the Android device's primary e-mail address

androidemail

提问by Brandon O'Rourke

How do you get the Android's primary e-mail address (or a list of e-mail addresses)?

您如何获得 Android 的主要电子邮件地址(或电子邮件地址列表)?

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.

我的理解是在 OS 2.0+ 上支持多个电子邮件地址,但在 2.0 以下每个设备只能有一个电子邮件地址。

回答by Roman Nurik

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.

作为一个友好的警告,在处理帐户、个人资料和联系人数据时,请小心并提前告知用户。如果您滥用用户的电子邮件地址或其他个人信息,可能会发生不好的事情。

Method A: Use AccountManager(API level 5+)

方法 A:使用AccountManager(API 级别 5+)

You can use AccountManager.getAccountsor AccountManager.getAccountsByTypeto 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.

您可以使用AccountManager.getAccountsAccountManager.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;
        ...
    }
}

Note that this requires the GET_ACCOUNTSpermission:

请注意,这需要GET_ACCOUNTS权限:

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

More on using AccountManagercan be found at the Contact Managersample code in the SDK.

在 SDKAccountManager中的Contact Manager示例代码中可以找到有关使用的更多信息。

Method B: Use ContactsContract.Profile(API level 14+)

方法 B:使用ContactsContract.Profile(API 级别 14+)

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.

从 Android 4.0 (Ice Cream Sandwich) 开始,您可以通过访问用户的个人资料来获取用户的电子邮件地址。访问用户个人资料有点重量级,因为它需要两个权限(更多内容见下文),但电子邮件地址是相当敏感的数据,因此这是入场的代价。

Below is a full example that uses a CursorLoaderto retrieve profile data rows containing email addresses.

下面是一个完整的示例,它使用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;
    }
}

This requires both the READ_PROFILEand READ_CONTACTSpermissions:

这需要READ_PROFILEREAD_CONTACTS权限:

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

回答by Jorge Cevallos

This could be useful to others:

这可能对其他人有用:

Using AccountPicker to get user's email addresswithout any global permissions, and allowing the user to be aware and authorize or cancel the process.

使用 AccountPicker 获取用户的邮箱地址,无需任何全局权限,并允许用户知晓并授权或取消该过程。

回答by SeBsZ

I would use Android's AccountPicker, introduced in ICS.

我会使用ICS 中引入的Android 的AccountPicker

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

And then wait for the result:

然后等待结果:

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

回答by Afzaal Iftikhar

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

回答by Wirling

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

有一个 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);
}

This will show a picker where the user can select an emailaddress. The result will be delivered in onActivityResult()

这将显示一个选择器,用户可以在其中选择电子邮件地址。结果将在onActivityResult()

回答by Burak Day

Sadly accepted answer isn't working.

可悲的是接受的答案不起作用。

I'm late, but here's the solution for internal Android Email application unless the content uri is changed by provider:

我迟到了,但这是内部 Android 电子邮件应用程序的解决方案,除非内容 uri 由提供商更改:

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

回答by AGrunewald

This is quite the tricky thing to do in Android and I haven't done it yet. But maybe these links may help you:

这在 Android 中是相当棘手的事情,我还没有做到。但也许这些链接可以帮助您:

回答by Iman Marashi

Use this method:

使用这个方法:

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

Note that this requires the GET_ACCOUNTSpermission:

请注意,这需要GET_ACCOUNTS权限:

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

Then:

然后:

editTextEmailAddress.setText(getUserEmail());

回答by hushed_voice

The suggested answers won't work anymore as there is a new restriction imposed from android 8 onwards.

建议的答案不再有效,因为从 android 8 开始施加了新的限制。

more info here: https://developer.android.com/about/versions/oreo/android-8.0-changes.html#aaad

更多信息在这里:https: //developer.android.com/about/versions/oreo/android-8.0-changes.html#aaad

回答by Agilanbu

Add this single line in manifest (for permission)

在清单中添加这一行(以获得许可

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

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