【问题标题】:Android 8.0 Oreo - AccountsAndroid 8.0 Oreo - 帐户
【发布时间】:2017-09-29 19:54:58
【问题描述】:

在我的应用中,我需要知道是否有任何 Google 帐户或任何三星帐户。

在 Android 7 之前,很容易通过以下方式获取此信息:

    Account[] accounts = AccountManager.get(getContext())
.getAccountsByType("com.google")

但是对于Oreo 的事件,这不再起作用了。

编辑:查看有关此主题的官方信息: 在 Android 8.0(API 级别 26)中,应用程序无法再访问用户帐户,除非身份验证器拥有帐户或用户授予该访问权限。 GET_ACCOUNTS 权限不再足够。要获得对帐户的访问权限,应用程序应使用 AccountManager.newChooseAccountIntent() 或特定于身份验证器的方法。获得帐户访问权限后,应用可以调用 AccountManager.getAccounts() 来访问它们。 Android 8.0 弃用了 LOGIN_ACCOUNTS_CHANGED_ACTION。应用程序应改为使用 addOnAccountsUpdatedListener() 在运行时获取有关帐户的更新。 有关为帐户访问和可发现性添加的新 API 和方法的信息,请参阅本文档新 API 部分中的帐户访问和可发现性

我花了半天时间寻找解决我需要的方法,但没有成功。

我发现信息声称现在访问帐户的唯一方法是像这样使用AccountPicker

AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"},true, null, null, null, null);

但这确实解决了我的问题。需要明确的是,我只需要知道是否存在某种类型的帐户(Google、Samsung...)我不需要知道有多少,也不需要帐户信息。

【问题讨论】:

  • “这不再起作用”是什么意思?您能否提供一些代码、日志或堆栈跟踪,无论您看起来是否相关,以便社区能够为您提供帮助?
  • 我的意思是 getAccount() 方法不再返回帐户数据,除非是链接到应用程序的帐户。
  • 以下是来自官方文档的更多详细信息:在 Android 8.0(API 级别 26)中,应用程序无法再访问用户帐户,除非身份验证器拥有帐户或用户授予该访问权限。
  • @Steeve Favre 你能分享一下这个链接吗?请告诉你如何解决这个问题。
  • 请看我的回答。这就是你让它工作的方式

标签: java android android-8.0-oreo


【解决方案1】:

使用“android.permission.READ_CONTACTS”权限,并且

    Account[] accounts = AccountManager.get(getContext())
.getAccountsByType("com.google") 

在安卓奥利奥中再次工作

【讨论】:

    【解决方案2】:

    正如您已经说过的,如果用户没有授予您这样做的权限,则无法读取其他帐户。现在不仅通过运行时权限提供权限,甚至通过帐户选择器提供权限,即只有当用户在您调用帐户选择器后选择了帐户时,您的应用程序才能看到帐户。这个新限制正是为了避免您尝试做的事情:读取所有用户帐户。您的问题没有解决方案,您唯一能做的就是将选择器呈现给用户并让他选择所有帐户,但这并不是最好的用户体验。

    编辑:从 Google Play Services 11.6 开始,现在有一种新方法 requestGoogleAccountsAccess() 可以获取所有 Google 帐户。

    【讨论】:

    • 正如我所说,我不想阅读有关帐户的任何信息。我只需要知道是否存在某种类型的就够了。但我想你是对的,即使这样也没有解决办法。
    • 我知道这已经晚了,所以我将只为未来的读者发布。了解帐户是否存在仍然是您需要访问才能获取的信息。 IE:用户可能不希望您知道存在哪些帐户,因为帐户的存在本身就是私人信息。
    • @AaronTHarris 请告诉你如何解决这个问题如何从链接的谷歌帐户获取用户名。
    • 请看我的回答。这就是你让它工作的方式
    【解决方案3】:

    使用此代码在运行 Oreo+ (8+) 的设备上获取已安装的 google 帐户

     Account[] accounts = AccountManager.get(getContext()).getAccountsByType("com.google")
    

    你需要先调用

    https://developers.google.com/android/reference/com/google/android/gms/auth/GoogleAuthUtil.html#requestGoogleAccountsAccess(android.content.Context)

    请先添加以下依赖

    com.google.android.gms:play-services-auth:16.0.0
    

    调用requestGoogleAccountsAccess() 引发异常,您可以将其强制转换(检查后)为UserRecoverableAuthException 并从中获取以startActivityForResult 开头的意图

    这是一些示例代码,适用于 Android Oreo

    // call this on a background thread!
    private void requestGoogleAccountAccess() throws Exception
    {
        googleAccountAccessGranted = GoogleAuthUtil.requestGoogleAccountsAccess(this);
        Log.i(TAG, "googleAccountAccessGranted: " + googleAccountAccessGranted);
    }
    
    // exception handler after calling method above
    private void handleAuthResult(Throwable e)
    {
        if (e instanceof UserRecoverableAuthException)
        {
            UserRecoverableAuthException authException = (UserRecoverableAuthException) e;
            startActivityForResult(authException.getIntent(), AUTH_PERMISSION_REQUEST);
        }
        else
        {
            Log.e(TAG, "Cannot request Google Account Access", e);
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
    
        if (requestCode == AUTH_PERMISSION_REQUEST)
        {
            Log.i(TAG, "Google Auth Permission Result");
    
            if (resultCode == Activity.RESULT_CANCELED)
            {
                Log.w(TAG, "User Cancelled Play Services Auth Request.")
            }
            else if (resultCode == Activity.RESULT_OK)
            {
                Log.d(TAG, "User accepted Play Services Auth Request.");
                // call the following line again on a background thread. the call now returns a boolean instead of throwing an exception
                //  googleAccountAccessGranted = GoogleAuthUtil.requestGoogleAccountsAccess(this);
            }
        }
    }
    

    Google 决定采用这种“架构”有点奇怪。为什么不返回任务等。 但这就是你让它工作的方式。

    当然,这段代码需要适当的异常处理,为了便于阅读,我省略了。

    【讨论】:

      猜你喜欢
      • 2018-05-24
      • 2018-08-16
      • 2019-10-01
      • 2018-02-01
      • 1970-01-01
      • 2018-03-09
      • 2019-01-23
      • 1970-01-01
      • 2018-02-10
      相关资源
      最近更新 更多