Android:无需可怕的(对于用户)权限即可获取用户 ID?

Android: get user ID without requiring scary (for user) permissions?

为了管理用户偏好,目前我正在获取 google 用户名(实际上是他们注册到设备的电子邮件地址)并将其用作 "user ID"区分不同的用户。与 here.

所描述的内容一致

一切正常,但有些用户(可以理解)被任何似乎赋予该应用某种邪恶力量以搜集他们的帐户信息或联系人的权限吓跑。

编辑:这个问题对于 Google 现在实施 Permission Groups in the Android 6 runtime permission 模式的方式来说更加尖锐。他们已将 GET_ACCOUNTS 放入 CONTACTS 权限组。所以现在,为了生成一个唯一的匿名用户 ID,必须向用户显示一个对话框,上面写着:

Allow this app to access your contacts? | Deny | Allow |

这有多大的误导性??我的应用不想访问联系人,但系统要求用户授予该应用访问联系人的权限!是的,有机会通过一个单独的对话框向用户解释,事实上,不需要访问联系人,但是他们仍然会看到股票系统对话框,要求他们授予访问联系人的权限......自然他们会认为 "why am I being asked to grant this permission if access to contacts is not required?" 和 "do I really trust the developer? they say access to contacts is not required, but is that really true?"... 非常非常混乱和非常糟糕的用户体验恕我直言(以及 others too 的意见)。

我宁愿避免所有这些麻烦和混乱,并获得一个唯一的用户 ID,而无需特殊权限。

那么 SDK 中是否有一个常用函数或方法可以 return 为用户创建一个唯一的用户 ID,而不需要任何额外的许可?如果没有,我会感到有点惊讶,因为这似乎是一件很常见的事情...想要拥有一个用户 ID 来管理应用程序用户。

两点:

(a) 我只需要一个匿名用户 ID... 我实际上不需要用户的电子邮件地址,也永远不需要用户的电子邮件地址。所以我不明白为什么 google 不能提供 return 唯一匿名 ID 的 getUserID() 方法,而无需向应用程序授予特殊权限。

(b) 它必须是用户 ID,而不是设备 ID,以便它可以在注册到同一 google 帐户的所有用户设备上使用。

谢谢。

不幸的是,没有解决方案,即使是最基本的帐户访问也需要用户许可。

您可以使用 Google 广告 ID 作为 UUID,但它不是 cross-device(还?):

https://support.google.com/googleplay/android-developer/answer/6048248?hl=en

这至少可以摆脱可怕的权限请求。

我不相信 Android/Google 有一个不需要许可的 cross-device UUID,尽管 Google 的 Doubleclick 据说正在开发一个。

如果您使用 Google Play 服务,您无需任何额外权限即可获取帐户类型和帐户名称。

首先,将以下依赖添加到build.gradle:

compile 'com.google.android.gms:play-services-auth:8.4.0'

接下来,启动帐户选择器意图:

Intent intent = AccountPicker.newChooseAccountIntent(null, null,
    new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE},
    false, null, null, null, null);

try {
  startActivityForResult(intent, REQUEST_CODE_EMAIL);
} catch (ActivityNotFoundException e) {
  // This device may not have Google Play Services installed.
  // TODO: do something else
}

最后,覆盖onActivityResult以获取帐户类型和帐户名称:

@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);
    String accountType = data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE);
    // TODO: do something with the accountName
    return;
  }
  super.onActivityResult(requestCode, resultCode, data);
}

来源:

您可以使用 AccountPicker 获取确切的 gmail 电子邮件地址,而无需添加权限。

Your app needs to include the Google Play Services but it doesn't need any permissions.

This whole process will fail on older versions of Android (2.2+ is required), or if Google Play is not available so you should consider that case.

来源中的示例代码:

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

上述信息的来源 是:This Answer on SO - 过去提出的一个类似但略有不同的问题。

This Post - 还有一些不错的方法可以满足您的目的。