Android M 6.0 - 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: переходя в «Настройки> Приложения> Мое приложение (com.mycomp.actualapp)> Разрешения», я вижу только два разрешения: «Телефон» «Хранилище».

Я заметил, что при компиляции с 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"/>

Я могу получить имя пользователя и токен учетной записи пользователя без предоставления дополнительных разрешений, но удаление учетных записей не работает. Я был бы очень признателен за любую помощь!


comment
Вы смогли решить ее за это время?   -  person André Lemos    schedule 02.09.2016


Ответы (3)


Я знаю, что уже поздно отвечать, но я подумал, что поделюсь своими выводами на случай, если кто-то еще окажется в такой же ситуации.

Я обновил свою сборку до сборки с 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: вам не нужно спрашивать разрешения, если приложение использует подпись аутентификатора, который управляет учетной записью. В этом случае мои подписи не совпадали, поэтому мне нужно было это запросить. Если вы создаете учетную запись в своем приложении для использования в своем приложении, вам не нужно запрашивать разрешение во время выполнения.

person riggaroo    schedule 31.12.2016
comment
Как запросить подпись, если она не совпадает с тем, что есть в вашем приложении? - person niczm25; 18.07.2018
comment
Потому что я немного запутался в том, о какой подписи в документации в AccountManager идет речь? Этот метод требует, чтобы у вызывающего объекта была совпадающая подпись с аутентификатором, которому принадлежит указанная учетная запись. - person niczm25; 18.07.2018

Я внезапно застрял в том же самом вчера. В моем случае я определил неправильное имя пакета в node. Просто исправьте это, и все будет работать идеально.

<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

person Hoang Nguyen Huu    schedule 22.07.2016

Проверяя исходный код, вы можете удалить учетные записи в двух случаях:

  1. учетная запись создается вашим приложением
  2. ваше приложение является системным приложением

Источник: https://android.googlesource.com/platform/frameworks/base/+/05c9ecc/services/core/java/com/android/server/accounts/AccountManagerService.java#1336

person Saba    schedule 09.08.2019