2011-07-08 16 views
28

Ben bir senkronizasyon uygulamış ve bunu kendi aktivitesinde bitirdiğinde bir geri arama almak istiyorum. ContentResolver.addStatusChangeListener kullanmayı denedim, ancak eşitleme beklemede/etkin olduğunda yalnızca geri aramaları alıyorum.Senkronizasyon bittiğinde nasıl bilinir?

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

Ancak onStatusChanged yöntemde if asla geçerlidir: İşte benim etkinlikten alakalı bazı kod. Ben de onResume() elle denir çünkü muhtemelen çalışır JumpNote demo gelen bu örneği almış, bu yüzden senkronizasyon tamamlandığında muhtemelen sistemin tarafından denilen olmamıştı. Yoksa öyle mi ve yanlış bir şey mi yapıyorum? İşte LogCat olsun ne:

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 

Yani, ben olabilir benim verileri yenilemek için ikinci SYNC_OBSERVER_TYPE_ACTIVE (4) durum değişikliği güvenmek gibi görünüyor, ama bu gerçekten çirkin görünüyor. Herhangi bir fikir? Bulduğum

cevap

36

bir çözüm tamamen ContentResolver hendek ve kendi yayın uygulamaktır. aktivitedeki bu

Intent i = new Intent(SYNC_FINISHED); 
sendBroadcast(i); 

Ve: Temel olarak, onPerformSync sonunda, senkronizasyon adaptörü bu eklentiyi

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

Bu sadece iyi iş gibi görünüyor, ancak bir şey bulmak için umuyordum Senkronizasyon bittiğinde doğrudan bana bildiren SDK.

+1

1 Ben ContentResolver.isSyncActive' 'ile bir saat kaybettim. Bunu yapmak aslında çok daha kolaydı. – rds

+0

"Bu işlemi senkronizasyon servisine ekle" dediğinizde, aslında senkronizasyon adaptörü mi demek istiyorsunuz? '' ... en sonunda '' beni düşünmemi sağlıyor: sync, onPerformSync'in sonunda tamamlandığında. – HGPB

+2

Bunu anlayamıyorum, gönderimBroadcast ve SYNC_FINISHED nedir? –

15

Garip, bu benim için çalışır. Benim Activity yılında

Ben:

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

bu benim için çalıştı, ancak 2 izin eklemem gerekiyordu: GET_ACCOUNTS, READ_SYNC_STATS –

+0

'@StatusChanged' üzerinde public void'i geçersiz kıl >> >>" Metodu, süper sınıftan yöntemi geçersiz kılmaz ". ?? – Eftekhari

+0

harika. çekicilik gibi çalışıyor :) –

6

Ben benzer bir şey üzerinde çalışıyordu ve ben onStatusChanged işlevi sonunda bir daha Log.d var ve yürütme değildi!

15 dakikalık hata ayıklama ve hatayı deneme süresinden sonra, READ_SYNC_STATS iznini eklemem gerektiğini anlıyorum, yine de GET_ACCOUNTS iznine sahibim. Öyleyse, lütfen doğru izni aldığınızı kontrol edin, "if" kelimesinin doğru olmadığı değil, her zaman kefalet ettiği anlamına gelir.

İlgili konular