Как реализовать учетную запись на Android без SyncAdapter - PullRequest
9 голосов
/ 19 марта 2011

Я внедряю систему входа в систему для приложения Android, используя встроенную систему учетных записей (с API AccountManager).

Все хорошо на Android 2.2+, но на Android 2.1 без SyncAdapter вызывает перезагрузки на экране настроек учетной записи (см. http://code.google.com/p/android/issues/detail?id=5009 и AccountManager без SyncAdapter? )

Чтобы обойти это, я реализовал заглушку SyncAdapter, которая просто возвращает null из IBinder onBind(Intent intent), и добавил соответствующие вещи в манифест. Это решает проблему перезагрузки на Android 2.1.

Однако это создает еще одну проблему: после добавления учетной записи система Android через некоторое время инициирует синхронизацию учетной записи. Хотя никаких ошибок не происходит (действительно, мой SyncAdapter ничего не делает, он не может вызвать ошибки, если только не возвращает null), значок синхронизации остается застрявшим в панели уведомлений вверху. Это приводит к тому, что система синхронизации Android поддерживает постоянный wake-lock , не позволяющий устройству спать.

Учетная запись не отображает никаких синхронизируемых компонентов на экране настроек учетной записи (под заголовком «Данные и синхронизация») и всегда отображает «Синхронизация отключена» для состояния синхронизации в списке учетных записей (даже при значке синхронизации). виден в панели уведомлений). Отключение синхронизации учетной записи не устраняет проблему. Удаление учетной записи останавливает проблему.

Мне кажется, я не должен возвращать ноль. Должен ли я возвращать базовую реализацию ThreadedSyncAdapter? Мы очень ценим любую помощь в создании системы учетных записей без соответствующей синхронизации на 2.1 и 2.2+.

Ответы [ 2 ]

6 голосов
/ 07 ноября 2012

Так как это единственный вопрос, который я видел, связанный с этой проблемой, вот ответ с> поздним опозданием.Я также столкнулся с проблемой постоянной блокировки из-за того, что система Android автоматически синхронизировала мою учетную запись.

Лучший способ справиться с этим, который требует минимального кода и фактически делает его таким, чтобы учетная запись никогда не синхронизировалась, если не был специально вызван для синхронизации в коде:

ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);

Теперь для этого требуется моментсоздать свою учетную запись вы называете этот статический метод.Принимая во внимание, что первый параметр - это учетная запись, для которой устанавливается этот параметр, второй параметр - это полномочия используемого контент-провайдера, а третий - целое число, которое при задании положительного числа включает синхронизацию, когда при значении 0 отключается синхронизация, а при задании чего-либо ещеделает это неизвестным.Полномочия для использования могут быть найдены внутри вашего "sync_something.xml" в атрибуте contentAuthority, который используется вашим SyncAdapter:

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.android.contacts" 
android:accountType="com.myapp.account"/> <!-- This being your own account type-->

Указанный выше файл xml указан внутри служебной части вашего AndroidManifest.xml:

<service android:name=".DummySyncAdapterService"
        exported="true"
        android:process=":contacts">
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <meta-data android:name="android.content.SyncAdapter" 
            android:resource="@xml/sync_something" /> <!--This points to your SyncAdapter XML-->
    </service>

Это фрагмент кода, который я использую для создания своей учетной записи внутри моей учетной записи LoginActivity:

Account account = new Account("John Doe", "com.myapp.account");
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);
AccountManager am = AccountManager.get(LoginActivity.this);
boolean accountCreated = am.addAccountExplicitly(account, "Password", null);
Bundle extras = LoginActivity.this.getIntent().getExtras();
if(extras != null){
    if (accountCreated) { 
        AccountAuthenticatorResponse response = extras.getParcelable(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
        Bundle result = new Bundle();
        result.putString(AccountManager.KEY_ACCOUNT_NAME, "John Doe");
        result.putString(AccountManager.KEY_ACCOUNT_TYPE, "com.myapp.account");
        response.onResult(result);
    }
}

Большая часть этого заключается в том, что когда система пытается синхронизировать службу, он проверяет, является ли служба синхронизируемой в первую очередь, если она установлена ​​в false, она отменяет синхронизацию.Теперь вам не нужно создавать свой собственный ContentProvider, а ваш ContentProvider не отображается в разделе «Данные и синхронизация». Однако вам нужно иметь реализацию-заглушку AbstractThreadedSyncAdapter, которая возвращает IBinder внутри его метода onBind. И, наконец, что не менее важно, он делает так, чтобы пользователь не мог включить синхронизацию или использовать «Синхронизировать сейчас»кнопка для этой учетной записи, если вы не добавили функциональность в свое приложение.

2 голосов
/ 21 марта 2011

Я вроде решил свою собственную проблему: вы не можете вернуть null из метода onBind вашего сервиса - вы должны вернуть IBinder из AbstractThreadedSyncAdapter.

Это приводит к нежелательному добавлению записи в раздел «Данные и синхронизация» на странице настроек учетной записи, хотя моя реализация AbstractThreadedSyncAdapter ничего не делает; Я надеялся избежать этого.

Подводя итог, чтобы использовать систему учетных записей в Android, необходимо:

  • Реализация службы, которая имеет IntentFilter для android.content.SyncAdapter.
  • Эта служба должна возвращать IBinder реализации AbstractThreadedSyncAdapter из своего метода onBind.
  • Тогда необходимо, чтобы у вас была ContentProvider (может быть просто реализация-заглушка), которая в вашем XML-файле SyncAdapter называется contentAuthority.
  • Недостатком является то, что ваш ContentProvider указан в заголовке «Данные и синхронизация» на странице настроек вашей учетной записи.
...