Android SecurityException:调用方uid XXXX与身份验证程序';液体

Android SecurityException:调用方uid XXXX与身份验证程序';液体,android,Android,我在尝试实现示例同步适配器应用程序时收到上述异常。我看到过许多与这个问题相关的帖子,但没有令人满意的回复 因此,我将在这里记下,以防其他人也遇到同样的问题。首先,检查以下说明的条件: […]如果您看到表单调用方uid XXXX的AccountManagerService中的错误与验证器的uid不同,则可能有点误导。该消息中的“authenticator”不是您的authenticator类,而是Android理解为帐户类型的注册验证器。AccountManagerService中发生的检查如下所

我在尝试实现示例同步适配器应用程序时收到上述异常。我看到过许多与这个问题相关的帖子,但没有令人满意的回复


因此,我将在这里记下,以防其他人也遇到同样的问题。

首先,检查以下说明的条件:

[…]如果您看到表单
调用方uid XXXX的
AccountManagerService
中的错误与验证器的uid
不同,则可能有点误导。该消息中的“authenticator”不是您的authenticator类,而是Android理解为帐户类型的注册验证器。
AccountManagerService
中发生的检查如下所示:

 private void checkCallingUidAgainstAuthenticator(Account account) {
     final int uid = Binder.getCallingUid();
     if (account == null || !hasAuthenticatorUid(account.type, uid)) {
         String msg = "caller uid " + uid + " is different than the authenticator's uid";
         Log.w(TAG, msg);
         throw new SecurityException(msg);
     }
     if (Log.isLoggable(TAG, Log.VERBOSE)) {
         Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid");
     }
 }
V/AccountManagerService: initiating bind to authenticator type com.example.account
V/Accounts: there is no service connection for com.example.account
V/Accounts: there is no authenticator for com.example.account, bailing out
D/AccountManagerService: bind attempt failed for Session: expectLaunch true, connected false, stats (0/0/0), lifetime 0.002, addAccount, accountType com.example.account, requiredFeatures null
请注意,
hassauthenticatoruid()
接受
帐户。键入
。这就是我搞砸的地方。我正在使用常数指定的类型创建我的
帐户

 class LoginTask {
     Account account = new Account(userId, AuthenticatorService.ACCOUNT_TYPE);
     ...
 }

 class AuthenticatorService extends Service {
     public static final String ACCOUNT_TYPE = "com.joelapenna.foursquared";
     ...
 }
但该常量与验证器的XML定义不匹配:

 <account-authenticator xmlns:android="/web/20150729061818/http://schemas.android.com/apk/res/android"
        android:accountType="com.joelapenna.foursquared.account" ... />


其次,如果您和我一样,希望将示例嵌入现有的应用程序中进行测试,请确保使用本示例中的
Constants
类,而不是在
android.provider.SyncStateContract
包下。因为这两个类使用相同的属性名
ACCOUNT\u TYPE
,在创建
ACCOUNT
对象时使用该属性名。

一些其他有用的技巧来调试类似的问题

首先为某些标记启用详细日志记录:

$ adb shell setprop log.tag.AccountManagerService VERBOSE
$ adb shell setprop log.tag.Accounts VERBOSE
$ adb shell setprop log.tag.Account VERBOSE
$ adb shell setprop log.tag.PackageManager VERBOSE
您将看到这样的日志记录:

 private void checkCallingUidAgainstAuthenticator(Account account) {
     final int uid = Binder.getCallingUid();
     if (account == null || !hasAuthenticatorUid(account.type, uid)) {
         String msg = "caller uid " + uid + " is different than the authenticator's uid";
         Log.w(TAG, msg);
         throw new SecurityException(msg);
     }
     if (Log.isLoggable(TAG, Log.VERBOSE)) {
         Log.v(TAG, "caller uid " + uid + " is the same as the authenticator's uid");
     }
 }
V/AccountManagerService: initiating bind to authenticator type com.example.account
V/Accounts: there is no service connection for com.example.account
V/Accounts: there is no authenticator for com.example.account, bailing out
D/AccountManagerService: bind attempt failed for Session: expectLaunch true, connected false, stats (0/0/0), lifetime 0.002, addAccount, accountType com.example.account, requiredFeatures null
这意味着没有为此帐户类型注册身份验证程序。要查看注册了哪些身份验证程序,请在安装包时查看日志:

D/PackageManager: encountered new type: ServiceInfo: AuthenticatorDescription {type=com.example.account}, ComponentInfo{com.example/com.example.android.AuthenticatorService}, uid 10028
D/PackageManager: notifyListener: AuthenticatorDescription {type=com.example.account} is added
我遇到的问题是,验证器xml描述符引用的字符串资源在安装过程中没有得到正确解决:

