¿Cómo saber cuándo se termina la sincronización?

He implementado un adaptador de sincronización y quiero obtener una devolución de llamada cuando termine en mi actividad. He intentado usar ContentResolver.addStatusChangeListener , pero sólo estoy recibiendo callbacks cuando la sincronización está pendiente / activa. He aquí un código relevante de mi actividad:

 @Override protected void onResume() { super.onResume(); final int mask = ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE | ContentResolver.SYNC_OBSERVER_TYPE_PENDING; syncObserverHandle = ContentResolver.addStatusChangeListener(mask, syncStatusObserver); } @Override protected void onPause() { super.onPause(); if (syncObserverHandle != null) { ContentResolver.removeStatusChangeListener(syncObserverHandle); syncObserverHandle = null; } } private SyncStatusObserver syncStatusObserver = new SyncStatusObserver() { @Override public void onStatusChanged(int which) { AccountManager am = AccountManager.get(TodosActivity.this); Account a = am.getAccountsByType(Const.ACCOUNT_TYPE)[0]; Log.d(Const.TAG, "Sync status changed: " + which); if (!ContentResolver.isSyncActive(a, DataProvider.AUTHORITY) && !ContentResolver.isSyncPending(a, DataProvider.AUTHORITY)) { Log.d(Const.TAG, "Sync finished, should refresh nao!!"); } } }; 

Sin embargo, el if en el método onStatusChanged nunca es válido. He tomado este ejemplo de la demostración de JumpNote donde trabaja probablemente porque también se llama manualmente en onResume() , así que es probablemente nunca llamado por el sistema cuando la sincronización es terminada. ¿O es, y estoy haciendo algo mal? Esto es lo que obtengo en logcat:

 D/MYAPP (10903): Sync status changed: 2 D/MYAPP (10903): Sync status changed: 2 D/MYAPP (10903): Sync status changed: 4 D/MYAPP (10981): --> DataSyncAdapter.onPerformSync() D/MYAPP (10981): <-- DataSyncAdapter.onPerformSync() D/MYAPP (10903): Sync status changed: 4 

Por lo tanto, parece que podría confiar en el segundo cambio de estado SYNC_OBSERVER_TYPE_ACTIVE (4) para actualizar mis datos, pero eso parece muy feo. ¿Algunas ideas?

Una solución que he encontrado es ContentResolver completamente el ContentResolver , e implementar mi propia emisión. Básicamente, agregue esto en el adaptador de sincronización, al final de onPerformSync :

 Intent i = new Intent(SYNC_FINISHED); sendBroadcast(i); 

Y esto en la actividad:

 @Override protected void onResume() { super.onResume(); registerReceiver(syncFinishedReceiver, new IntentFilter(DataSyncService.SYNC_FINISHED)); } @Override protected void onPause() { super.onPause(); unregisterReceiver(syncFinishedReceiver); } private BroadcastReceiver syncFinishedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(Const.TAG, "Sync finished, should refresh nao!!"); } }; 

Esto parece funcionar muy bien, sin embargo, esperaba encontrar algo en el SDK que me notifique directamente cuando se termina una sincronización.

Extraño, funciona para mí.

En mi Activity tengo:

  @Override protected void onPause() { super.onPause(); ContentResolver.removeStatusChangeListener(mContentProviderHandle); } @Override protected void onResume() { super.onResume(); mContentProviderHandle = ContentResolver.addStatusChangeListener( ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, this); } @Override public void onStatusChanged(int which) { AccountManager accountManager = AccountManager.get(this); Account[] accounts = accountManager .getAccountsByType(AuthenticatorActivity.PARAM_ACCOUNT_TYPE); if (accounts.length <= 0) { return; } updateRefresh(ContentResolver.isSyncActive(accounts[0], MyContentProvider.AUTHORITY)); } // Since onStatusChanged() is not called from the main thread // I need to update the ui in the ui-thread. private void updateRefresh(final boolean isSyncing) { runOnUiThread(new Runnable() { @Override public void run() { if (isSyncing) { mRefreshMenu.setActionView(R.layout.menu_item_refresh); } else { mRefreshMenu.setActionView(null); } } }); } 

Yo estaba trabajando en algo similar, y tengo un Log.d más al final de la función onStatusChanged, y no estaba ejecutando!

Así que después de 15 minutos de depuración y prueba por error, me doy cuenta de que necesito agregar el permiso READ_SYNC_STATS, ya tengo el permiso GET_ACCOUNTS. Por lo tanto, compruebe que obtiene el permiso adecuado, no es que el "si" no se convierte en verdad, es que se mantiene todo el tiempo.

  • ¿Cómo implementar la sincronización de datos entre dispositivos en línea y sin conexión con el motor de aplicaciones de Google?
  • Android sync strings.xml
  • Cómo compartir un objeto entre dos subprocesos (sincronización de subprocesos)?
  • Cómo mostrar el mensaje de error de sincronización
  • API de copia de seguridad de Android
  • SyncAdapter no se llama dependiendo del orden de las llamadas de configuración de cuenta
  • Sincronización de archivos y bases de datos de Android con Dropbox
  • ¿Cómo acceder a un contexto de aplicación ya en ejecución desde un servicio de adaptador de sincronización en Android?
  • ¿Por qué Android activa una sincronización de cuenta de Google cada vez que agrego o elimino una cuenta de un tipo personalizado?
  • Sincronizar datos SQLite desde el teléfono Android a la base de datos MySQL de MySQL de Windows
  • Recuperación de llamada de Android SyncAdapter
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.