Android 8.0 Oreo - 帐户

时间:2017-09-29 19:54:59

标签: java android android-8.0-oreo

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

直到Android 7,很容易通过以下方式获取此信息:

angular.element(document.body).injector().get('$state');

但是 Account[] accounts = AccountManager.get(getContext()) .getAccountsByType("com.google") 的事件不再适用了。

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

我花了半天时间找到解决方案来解决我的需求,但没有成功。

我发现信息声称现在访问帐户的唯一方法是使用Oreo,如下所示:

AccountPicker

但这确实可以解决我的问题。需要说明的是,我只需要知道某个类型的帐户是否存在(Google,三星......)我不需要知道多少,如果是这样,也不需要帐户信息。

3 个答案:

答案 0 :(得分:5)

正如您已经说过的,如果用户未授予您许可,则无法阅读其他帐户。现在,权限不仅提供了运行时权限,而且还提供了帐户选择器,即只有在您调用帐户选择器后用户选择了帐户时,您的应用才能看到该帐户。这个新限制正是为了避免您尝试执行的操作:阅读所有用户帐户。您的问题没有解决办法,您唯一能做的就是向用户展示选择器并让他选择所有帐户,而不是最佳用户体验。

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

答案 1 :(得分:4)

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

$nodes[0]->insert_new_elt('before', '#PI' =>'merge  subdocs = 0 :sheet1-01.xml')

再次在android Oreo中工作

答案 2 :(得分:1)

要使用此代码在运行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为何决定采用这种“架构”,这有点奇怪。为什么不返回任务,等等。 但这就是您如何使其工作的方式。

当然,此代码需要适当的异常处理,出于可读性考虑,我将其保留。