Syncadapter onPerformSync que se llama dos veces la primera vez

Mi syncadapter funciona bien, excepto por una cosa. Después de que el usuario instale la aplicación, mi aplicación se sincroniza dos veces. Más tarde, si la sincronizo manualmente en "ajustes" se sincroniza sólo una vez como se esperaba. Es sólo la primera ejecución de la aplicación que esto sucede.

Aquí está el código en mi "onCreate" que crea la cuenta si no ya ha creado y configura el syncadapter. ¿Alguna idea de lo que estoy haciendo mal?

if (accountManager.addAccountExplicitly(appAccount, null, null)) { ContentResolver.setIsSyncable(appAccount, PROVIDER, 1); ContentResolver.setSyncAutomatically(appAccount, PROVIDER, true); Bundle extras = new Bundle(); extras.putBoolean("dummy stuff", true); ContentResolver.addPeriodicSync(appAccount, PROVIDER, extras, 43200); } 

Mi comportamiento deseado es que la aplicación se sincronice una vez inmediatamente después de la instalación y, a continuación, periódicamente según la sentencia "addPeriodicSync".

Observé este comportamiento también.

Es correcto, que addAccountExplicit () activará una resync de cuenta de sistema de cuentas obsoletas.

Clarificación

Sin embargo, la observación de Zapek acerca de la sincronización addPeriodic o la sincronización de peticiones que son sincronizaciones "inmediatas", no es del todo correcta. Ambos están en cola. Además, lo siguiente es válido para addPeriodicSync ():

Estas sincronizaciones periódicas respetan las configuraciones "syncAutomatically" y "masterSyncAutomatically". Aunque estas sincronizaciones están programadas en la frecuencia especificada, puede tardar más en que se inicie realmente si hay otras sincronizaciones por delante en la cola de operaciones de sincronización. Esto significa que el tiempo real de inicio puede desviarse. ( Documentación )

En relación con su problema

Lo que experimenta se describe en el entrenamiento sobre la ejecución de adaptadores de sincronización:

El método addPeriodicSync () no deshabilita setSyncAutomatically (), por lo que puede obtener múltiples sincronización se ejecuta en un período de tiempo relativamente corto. Además, sólo se permiten unos cuantos indicadores de control del adaptador de sincronización en una llamada a addPeriodicSync (); Los indicadores que no están permitidos se describen en la documentación referenciada para addPeriodicSync (). Adaptador de sincronización de formación para Android

La propia solución de Google se parece a la tuya, con una frecuencia incluso menor (60 * 60 = 3600):

  if (accountManager.addAccountExplicitly(account, null, null)) { // Inform the system that this account supports sync ContentResolver.setIsSyncable(account, CONTENT_AUTHORITY, 1); // Inform the system that this account is eligible for auto sync when the network is up ContentResolver.setSyncAutomatically(account, CONTENT_AUTHORITY, true); // Recommend a schedule for automatic synchronization. The system may modify this based // on other scheduled syncs and network utilization. ContentResolver.addPeriodicSync( account, CONTENT_AUTHORITY, new Bundle(),SYNC_FREQUENCY); newAccount = true; } 

Proposición

Propongo utilizar el SyncStats en onPerformSync () para realmente devolver alguna información acerca de su sincronización inicial al sistema, por lo que puede programar de manera más eficiente.

 syncResult.stats.numEntries++; // For every dataset 

Esto no puede ayudar si la otra tarea ya está programada – investigando

Además uno puede establecer un indicador 'isInitialOnPerformSync' (compartidoPreferencias), para hacer que otras tareas de copia de seguridad.

 syncResult.delayUntil = <time>; 

Yo personalmente no soy realmente fan de la creación de un período de tiempo sin sincronización fija después de la sincronización inicial.

Otras consideraciones – Sincronización inicial inmediatamente

Como se indica en la aclaración, la sincronización no se ejecutará inmediatamente con la configuración. Hay una solución, que le permitirá sincronizar de inmediato. Esto no influirá en los ajustes de sincronización y no los hará retroceder, por lo que esto no soluciona el problema, pero tiene el efecto de que su usuario no tendrá que esperar a que se active la sincronización. Para mostrar el contenido principal de su aplicación de esta manera.

Código: Configurar un indicador para isInitialSync dentro de su proceso de aplicación normal (que se guarda, por ejemplo, en defaultSharedPreferences). Incluso puede utilizar la opción Al iniciar la instalación o inicio de sesión (si es necesario la autenticación) puede invocar una sincronización inmediata como sigue.

 /** * Start an asynchronous sync operation immediately. </br> * * @param account */ public static void requestSyncImmediately(Account account) { // Disable sync backoff and ignore sync preferences. In other words...perform sync NOW! Bundle settingsBundle = new Bundle(); settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); // Request sync with settings ContentResolver.requestSync(account, SyncConstants.CONTENT_AUTHORITY, settingsBundle); } 

¿Está solicitando una sincronización aparte de la función addPeriodicSync ()?

Debe sincronizarse por sí mismo cuando agregue la cuenta por primera vez. Por lo tanto, cualquier petición de sincronización adicional tendría en cuenta la sincronización doble.

Si eso no ayuda, siempre puedes guardar en las preferencias la hora de la última sincronización y comprobar contra cada sincronización, para que puedas limitar la frecuencia de sincronización a lo que quieras.

¡Espero que ayude!

AddAccountExplicitely () provocará una sincronización para todas las cuentas que tienen un estado sincronizable desconocido (que incluye su SyncAdapter recién agregado).

El problema es que puede llevar de unos pocos segundos a unos pocos minutos, dependiendo de cuántas otras aplicaciones con un SyncAdapter y cuentas configuradas estén instaladas.

AddPeriodicSync () (o requestSync ()) realizará una sincronización inmediatamente, lo cual es deseable en el caso de que el usuario necesite ver los datos tan pronto como sea posible al iniciar la aplicación.

No hay mucho que puedas hacer, aparte de asegurarse de que tus sincronizaciones estén optimizadas para ser rápidas en el caso de que no haya datos entre el cliente y el servidor.

  • Ocultar la cuenta ficticia para el adaptador de sincronización de la configuración
  • SyncAdapter periodicsync () no se activa
  • Uso de SyncAdapter sin crear una cuenta
  • ¿Es mala práctica o grosero hacer ContentResolver.setMasterSyncAutomatically en una aplicación android?
  • ¿Por qué ContentResolver.requestSync no activa una sincronización?
  • ¿Cómo se escucha el progreso de Android SyncAdapter?
  • Sincronización de un servicio REST con una aplicación de Android
  • ¿Se notifica SyncAdapter cuando AccountManager elimina la cuenta?
  • Android Flavors, ContentProviders, SyncAdapters y AccountManager
  • ¿Cómo notificar a la actividad de llamada cuando SyncAdapter ha finalizado?
  • SyncAdapter siempre en estado pendiente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.