Android M 6.0 - SecurityException 试图删除帐户
Android M 6.0 - SecurityException Trying to remove accounts
我有一个使用 Android AccountManager(程序包名称:com.mycompany.accounts)的应用程序,可将帐户添加到设备并提供登录屏幕。我有另一个应用程序 (com.mycomp.actualapp),它使用第一个应用程序到 add/remove 个帐户。
我可以使用清单中的以下权限在 Pre Marshmallow 设备上成功添加和删除帐户:
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
使用 sdk 22 编译并以 sdk 22 为目标时,应自动授予这些权限。以下代码:
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);
失败,出现以下异常:
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.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.doInBackground(LoginHelper.java:282)
at com.mycomp.actualapputils.LoginHelper.doInBackground(LoginHelper.java:242)
at android.os.AsyncTask.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)
奇怪的是,这段代码在 Marshmallow 之前的设备上运行良好,没有任何问题。
附带说明一下,我注意到使用 sdk 22 和目标 22 进行编译:转到 "Settings > Apps > My app(com.mycomp.actualapp) > Permissions" 我只看到两个权限,"Phone" "Storage"。
我注意到使用 sdk 23 和目标 23 进行编译:我看到三个权限,"Phone"、"Storage" 和 "Contacts"。
我试过以下方法:
切换到使用 sdk 23 编译 - 在应用程序设置中授予所有权限,再次尝试删除帐户。仍然失败并出现相同的异常。
用22编译,在manifest中添加如下权限。确保授予所有权限。仍然失败并出现相同的异常:
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
我能够在没有额外权限授予的情况下获取用户帐户用户名和令牌,但是删除帐户不起作用。
如果有任何帮助,我将不胜感激!
昨天我突然卡在了同样的事情上。
就我而言,我在节点中定义了错误的包名称。
只需修复它,它就会完美运行。
<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>
如果您的包裹名称是:
com.example.android
那么账户类型应该是:com.example.android.accounts
我知道回答这个问题已经晚了,但我想我会分享我的发现,以防其他人遇到同样的情况。
我将我的构建升级为使用 23 而不是 22 构建,因为我无法在 22 上解决它。然后我在运行时明确请求权限 到 GET_ACCOUNTS 在尝试对它们做任何事情之前。
https://developer.android.com/training/permissions/requesting.html
https://developer.android.com/reference/android/Manifest.permission.html#GET_ACCOUNTS
有关使用 23 进行编译的更多信息:如果应用共享管理帐户的验证器的签名,您不需要请求许可。在这种情况下,我的签名不匹配,所以我确实需要请求它。如果您在您的应用程序中创建要在您的应用程序中使用的帐户,您不需要在运行时请求权限。
查看源码,有两种情况可以removeAccounts:
- 该帐户是由您的应用创建的
- 您的应用是系统应用
我有一个使用 Android AccountManager(程序包名称:com.mycompany.accounts)的应用程序,可将帐户添加到设备并提供登录屏幕。我有另一个应用程序 (com.mycomp.actualapp),它使用第一个应用程序到 add/remove 个帐户。
我可以使用清单中的以下权限在 Pre Marshmallow 设备上成功添加和删除帐户:
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
使用 sdk 22 编译并以 sdk 22 为目标时,应自动授予这些权限。以下代码:
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);
失败,出现以下异常:
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.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.doInBackground(LoginHelper.java:282)
at com.mycomp.actualapputils.LoginHelper.doInBackground(LoginHelper.java:242)
at android.os.AsyncTask.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)
奇怪的是,这段代码在 Marshmallow 之前的设备上运行良好,没有任何问题。
附带说明一下,我注意到使用 sdk 22 和目标 22 进行编译:转到 "Settings > Apps > My app(com.mycomp.actualapp) > Permissions" 我只看到两个权限,"Phone" "Storage"。
我注意到使用 sdk 23 和目标 23 进行编译:我看到三个权限,"Phone"、"Storage" 和 "Contacts"。
我试过以下方法:
切换到使用 sdk 23 编译 - 在应用程序设置中授予所有权限,再次尝试删除帐户。仍然失败并出现相同的异常。
用22编译,在manifest中添加如下权限。确保授予所有权限。仍然失败并出现相同的异常:
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
我能够在没有额外权限授予的情况下获取用户帐户用户名和令牌,但是删除帐户不起作用。 如果有任何帮助,我将不胜感激!
昨天我突然卡在了同样的事情上。 就我而言,我在节点中定义了错误的包名称。 只需修复它,它就会完美运行。
<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>
如果您的包裹名称是:
com.example.android
那么账户类型应该是:com.example.android.accounts
我知道回答这个问题已经晚了,但我想我会分享我的发现,以防其他人遇到同样的情况。
我将我的构建升级为使用 23 而不是 22 构建,因为我无法在 22 上解决它。然后我在运行时明确请求权限 到 GET_ACCOUNTS 在尝试对它们做任何事情之前。 https://developer.android.com/training/permissions/requesting.html https://developer.android.com/reference/android/Manifest.permission.html#GET_ACCOUNTS
有关使用 23 进行编译的更多信息:如果应用共享管理帐户的验证器的签名,您不需要请求许可。在这种情况下,我的签名不匹配,所以我确实需要请求它。如果您在您的应用程序中创建要在您的应用程序中使用的帐户,您不需要在运行时请求权限。
查看源码,有两种情况可以removeAccounts:
- 该帐户是由您的应用创建的
- 您的应用是系统应用