Intereting Posts
Как использовать MediaSessionCompat? Проверка InAppPurchase и отдельный сервер для логики игры Запустить приложение в определенное время Как записать видео с помощью предварительного просмотра камеры в TextureView GridLayout выровняет дочерние элементы в столбце В чем разница между панелью действий и новой панелью инструментов? Несколько входных параметров для метода execute () для AsyncTask Воспроизведение звука с использованием примера soundpool Как добиться анимации пульсации с помощью библиотеки поддержки? Android Studio два варианта с различными файлами манифеста RecyclerView onBindViewHolder вызывается только один раз внутри макета вкладки Есть ли способ сделать номер телефона кликабельным на iphone или Android-телефоне, чтобы позвонить в HTML? PhoneGap / Кордова Разработка Android Представление списка задает настраиваемый селектор пульсаций Android – Geocoder.getFromLocationName () не работает в устройстве ICS

Синхронизированная анимация SyncAdapter – как узнать, активно ли SyncAdapter синхронизация

Я хочу показать ProgressBar в ActionBar, в то время как мой SyncAdapter активно синхронизирует контент с Интернетом и из Интернета.

Я попытался использовать SyncStatusObserver вместе с ContentProvider.addStatusChangeListener . Однако я не могу проверить, активно ли активный SyncAdapter. Я могу только проверить:

  1. SyncAdapter ожидает использования ContentResolver.isSyncPending
  2. SyncAdapter ожидает или активно работает с использованием ContentResolver.isSyncActive

Эти флаги можно комбинировать !isSyncPending && isSyncActive чтобы можно было проверить, что SyncAdapter активно работает и не имеет ожидающей работы. Однако в некоторых случаях SyncAdapter активно работает и ожидает второго ожидающего запроса.

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

Вышеприведенное решение в коде показано ниже. Мы регистрируем наблюдателя в activity.onResume:

  int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING | ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE; syncHandle = ContentResolver.addStatusChangeListener(mask, syncObserver); 

Здесь SyncObserver определяется как:

 syncObserver = new SyncStatusObserver() { @Override public void onStatusChanged(int which) { Account account = getSomeAccount(); boolean syncActive = ContentResolver.isSyncActive(account, CONTENT_AUTHORITY); boolean syncPending = ContentResolver.isSyncPending(account, CONTENT_AUTHORITY); boolean isSynchronizing = syncActive && !syncPending; updateRefreshButtonState(); } } 

Solutions Collecting From Web of "Синхронизированная анимация SyncAdapter – как узнать, активно ли SyncAdapter синхронизация"

Я, наконец, нашел решение проблемы. Идея заключается в использовании методов getCurrentSyncs () или GetCurrentSync () ContentResolver , в зависимости от того, что доступно. Нижеприведенные методы будут проверять, работает ли в настоящее время операция синхронизации для учетной записи и полномочий. Для этого требуется уровень API 8 (Froyo = Android 2.2).

 private static boolean isSyncActive(Account account, String authority) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { return isSyncActiveHoneycomb(account, authority); } else { SyncInfo currentSync = ContentResolver.getCurrentSync(); return currentSync != null && currentSync.account.equals(account) && currentSync.authority.equals(authority); } } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private static boolean isSyncActiveHoneycomb(Account account, String authority) { for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs()) { if(syncInfo.account.equals(account) && syncInfo.authority.equals(authority)) { return true; } } return false; } 

Затем активность регистрируется для обновлений в onResume() и onDestroy() в onDestroy() . Кроме того, нужно обновить состояние вручную в onResume() чтобы догнать текущий статус.

Вот реализация, которая делает именно это. Подклассы должны сами определять

  • getAccount() учетную запись использовать (внедрение getAccount() )
  • Какое полномочие использовать (поле CONTENT_AUTHORITY )
  • Как отображать состояние синхронизации (внедрение updateState(boolean isSynchronizing) )

Надеюсь, это поможет кому-то в будущем.

 import android.accounts.Account; import android.annotation.TargetApi; import android.app.Activity; import android.content.ContentResolver; import android.content.SyncInfo; import android.content.SyncStatusObserver; import android.os.Build; import android.os.Bundle; public abstract class SyncActivity extends Activity { private static final String CONTENT_AUTHORITY = "com.example.authority"; private Object syncHandle; private SyncStatusObserver observer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); observer = new SyncStatusObserver() { @Override public void onStatusChanged(int which) { runOnUiThread(new Runnable() { @Override public void run() { Account account = getAccount(); boolean isSynchronizing = isSyncActive(account, CONTENT_AUTHORITY); updateState(isSynchronizing); } }); } }; } @Override protected void onResume() { super.onResume(); // Refresh synchronization status observer.onStatusChanged(0); // Watch for synchronization status changes final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING | ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE; syncHandle = ContentResolver.addStatusChangeListener(mask, observer); } @Override protected void onPause() { super.onPause(); // Remove our synchronization listener if registered if (syncHandle != null) { ContentResolver.removeStatusChangeListener(syncHandle); syncHandle = null; } } private static boolean isSyncActive(Account account, String authority) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { return isSyncActiveHoneycomb(account, authority); } else { SyncInfo currentSync = ContentResolver.getCurrentSync(); return currentSync != null && currentSync.account.equals(account) && currentSync.authority.equals(authority); } } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private static boolean isSyncActiveHoneycomb(Account account, String authority) { for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs()) { if(syncInfo.account.equals(account) && syncInfo.authority.equals(authority)) { return true; } } return false; } protected abstract Account getAccount(); protected abstract void updateState(boolean isSynchronizing); }