Roc*_*Lee 1 android android-securityexception
注意:这不是重复的,我在类似的StackOverflow问题中尝试了很多解决方案,但在我的情况下它们不起作用。感谢您的任何帮助。
只有在运行Android 6.0之前的版本的设备上才会发生此崩溃。例如,它在运行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) { ...
Run Code Online (Sandbox Code Playgroud)
这是堆栈跟踪,还有更多的日志记录代码:
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 ComponentInfo{MainActivity}: 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)
Run Code Online (Sandbox Code Playgroud)
什么是来电者的UID,和为什么它采用流体10156代替10018或10009具有的权限?
我验证了我在AuthenticationService中的帐户类型字符串与authenticator.xml的accountType相同,并且它们都使用了硬编码的字符串(不是String资源)。
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);
Run Code Online (Sandbox Code Playgroud)
而我的身份验证者:
<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"
/>
Run Code Online (Sandbox Code Playgroud)
我也有这个:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
在<manifest>标签中,而不是<application>标签中。表现:
<?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>
Run Code Online (Sandbox Code Playgroud)
这似乎是Android文档中的一条线索,但似乎与我的错误没有关联,因为清单中确实有我的权限(http://developer.android.com/reference/android/Manifest.permission。 html#GET_ACCOUNTS):
注意:从Android 6.0(API级别23)开始,如果应用共享管理帐户的身份验证器的签名,则无需“ GET_ACCOUNTS”权限即可读取有关该帐户的信息。在Android 5.1及更低版本上,所有应用都需要具有“ GET_ACCOUNTS”权限才能读取有关任何帐户的信息。
事实证明,我使用的库存在冲突。具体来说,图书馆的支持团队告诉我:
层SDK使用maxSdkVersion为18来请求GET_ACCOUNTS权限。看来,合并清单时,这会覆盖清单中的权限请求,因此不会为19+请求该权限。
解决的办法是从此更改我的清单:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Run Code Online (Sandbox Code Playgroud)
对此:
<uses-permission android:name="android.permission.GET_ACCOUNTS" tools:node="replace" />
Run Code Online (Sandbox Code Playgroud)
具体来说,添加tools:node="replace"。
有关更多详细信息,请参见我的其他问题的答案:https : //stackoverflow.com/a/37013603/2423194