2011-10-28 4 views
16

Ho riscontrato un comportamento leggermente strano con il mio SyncAdapter.SyncAdapter non viene chiamato in base all'ordine delle chiamate di impostazione dell'account

La prima volta che installo la mia app (dopo la disinstallazione con adb), avvia e crea un account. A seconda dell'ordine di alcune istruzioni (vedi sotto), il mio SyncAdapter's onPerformSync() non verrà mai chiamato; il mio account sotto "Account e sincronizzazione" mostra l'icona "sincronizzazione in corso" che gira a tempo indeterminato. Se poi deseleziono la casella di controllo sincronizzazione accanto all'account della mia app, e quindi ricontrollare, my OnPerformSync() viene chiamato immediatamente.

Ciò causa il mancato richiamo del mio SyncAdapter. icona "Sincronizzazione in corso" gira per sempre, a meno che io deselezionare, quindi ricontrollare la casella di controllo di sincronizzazione:

final Account account = new Account(mUsername, getString(R.string.ACCOUNT_TYPE)); 
mAccountManager.addAccountExplicitly(account, mPassword, null); 
ContentResolver.setSyncAutomatically(account, getString(R.string.CONTENT_AUTHORITY), true); 
ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1); 

Con questo ordinamento delle stesse dichiarazioni, tutto funziona perfettamente:

final Account account = new Account(mUsername, getString(R.string.ACCOUNT_TYPE)); 
ContentResolver.setSyncAutomatically(account, getString(R.string.CONTENT_AUTHORITY), true); 
ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1); 
mAccountManager.addAccountExplicitly(account, mPassword, null); 

La mia ipotesi Sto mettendo il SyncManager in uno stato incoerente a causa del fatto che spegne immediatamente una richiesta di sincronizzazione per la creazione dell'account, e sto cambiando la sua configurazione sotto i suoi piedi. Ma la documentazione (poco coerente) non menziona alcun problema con la chiamata di queste funzioni in qualsiasi momento.

Per gli altri alle prese con SyncAdapters, ho trovato che contentResolver.requestSync() non attiverà mai il tuo SyncAdapter.onPerformSync() a meno che non chiami ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1);.

Qualcuno potrebbe spiegare questo comportamento? La documentazione che circonda Account e Sincronizzazione è a dir poco poco chiara.

Ho riscontrato questo comportamento sull'emulatore 2.1, la compilazione rispetto all'SDK 2.1.

+0

+1! Ci sono volute ore di frustrazione finché non abbiamo guardato a questo e abbiamo chiamato setIsSyncable! Grazie! –

+0

Molto informativo. Per favore scrivi una risposta alla tua domanda, in modo che sappiamo che non è più nella lista dei "non ascoltati". – rds

+0

Ho aggiornato la mia domanda in modo che la parte della domanda sia più chiara. Voglio che qualcuno spieghi o elabori perché questo comportamento si verifica. –

risposta

6

Ho trovato che contentResolver.requestSync() non attiverà mai SyncAdapter.onPerformSync() a meno che non si chiami ContentResolver.setIsSyncable(account, getString(R.string.CONTENT_AUTHORITY), 1);.

Per un resoconto dettagliato della soluzione sono andato con l'utilizzo di SyncAdapter, vedere la mia risposta qui:

https://stackoverflow.com/a/12015967/988870

+0

Sto affrontando lo stesso problema, grazie per la risposta. –

4

ho appena sbattuto la testa contro un muro per ore cercando di capire il motivo per cui la sincronizzazione periodica wasn' t lavorando. Risulta che la frequenza del sondaggio deve essere espressa in secondi (letterali) e non in millisecondi, e non in secondi in millisecondi. Così, per esempio, se si desidera sincronizzare ogni minuto e mezzo, si avrebbe bisogno di chiamare:

  ContentResolver.addPeriodicSync(
        account, 
        authority, 
        Bundle.EMPTY, 
        90 
      ); 

Inoltre, il fascio passato in non può essere nulla in quanto è nella documentazione, si getterà un NullPointerException.