Кто-нибудь реализовал (или получил дополнительную информацию) на Android SyncObserver
Я разрабатываю приложение на 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 ответа:
У меня была та же проблема, и в итоге я реализовал ее с помощью комбинации 1) широковещательной передачи от SyncAdapter и 2) использования SharedPreferences для указания статуса.
В Синкадаптере что-то вроде этого:
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(); } } }
Спасибо за ответ.
Из-за асинхронного характера фоновой синхронизации ваше приложение (действие) может быть запущено с уже выполненной фоновой синхронизацией, которую вы обнаруживаете с сохраненным в предпочтении статусом.
Что я сделал, так это реализовал класс SyncObserver, который реализует интерфейс SyncStatusObserver и создает / уничтожает при приостановке / возобновлении.
syncObserverHandle = ContentResolver.addStatusChangeListener( ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, new SyncObserver() );
Это получает информацию о любом событии, связанном с синхронизацией (ожидание, начало и т. д.), И я также проверяю статус использование
API для Android для этого довольно просты, и вы должны уважать правила о том, что делается в потоке пользовательского интерфейса, а что нет, но если кто-то хочет увидеть мою реализацию, просто напишите вопрос и укажите мне на него, и я с удовольствием отвечу.ContentResolver.isSyncActive();