Android M 6.0 - SecurityException试图删除帐户

时间:2015-09-28 06:42:18

标签: android permissions android-6.0-marshmallow android-account android-securityexception

我有一个使用Android AccountManager的应用程序(包名:com.mycompany.accounts),它将帐户添加到设备并提供登录屏幕。我有另一个应用程序(com.mycomp.actualapp),它使用第一个应用程序添加/删除帐户。

我可以使用清单中的以下权限在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$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)

奇怪的是,这个代码在Pre Marshmallow设备上运行正常,没有任何问题。

在旁注中,我注意到使用sdk 22进行编译并且定位22:转到“设置&gt;应用&gt;我的应用(com.mycomp.actualapp)&gt;权限”我只看到两个权限,“电话” “存储”。

我注意到使用sdk 23进行编译并且定位23:我看到三个权限,“电话”,“存储”和“联系人”。

我尝试了以下内容:

  • 切换到使用sdk 23编译 - 在应用设置中授予所有权限,再次尝试删除帐户。仍然失败,但同样的例外。

  • 使用22进行编译并将以下权限添加到清单中。确保授予所有权限。仍然失败,但同样的例外:

    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>

我可以在没有其他权限授予的情况下获取用户帐户的用户名和令牌,但删除帐户不起作用。 我真的很感激任何帮助!

4 个答案:

答案 0 :(得分:1)

我知道这已经很晚才回答,但我想我会分享我的调查结果以防其他人处于相同的情况。

我将构建版本升级为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进行编译的更多信息:如果应用程序共享管理帐户的身份验证器的签名,则不需要请求权限。在这种情况下,我的签名没有匹配,所以我确实需要请求它。如果您在应用中创建了一个帐户,以便在您的应用中使用,则无需在运行时请求权限

答案 1 :(得分:0)

昨天我突然陷入了同样的困境。 就我而言,我在节点中定义了错误的包名称。 只需修复它就能完美运行。

<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

答案 2 :(得分:0)

对于棉花糖,您需要添加运行时用户权限。 你可以查看这个网址

https://stackoverflow.com/a/37669861/4549220

答案 3 :(得分:0)

签入源代码,您可以在两种情况下删除帐户:

  1. 该帐户是由您的应用创建的
  2. 您的应用是系统应用

来源:https://android.googlesource.com/platform/frameworks/base/+/05c9ecc/services/core/java/com/android/server/accounts/AccountManagerService.java#1336