android:accountType="@string/account_type"
日志显示

encountered new type: ServiceInfo: AuthenticatorDescription {type=@2131231194}, ...
用普通字符串(不是资源)替换它解决了问题。这似乎是Android 2.1特有的

android:accountType="com.example.account"
而且

检查是否将AccountType视为一个普通的旧字符串

我的大部分代码都打包在com.mycompany.android下

我成功地使用了以下AccountType:com.mycompany.android.ACCOUNT

现在我想使用多个帐户,当我尝试在我的帐户末尾附加“.subType”的方法时,它失败了

调用方uid xxxxx与身份验证器的uid不同

但是,如果我使用“_subType”(下划线而不是点),它可以正常工作

我的猜测是,安卓正在试图将com.mycompany.Android.ACCOUNT视为一个合法的软件包名称,但事实肯定并非如此

因此,再一次:

com.mycompany.android.ACCOUNT.subType


com.mycompany.android.ACCOUNT\u子类型

我的错误是假定AccountManager getAccounts()方法返回的帐户仅与我的应用程序上下文关联。我从

AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccounts();


确保您的服务XML指向正确的位置

例如,如果您正在使用模块名

com.example.module.auth

你是安卓服务:名字应该是

<service android:name=".module.auth.name-of-authenticator-service-class"...

还要确保AccountAuthenticatorService具有验证目的过滤器


实现自定义帐户的部分很少

要在活动中调用AccountManager,您已经实现了类似的功能

Account account = new Account(username, ACCESS_TYPE);
AccountManager am = AccountManager.get(this);
Bundle userdata = new Bundle();
userdata.putString("SERVER", "extra");

if (am.addAccountExplicitly(account, password, userdata)) {
    Bundle result = new Bundle();
    result.putString(AccountManager.KEY_ACCOUNT_NAME, username);
    result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCESS_TYPE);
    setAccountAuthenticatorResult(result);
}
在res/xml/authenticator.xml中,必须定义AccountAuthenticator数据(负责验证器UID)。访问类型必须与此xml中定义的accountType相同

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="de.buecherkiste"
    android:icon="@drawable/buecher"
    android:label="@string/app_name"
    android:smallIcon="@drawable/buecher" >
</account-authenticator>

最后,您必须定义您的服务和清单。请不要忘记管理您的帐户的相关权限(验证\u帐户/使用\u凭据/获取\u帐户/管理\u帐户)


在我的例子中,问题很简单,就是在
res/xml/authenticator.xml
中声明为
android:accountType=“com.foo”
的accountType不匹配,但在创建帐户时被错误地引用为
“foo.com”

Account newAccount = new Account("dummyaccount", "foo.com");

如果在清单中的意图过滤器中输入了不正确的值,则会出现相同的错误。 我阅读了关于同步适配器的android开发教程,最后为syncadapter/accountauthenticator的“intent filter/action android:name”和“meta data/android:name”设置了一个虚假值。此错误导致相同的错误出现在日志中


对于记录,正确的值是:{android.content.SyncAdapter,android.accounts.AccountAuthenticator}

首先,再看看Jan Berkel的优秀调试建议

最后,要检查的另一件事是,您的内容提供商、身份验证和同步服务被声明为
应用程序
标记的子项

    <application
        ...>
        <activity
            ...(Activity)...
        </activity>
        <provider
            ...(CP service declaration)/>

        <service
            ...(Authentication service declaration)...
        </service>

        <service
            ...(Sync service declaration)... 
        </service>
    </application>


如果您遇到此错误,并且上述所有解决方案都不适用于您。另外,您假设您已经遵循了所有的过程。身份验证服务可能是由其他开发人员开发的,您希望利用这些开发人员添加帐户


您可以尝试使用发布密钥库对应用程序进行签名。现在运行应用程序。我想这应该对你有用。

对我来说,这是一个非常愚蠢的错误,很难找到

在authenticator.xml中,我编写了

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

xmlns:android=”http://schemas.android.com/apk/res/android"
android:accountType=“com.myapp”
android:icon=“@drawable/ic_启动器”
android:smallIcon=“@drawable/ic_启动器”
android:label=“@string/app\u name”
/>
而不是

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

这是什么引起的
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.myapp"
android:icon="@drawable/ic_launcher"
android:smallIcon="@drawable/ic_launcher"
android:label="@string/app_name"
/>
<uses-permission android:name="ANDROID.PERMISSION.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
public Account findAccount(String accountName) {
    for (Account account : accountManager.getAccounts())
        if (TextUtils.equals(account.name, accountName) && TextUtils.equals(account.type, "myservice.com"))
            return account;
    return null;
}