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