¿Se notifica SyncAdapter cuando AccountManager elimina la cuenta?
Por lo tanto, mi pregunta se restablece cuando vaya a Configuración -> Cuentas y sincronización y seleccione la cuenta que se creó que SyncAdapter
está sincronizando con un servidor de nube, y seleccione quitar cuenta, ¿qué sucede en lo que respecta a SyncAdapter
? Aparecerá un cuadro de diálogo que le pedirá que confirme y que se eliminarán los datos del teléfono asociados con esa cuenta. No puedo creer fácilmente que el marco puede eliminar automáticamente los datos que mi SyncAdapter
ha almacenado en la base de datos local, pero parece implicar que la eliminación de la cuenta (y yo estaría de acuerdo en que debe) eliminar esos datos. ¿Hay una adición a mi SyncAdapter
que servirá como una especie de devolución de llamada para la eliminación de cuentas para manejar la eliminación de todos los datos apropiados de la base de datos local? Tal vez tiene que hacerse a través del AccountManager
en AccountManager
lugar; Mi AccountManager
se notifica cuando la cuenta se quita y desde allí puedo activar la eliminación de datos sin el SyncAdapter
.
EDIT: En una nota relacionada, ¿el administrador de sincronización llama a mi SyncAdapter
para cada cuenta que se sincroniza cuando se agrega una cuenta nueva? Veo un onPerformSync(...)
está ejecutando para las cuentas agregadas previamente junto con la cuenta justa agregada cuando agrego una cuenta, y quisiera parar eso.
- En Android, ¿debe ejecutarse un adaptador de sincronización de contactos en un proceso independiente?
- ¿Qué es Android SyncAdapter contentAuthority y accountType?
- Servidor SyncAdapter y Rest con respuesta paginada
- ¿Cómo señalar la sincronización completa al Android SyncManager?
- Sincronización personalizada que no funciona con la cuenta de Google (com.google) en algunos dispositivos Samsung
- ¿Cómo configurar correctamente el syncAdapter?
- ¿Por qué AccountManager.addAccount puede devolver false de forma explícita?
- ContentProvider no aparecerá en el área de datos y sincronización
- Sincronizar cliente Android y servidor REST
- ¿Cómo puedo obtener mi tipo de cuenta personalizada para que aparezca en la aplicación de contactos de Android?
- Evitar el bucle de sincronización de red al sincronizar desde la red en Android ContentProvider
- Opciones de SyncAdapter
- Proveedor de calendario de Android: ¿Existe un identificador único para eventos, utilizable en varios dispositivos?
Descubrí que la solución es hacer que ContentProvider
aplicación implemente OnAccountsUpdateListener
. Adjunte el ContentProvider
como un listener en su método onCreate
con account_manager.addOnAccountsUpdatedListener(this, null, false)
e implemente el método de interfaz como
@Override public void onAccountsUpdated(final Account[] accounts) { Ln.i("Accounts updated."); final Iterable<String> account_list = new Iterable<String>() { @Override public Iterator<String> iterator() { return new Iterator<String>() { private final Iterator<Account> account_list = Arrays.asList(accounts).iterator(); @Override public boolean hasNext() { return account_list.hasNext(); } /** Extracts the next account name and wraps it in single quotes. */ @Override public String next() { return "'" + account_list.next().name + "'"; } @Override public void remove() { throw new UnsupportedOperationException("Not implemented"); } }; } }; final String account_set = TextUtils.join(", ", account_list); Ln.i("Current accounts: %s", account_set); // Removes content that is associated with accounts that are not currently connected final SelectionBuilder builder = new SelectionBuilder(); builder.table(Tables.CALENDARS) .where(Calendars.CALENDAR_USER + " NOT IN (?)", account_set); new SafeAsyncTask() { @Override public Void call() throws Exception { _model.openWritableDatabase(); _model.delete(builder); return null; } }.execute(); getContext().getContentResolver().notifyChange(Calendars.NO_SYNC_URI, null, false); }
Construyo una String
de las cuentas actualmente conectadas, luego construyo una consulta SQL con esa String
. Realizo una supresión en la base de datos en un subproceso de fondo de esa consulta para eliminar los datos asociados a las cuentas que no están conectadas actualmente. Y me notifico que el contenido ha cambiado, pero no necesita ser sincronizado con el servidor.
No, pero su autenticador hace [1]. Este método se llama antes de eliminar la cuenta:
AbstractAccountAuthenticator.getAccountRemovalAllowed(AccountAuthenticatorResponse, Account)
El param de cuenta es la cuenta que se elimina – el comportamiento predeterminado es permitir la eliminación de la cuenta:
return super.getAccountRemovalAllowed(response, account); // returns Bundle[{booleanResult=true}]
..pero supongo que es un gancho que puede utilizar para ordenar las cosas o bloquear la cuenta que se quita si lo desea.
[1] – este es un hack sucio; Por favor vea el comentario de Dandre.
Otra opción es registrarse en la transmisión android.accounts.LOGIN_ACCOUNTS_CHANGED
que envía el AccountManager
. Desafortunadamente, esta emisión se envía cada vez que se cambia cualquier cuenta y la emisión no entrega más información lo que ha cambiado.
Así que tendrías que consultar al administrador de cuentas y ver cuántas "cuentas" te quedan y eliminar los datos de los que faltan.
- NoClassDefFoundError al usar Dagger 2 después de cambiar a Android Studio 2.0
- Android ActionBar no cambia el color de fondo