获取Android设备所有者的电子邮件地址的方法

45

我想让用户在不用输入的情况下提供他们的电子邮件地址。理想情况下,有一个文本框,用户可以在其中输入电子邮件地址或按一个按钮来自动填充。

在早些时候的一个问题中,Roman Nurik建议使用AccountManager来处理这个问题,但这需要我的应用程序使用GET_ACCOUNTS权限;然后我的应用程序就可以访问设备上用户所有的帐户,包括他们的Facebook/Twitter帐户。对于我想要的功能来说,这种权限似乎过于广泛了。

有没有更好的方法来处理这个问题,而不需要授予我的应用程序如此重的权限?


2
发问后我注意到一件事情,那就是 GET_ACCOUNTS 权限通常隐藏在“更多细节”部分中,它不会在折叠前的权限列表中显示。因此,大多数用户不会注意到您是否请求此权限。 - Dan Fabulich
你真的认为 GET_ACCOUNTS 很重吗?如果你想支持 < v4.0.4,那么你需要它来使用 GCM。 - ostergaard
您也需要请求此权限吗?用户可以禁用它吗? - rupinderjeet
5个回答

123

虽然我知道现在已经太晚了,但这对他人可能有用。

我认为现在自动填充电子邮件字段的最佳方法是使用AccountPicker

如果您的应用程序具有 GET_ACCOUNTS 权限并且只有一个帐户,则可以立即获取该帐户。 如果您的应用程序没有它,或者如果有多个帐户,则用户会得到一个提示,因此他们可以授权或不授权该操作。

您的应用程序需要包含Google Play Services身份验证库com.google.android.gms:play-services-auth,但不需要任何权限。

整个过程将在旧版本的 Android(需要2.2+),或者如果 Google Play 不可用时失败,因此您应该考虑该情况。

这是一个基本的代码示例:

    private static final int REQUEST_CODE_EMAIL = 1;
    private TextView email = (TextView) findViewById(R.id.email);

    // ...

    try {
        Intent intent = AccountPicker.newChooseAccountIntent(null, null,
                new String[] { GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE }, false, null, null, null, null);
        startActivityForResult(intent, REQUEST_CODE_EMAIL);
    } catch (ActivityNotFoundException e) {
        // TODO
    }

    // ...

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE_EMAIL && resultCode == RESULT_OK) {
            String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            email.setText(accountName);
        }
    }

说谷歌应用商店未激活就无法使用是没有意义的,因为每个应用都是通过谷歌应用商店下载的,除非用户从浏览器下载了apk文件。但是回答不错,点赞+1。 - Luis Pena
19
有许多设备不符合Google设定的要求,因此无法访问G应用程序,包括Google Play。它们必须从其他市场安装应用程序或通过下载APK文件进行安装。即使只有很小一部分,您在应用程序中也必须考虑所有情况。 - Jorge Cevallos
2
已在4台不同设备上进行了测试,适用于从Android 4.x到Android 5.1的版本,并且这种方法对所有设备都有效:Galaxy Note 4、HTC One X+、Sony Xperia和Nexus7平板电脑。谢谢! - A. Masson
2
@semicircle21 由于某种原因,只有与互联网相关的权限和“防止手机休眠”这些被添加了。与联系人/帐户无关。我现在已经在多个Android设备和版本上进行了测试。另外,顺便说一下,从Android 6开始,您可以使用:AccountManager.newChooseAccountIntent - android developer
1
准确来说,您需要包括 com.google.android.gms:play-services-auth:17.0.0 - CamHart
显示剩余8条评论

19

事实上,如果没有 GET_ACCOUNTS 权限,你不仅无法做到这一点,而且你想要的信息只存在于用户(谷歌)账户数据中。

在我的 Sprint 手机上, 'owner' 地址是 Sprint 分配的 myusername@sprintpcs.com,可以使用 shell 的 getprop 查看。但那不是我的主要电子邮件地址,甚至也不是我曾经使用/检查过的地址。你想要的是我的 Gmail 地址,而这是存储在 Android 账户数据中的。

实际上,你想要的是两个中的一个 —— 这是需要 GET_ACCOUNTS 的另一个原因。如果你要问我的电子邮件地址,你需要让我在设备上选择两个已配置的 @gmail.com 账户之一。 知道哪一个是我的“首选”(虽然即使这个也是有上下文的),但据我所知,系统认为其中任何一个都不比另一个更“主要”或“默认”。


0

1
我认为那不是一个可行的替代方案;这与Roman的建议没有什么不同(我在原始问题中提供了链接)。它要求我获取账户,这在我看来是一个过于重要的安全权限。 - Dan Fabulich
3
好的,我认为你的问题的答案是否定的。 - Graham Borland
不要使用这个,有些人有自定义域名。 - Ajay

0
由于被接受的答案已经过时,您可以采用新的方法:
val result = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {

    if (it.resultCode == Activity.RESULT_OK) {
        val accountName = it.data?.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)
    }
}

val options = AccountChooserOptions.Builder()       
    .setAlwaysShowAccountPicker(true)
    .build()

result.launch(AccountPicker.newChooseAccountIntent(options))

-8

没有什么好的方法可以在不请求GET_ACCOUNTS权限的情况下访问用户的帐户(电子邮件)信息。 :-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接