Android SyncAdapter Callback - PullRequest
       18

Android SyncAdapter Callback

8 голосов
/ 14 февраля 2012

Я реализовал SyncAdapter, AccountManager и частный ContentProvider в соответствии с примером проекта SimpleSyncAdapter в SDK. Все работает хорошо.

Теперь я хочу показать пользователю сообщение, когда с удаленного сервера были загружены новые строки, для которых установлен определенный флаг. Мне нужен обратный вызов из SyncAdapter после завершения синхронизации, чтобы я мог выполнить запрос и отобразить сообщение из действия. Я видел несколько вопросов о StackOverflow, обсуждающих это, но ни одного с хорошим ответом.

Как можно услышать прогресс от Android SyncAdapter? говорит, что SyncStatusObserver бесполезен. Пользователь mobibob предлагает использовать ResultReceiver для ответа на пользовательский интерфейс из потока синхронизации.

Как узнать, когда синхронизация завершена? предлагает использовать Intent в вашем SyncService.

Как передать сигнал завершения синхронизации в Android SyncManager? предлагает использовать SyncResult. Пример кода, на который ссылается maxpower47, использует класс SyncResult для сообщения об исключениях, но не для того, чтобы фактически сообщать об успешном завершении синхронизации.

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

Ответы [ 3 ]

2 голосов
/ 19 апреля 2014

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

registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)

Регистрирует класс наблюдателя, который получает обратный вызов при изменении данных, идентифицированных данным URI контента. Но это может произойти, только если ваш ContentProvider отправит уведомление. Например, если вы хотите получать уведомления на вышеупомянутом ContentObserver обо всех обновлениях, выполненных в вашей базе данных через ContentProvider, ваш ContentProvider должен реализовать обновление, подобное следующему:

@Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
    // code goes here
    this.getContext().getContentResolver().notifyChange(uri, null);
    return 0;
}

Использование notifyForDescendents при выполнении registerContentObserver может быть очень полезным.

1 голос
/ 16 января 2015

Это старый вопрос, но я провел некоторое исследование в последние дни, и не так много примеров использования syncAdapter для обработки сетевых запросов и уведомления пользовательского интерфейса.

Сначала вам следует использовать Loaders with contentProvider, чтобы сделать свою жизньПолегче.Вам больше не нужно регистрироваться для распознавания контента, загрузчик делает это за вас.Таким образом, это означает, что ваш пользовательский интерфейс получает уведомление обо всем, что поступает на ваш контент-провайдер.

Что делать, если ничего не изменилось?все обновлено или у вас произошла сетевая ошибка.

  1. Вы можете прослушивать состояние вашего syncAdapter, как это делает приложение ввода-вывода Google, выполнить поиск mSyncStatusObserver в BaseActivity * 1009.*
  2. Я посмотрел на приложение электронной почты по умолчанию для Android, и они используют Singleton с callBacks.
  3. Вы можете BroadcastIntents или использовать eventBus (квадратный Otto для примера)чтобы уведомить ваш пользовательский интерфейс о любом поведении.

Мне больше нравится последний, потому что он дает вам больше детализации событий, происходящих в syncAdapter.

0 голосов
/ 21 мая 2016

Мы столкнулись с подобной ситуацией и написали интерфейс статического прослушивателя для SyncAdapter. Слушатель является действием и выполняет необходимые действия, когда данные доступны (обновление пользовательского интерфейса). Это также работает, когда адаптер синхронизации вызывается системой во время автосинхронизации, когда этот прослушиватель будет нулевым, а процесс синхронизации будет заниматься своими делами.

class SyncAdapter extends AbstractThreadedSyncAdapter {

    protected static Listener uiListener = null;
    public interface Listener {
        public void onSync();
    }
    public static void setListener(Listener l) {
        uiListener = l;
    }
    public static void clearListener() {
        uiListener = null;
    }
    protected void broadcastSync() {
        if (uiListener != null)
            uiListener.onSync();
    }
    public void onPerformSync(Account account, Bundle extras, String authority,
                          ContentProviderClient provider, SyncResult syncResult) {

         // call broadcastSync();
    }

Затем в Activity выполните интерфейс SyncAdapter.Listener.

...