¿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:
- Utilizando un local_manifest.xml con repo
- Android Gradle Error: "Error al obtener el ID de la aplicación para depurar"
- Adaptador de sincronización sin cuenta
- ¿Cómo sincronizar la base de datos SQLite en el teléfono Android con la base de datos MySQL en el servidor?
- Una solución en la nube para sincronizar la base de datos de aplicaciones en Android
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?
- Android: cómo recibir notificaciones cuando finaliza la sincronización, al solicitar una sincronización con ContentResolver.requestSync ()
- Sincronizar la hora del sistema en 2 teléfonos
- Cómo sincronizar datos entre diferentes dispositivos
- Sincronizar dispositivos Android a través de la hora GPS?
- Android - Cómo descargar los datos en segundo plano en determinados momentos
- sincronización del tiempo del emulador androide
- Sincronizar varias ventanas con varias vistas en Android
- Evitar que el servicio de fondo se destruya debido a "detectar una CPU excesiva en un proceso bifurcado"
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.
- Android descodificador-> decodificar devuelto falso para Bitmap descargar
- Quitar icono de la contraseña de la muestra en Android N