Вопрос

Я реализую систему входа в приложение для 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 поддерживает постоянная блокировка пробуждения, не позволяя устройству переходить в спящий режим.

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

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

Это было полезно?

Решение 2

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

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

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

  • Внедрить услугу с IntentFilter за android.content.SyncAdapter.
  • Эта услуга должна вернуть IBinder из AbstractThreadedSyncAdapter реализация из его onBind метод
  • Это затем требует, чтобы у вас есть ContentProvider (может быть просто реализация квитанции), которая называется contentAuthority В вашем файле Syncadapter XML.
  • У этого есть вниз, которую ваш ContentProvider указан в заголовке данных и синхронизации на странице настроек вашей учетной записи.

Другие советы

Поскольку это единственный вопрос, связанный с этой проблемой, который я видел, вот ответ, опоздавший на > года.Я также столкнулся с постоянной проблемой блокировки пробуждения из-за того, что система 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. И последнее, но не менее важное: пользователь не сможет включить синхронизацию или использовать кнопку «Синхронизировать сейчас» для этой учетной записи, если вы не добавили эту функциональность в свое приложение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top