java.lang.SecurityException:调用者 uid XXXXX 缺少任何 android.permission.GET_ACCOUNTS

Posted

技术标签:

【中文标题】java.lang.SecurityException:调用者 uid XXXXX 缺少任何 android.permission.GET_ACCOUNTS【英文标题】:java.lang.SecurityException: caller uid XXXXX lacks any of android.permission.GET_ACCOUNTS 【发布时间】:2016-08-19 12:17:37 【问题描述】:

注意:这不是重复的,我在类似的 *** 问题中尝试了很多解决方案,但它们在我的情况下不起作用。感谢您的帮助。

此崩溃似乎只发生在运行早于 6.0 的 android 版本的设备上。例如,它在运行 Android 5.1 版本的 XT1032 上崩溃。在那种情况下,每当我调用这个方法时,在我的 AppCompatActivity 的 onCreate 方法中,

AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);

它崩溃是因为它似乎没有所需的权限(我不知道为什么,因为它在清单中)。我相信它并没有真正进入方法,而是由于@RequiresPermission 行而在进入方法时崩溃:

@RequiresPermission(GET_ACCOUNTS)
    public void addOnAccountsUpdatedListener(final OnAccountsUpdateListener listener,
            Handler handler, boolean updateImmediately)  ...

这是堆栈跟踪,还有一些日志记录代码:

V/AccountManagerService: getAccounts: accountType null, caller's uid 10018, pid 23074
V/AccountManagerService:   caller uid 10018 has android.permission.GET_ACCOUNTS
V/AccountManagerService: getAccounts: accountType null, caller's uid 10018, pid 23074
V/AccountManagerService:   caller uid 10018 has android.permission.GET_ACCOUNTS
V/AccountManagerService:   caller uid 10009 has android.permission.INTERACT_ACROSS_USERS
V/AccountManagerService: getAccounts: accountType com.google, caller's uid 10009, pid 1738
V/AccountManagerService:   caller uid 10009 has android.permission.GET_ACCOUNTS
V/AccountManagerService: getAccounts: accountType null, caller's uid 10018, pid 23074
V/AccountManagerService:   caller uid 10018 has android.permission.GET_ACCOUNTS
V/AccountManagerService: getAccounts: accountType null, caller's uid 10156, pid 13722
W/AccountManagerService:   caller uid 10156 lacks any of android.permission.GET_ACCOUNTS

java.lang.RuntimeException: Unable to start activity ComponentInfoMainActivity: java.lang.SecurityException: caller uid 10156 lacks any of android.permission.GET_ACCOUNTS
                                                                                             at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
                                                                                             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
                                                                                             at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
                                                                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                             at android.os.Looper.loop(Looper.java:135)
                                                                                             at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                                             at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
                                                                                          Caused by: java.lang.SecurityException: caller uid 10156 lacks any of android.permission.GET_ACCOUNTS
                                                                                             at android.os.Parcel.readException(Parcel.java:1546)
                                                                                             at android.os.Parcel.readException(Parcel.java:1499)
                                                                                             at android.accounts.IAccountManager$Stub$Proxy.getAccounts(IAccountManager.java:728)
                                                                                             at android.accounts.AccountManager.getAccounts(AccountManager.java:407)
                                                                                             at android.accounts.AccountManager.addOnAccountsUpdatedListener(AccountManager.java:2372)

调用者的uid是什么,为什么使用uid10156而不是1001810009有权限?

我验证了我的 AuthenticationService 中的帐户类型字符串与authenticator.xml 的帐户类型相同,并且它们都使用硬编码字符串(不是字符串资源)。

public class AuthenticationService extends Service 

    public static final String ACCOUNT_TYPE = "com.mywebsite";
    ...
    public static boolean createAccount(String username,...) 

        AccountManager am = AccountManager.get(Application.getInstance());
        Account account = new Account(username, ACCOUNT_TYPE);

还有我的验证器:

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
                       android:accountType="com.mywebsite"
                       android:icon="@mipmap/ic_launcher"
                       android:smallIcon="@mipmap/ic_launcher"
                       android:label="@string/app_name"
    />

我也有这个: &lt;uses-permission android:name="android.permission.GET_ACCOUNTS" /&gt;&lt;manifest&gt; 标记中,而不是&lt;application&gt; 标记中。清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mywebsite.android.department.departmentname” >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
    <uses-permission android:name="android.permission.READ_LOGS"/>

    <application
        android:name=".Application"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name”>
        <service android:name=".auth.AuthenticationService" >
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator" />
            </intent-filter>

            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/authenticator" />
        </service>

    </application>

</manifest>

这似乎是 Android 文档中的一个线索,但它似乎与我的错误无关,因为我在清单 (http://developer.android.com/reference/android/Manifest.permission.html#GET_ACCOUNTS) 中确实拥有权限:

注意:从 Android 6.0(API 级别 23)开始,如果应用共享 管理帐户的身份验证器的签名,它不 需要“GET_ACCOUNTS”权限才能读取有关该帐户的信息。 在 Android 5.1 及更低版本上,所有应用都需要“GET_ACCOUNTS”权限才能 阅读有关任何帐户的信息。

【问题讨论】:

“调用者 uid 是什么”——它们是应用程序的 Linux 用户 ID (uid),它们调用路由到 AccountManagerService 的某些方法。 “为什么它使用 uid 10156 而不是有权限的 10018 或 10009?” -- 大概,您的应用程序的 uid 为 10156。可能其他 uid 用于设备上的其他应用程序。 好的,我发布了整个清单。谢谢@CommonsWare 试试这个它会工作 API 级别 23 ***.com/a/41221852/5488468 【参考方案1】:

事实证明,与我正在使用的库发生冲突。具体来说,图书馆的支持团队告诉我:

图层 SDK 使用 GET_ACCOUNTS 权限请求 maxSdkVersion 为 18。看起来当清单获取 合并这是覆盖清单中的权限请求, 因此不要求 19 岁以上的许可。

解决方案是从这里更改我的清单:

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

到这里:

<uses-permission android:name="android.permission.GET_ACCOUNTS" tools:node="replace" />

具体来说,添加tools:node="replace"

更多详情,请看我另一个问题的答案:https://***.com/a/37013603/2423194

【讨论】:

以上是关于java.lang.SecurityException:调用者 uid XXXXX 缺少任何 android.permission.GET_ACCOUNTS的主要内容,如果未能解决你的问题,请参考以下文章