问题
I have an app that uses Android AccountManager (package name: com.mycompany.accounts), that adds accounts to the device and provides a login screen. I have another app (com.mycomp.actualapp), that uses the first app to add/remove accounts.
I can successfully add and remove accounts on Pre Marshmallow devices, using the following permissions in the manifest:
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
When compiling with sdk 22 and targetting sdk 22, these permissions should be automatically granted. The following code:
accountManager.removeAccount(getAccount(), activity, new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
try {
Bundle bundle = accountManagerFuture.getResult();
boolean success = bundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
if (success) {
Toast.makeText(activity, activity.getString(R.string.successfully_loggedout), Toast.LENGTH_LONG).show();
afterLogoutSuccess(activity);
} else {
Toast.makeText(activity.getApplicationContext(), activity.getString(R.string.failed_to_logout), Toast.LENGTH_LONG).show();
}
onLogoutListener.onLogoutFinished(success);
return;
} catch (OperationCanceledException e) {
Log.e(TAG,"Operation cancelled exception:", e);
} catch (IOException e) {
Log.e(TAG, "IOException:", e);
} catch (AuthenticatorException e) {
Log.e(TAG, "AuthenticatorException:", e);
}
onLogoutListener.onLogoutFinished(false);
}
}, null);
Fails with the following exception:
java.lang.SecurityException: uid 10057 cannot remove accounts of type: com.mycompany.accounts
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at android.accounts.IAccountManager$Stub$Proxy.removeAccount(IAccountManager.java:897)
at android.accounts.AccountManager$7.doWork(AccountManager.java:900)
at android.accounts.AccountManager$AmsTask.start(AccountManager.java:1888)
at android.accounts.AccountManager.removeAccount(AccountManager.java:897)
at com.mycomp.actualapp.utils.LoginHelper$4.doInBackground(LoginHelper.java:282)
at com.mycomp.actualapputils.LoginHelper$4.doInBackground(LoginHelper.java:242)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
The strange thing, is that this code runs fine on Pre Marshmallow devices without any issues.
On a side note, I noticed that compiling with sdk 22 and targeting 22: Going to "Settings > Apps > My app(com.mycomp.actualapp) > Permissions" I see only two permissions, "Phone" "Storage".
I noticed that compiling with sdk 23 and targeting 23: I see three permissions, "Phone", "Storage" and "Contacts".
I have tried the following:
Switching to compile with sdk 23 - grant all permissions in app settings, try remove account again. Still fails with the same exception.
Compile with 22 and add the following permissions to the manifest. Make sure all permissions are granted. Still fails with the same exception:
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
I am able to get the users account username and token without additional permission granting, but the removing of accounts doesn't work. I would really appreciate any help!
回答1:
I know this is late to answer but I thought I would share my findings in case anyone else is in the same situation.
I upgraded my build to build with 23 instead of 22 as I couldn't solve it on 22. Then I explicitly asking for the permission at runtime to GET_ACCOUNTS before trying to do anything with them. https://developer.android.com/training/permissions/requesting.html https://developer.android.com/reference/android/Manifest.permission.html#GET_ACCOUNTS
Further information for compiling with 23: You don't need to ask permission if the app shares the signature of the authenticator that manages an account. In this case, my signatures didn't match so I did need to request it. If you create an account within your app to be used within your app, you do not need to request permission at runtime.
回答2:
I suddenly was stuck in the same thing yesterday. In my case, I defined wrong package name in node. Just fix it and it will work perfectly.
<account-authenticator>
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="Your correct packet name here" + ".accounts"
android:icon="@drawable/ic_launcher"
android:label="xxx"
android:smallIcon="@drawable/ic_launcher"
>
</account-authenticator>
If your package name is:
com.example.android
then the account type should be: com.example.android.accounts
回答3:
Checking in the source code, you can removeAccounts in two cases:
- the account is created by your app
- your app is a system app
Source: https://android.googlesource.com/platform/frameworks/base/+/05c9ecc/services/core/java/com/android/server/accounts/AccountManagerService.java#1336
来源:https://stackoverflow.com/questions/32817053/android-m-6-0-securityexception-trying-to-remove-accounts