如何获取 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
How to get the Android device's primary e-mail address
提问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.getAccounts
or AccountManager.getAccountsByType
to 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.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;
...
}
}
Note that this requires the GET_ACCOUNTS
permission:
请注意,这需要GET_ACCOUNTS
权限:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
More on using AccountManager
can 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 CursorLoader
to 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_PROFILE
and READ_CONTACTS
permissions:
这需要READ_PROFILE
和READ_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_ACCOUNTS
permission:
请注意,这需要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;
}