Кто-нибудь реализовал (или получил больше информации) на Android SyncObserver - PullRequest
5 голосов
/ 31 марта 2011

Я занимаюсь разработкой приложения для Android, которое выполняет фоновую синхронизацию с сервером (используя SyncAdapter, аутентификацию и т. Д.).

Когда запускается приложение переднего плана (с пользовательским интерфейсом), возможно, выполняется фоновая синхронизация или, возможно, она запускается с помощью кнопки пользовательского интерфейса.

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

В документации ContentResolver (http://developer.android.com/reference/android/content/ContentResolver.html) упоминается загадочный "SyncObserver", который не имеет ссылки на javadoc и не задокументирован (что я могу найти).

Вокруг него есть и другие страницы, на которых упоминается (http://www.chinaup.org/docs/migrating/m5-0.9/changes/android.content.ContentResolver.html), но я не могу узнать больше об этом.

Кто-нибудь реализовал этого зверя?

Если нет, есть ли у кого-нибудь пример кода или рекомендации по отслеживанию хода фоновой синхронизации на переднем плане Упражнение?

Ответы [ 2 ]

5 голосов
/ 06 июня 2011

Спасибо за ответ.

Из-за асинхронного характера фоновой синхронизации ваше приложение (действие) может быть запущено с уже запущенной фоновой синхронизацией, которую вы обнаруживаете со статусом, сохраненным в предпочтении.

Что я сделал, так это реализовал класс SyncObserver, который реализует интерфейс SyncStatusObserver, и создал / уничтожил при приостановке / возобновлении.

syncObserverHandle = ContentResolver.addStatusChangeListener( ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, new SyncObserver() );

Он получает информацию о любом событии, связанном с синхронизацией (ожидание, запуск и т. Д.), И я также проверяю статус с помощью

ContentResolver.isSyncActive();

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

3 голосов
/ 25 мая 2011

У меня была такая же проблема, и в итоге я реализовал ее с помощью комбинации 1) трансляции из SyncAdapter и 2) использования SharedPreferences для индикации состояния.

В SyncAdapter, что-то вроде этого:

public static final String START_SYNC = "com.whatever.sync.start";
public static final String STOP_SYNC = "com.whatever.sync.stop";
public static final String SYNC_PROGRESS = "syncProgress";


public void onPerformSync(Account account, Bundle extras, String authority,
    ContentProviderClient provider, SyncResult syncResult) {

        // Add an integer to the shared settings to indicate the status
        SharedPreferences settings = mContext.getSharedPreferences(Constants.PREFS, 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putInt(SyncAdapter.SYNC_PROGRESS, 0);
        editor.commit();

        Intent intent = new Intent();
        intent.setAction(START_SYNC);
        mContext.sendBroadcast(intent);


        //... do some stuff, setting SYNC_PROGRESS to other values and
        // sending more broadcasts as the state changes

        // When we are done, remove the "in progress" setting and store some
        // other data
        editor.putString(SyncAdapter.LAST_UPDATED, new Date().toString());
        editor.remove(SyncAdapter.SYNC_PROGRESS);
        editor.commit();

        Intent stopIntent = new Intent();
        stopIntent.setAction(STOP_SYNC);
        mContext.sendBroadcast(stopIntent); 
      }

В упражнении мы делаем две вещи в резюме: 1) проверяем общее предпочтение на предмет того, выполняется ли синхронизация в данный момент, 2) регистрируем для прослушивания передач с получателем.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// .. do some UI stuff

    mReceiver = new SyncReceiver(this);
}

@Override
public void onResume() {
    super.onResume();

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(SyncAdapter.START_SYNC);
    intentFilter.addAction(SyncAdapter.STOP_SYNC);
    registerReceiver(mReceiver, intentFilter);  

    showProgress();
}

public void showProgress() {
    SharedPreferences settings = getSharedPreferences(Constants.PREFS, 0);
    if (settings.contains(SyncAdapter.SYNC_PROGRESS)) {
        // ... set the UI to show that a sync is in progress
    } else {
        // ... set the UI to show that a sync is NOT in progress
    }
}

private class SyncReceiver extends BroadcastReceiver {

    private MyActivity mActivity;

    public SyncReceiver(MyActivity activity) {
        mActivity = activity;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SyncAdapter.START_SYNC)) {
            Log.i("@string/app_name", "Started sync");
            mActivity.showProgress();
        }
        else if (intent.getAction().equals(SyncAdapter.STOP_SYNC)) {
            Log.i("@string/app_name", "Started sync");
            mActivity.showProgress();
        }
    }
}

Кажется, это работает для меня. Должен признать, что у меня есть ощущение, что с этим связаны некоторые потенциальные проблемы из-за асинхронного характера передач. Буду признателен за любой вклад в улучшение моего подхода!

...