5

Estoy desarrollando una aplicación en Android que realiza una sincronización de fondo con un servidor (usando SyncAdapter y autenticación, etc.).¿Alguien ha implementado (u obtenido más información) en Android SyncObserver

Cuando se inicia la aplicación en primer plano (con IU), es posible que haya una sincronización en segundo plano en curso u opcionalmente puede iniciarse a través de un botón de IU.

Me gustaría una forma de "conectar" una sincronización de fondo en curso (ya sea iniciada por el sistema, o la configuración de sincronización periódica o la IU) y mostrar su progreso en la actividad de primer plano.

La documentación de ContentResolver (http://developer.android.com/reference/android/content/ContentResolver.html) menciona un misterioso "SyncObserver" que no tiene ningún vínculo con javadoc y no está documentado (que puedo encontrar) .

Hay otras páginas que lo mencionan (http://www.chinaup.org/docs/migrating/m5-0.9/changes/android.content.ContentResolver.html) pero no puedo encontrar más al respecto.

¿Alguien ha implementado esta bestia?

Si no es así, ¿alguien tiene un código de ejemplo o recomendaciones sobre el seguimiento del progreso de una sincronización en segundo plano en una actividad en primer plano?

Respuesta

3

Tuve el mismo problema y terminé implementándolo con una combinación de 1) una transmisión desde SyncAdapter, y 2) usando SharedPreferences para indicar el estado.

En el SyncAdapter, algo como esto esto:

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); 
     } 

En la actividad que hacemos dos cosas a la hoja de vida 1) comprobar la preferencia compartida por si una sincronización está en curso, 2) registrarse para escuchar emisiones con un receptor.

@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(); 
     } 
    } 
} 

Esto parece funcionar para mí. Debo admitir que tengo la sensación de que hay algunos problemas potenciales con esto debido a la naturaleza asincrónica de las transmisiones. ¡Cualquier comentario sobre mejorar mi enfoque sería apreciado!

+0

Creo que el único problema con esto es que, como sugiere, está relacionado con la naturaleza asincrónica de la sincronización en segundo plano. –

+0

No sé sobre ContentResolver.isSyncActive(), eso podría ser mejor que verificar la preferencia compartida. Gracias. – fredw

5

Gracias por la respuesta.

Debido a la naturaleza asincrónica de la sincronización en segundo plano, su aplicación (actividad) podría iniciarse con una sincronización en segundo plano ya en curso, que detectará con el estado almacenado en una preferencia.

Lo que he hecho es implementar una clase SyncObserver que implemente la interfaz SyncStatusObserver y cree/destruya en suspender/reanudar.

syncObserverHandle = ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, new SyncObserver()); 

esto se pone informado de cualquier evento relacionado a sincronizar (pendiente, iniciado, etc) y también comprobar el estado utilizando

ContentResolver.isSyncActive(); 

Las API de Android para esto son bastante básicas, y hay que Respeto las reglas sobre lo que se hace en el hilo de la interfaz de usuario y lo que no, pero si alguien quiere ver mi implementación simplemente publique una pregunta y apúnteme a ella y le responderé con gusto.

+1

Me gustaría presentarle su amable oferta :) Su solución parece que puede resolver mi pregunta http://stackoverflow.com/questions/9268453/android-syncadapter-callback – JosephL

+0

@Andrew Mackenzie También me gustaría ver su implementación, responda a la pregunta dada anteriormente por JosephL – Thomas

+0

@Thomas, debe buscar el código de [BasicSyncAdapter] (https://developer.android.com/samples/BasicSyncAdapter/src/com.example.android.basicsyncadapter/EntryListFragment. html # l82) de android google doc. Particularmente el código de EntryListFragment. – hermannovich

Cuestiones relacionadas