2012-10-16 16 views
11

SyncAdapter etkin bir şekilde web'e içerik senkronize ederken ActionBar'da bir ProgressBar göstermek istiyorum.SyncAdapter animasyonu çalıştırma - SyncAdapter etkin olarak senkronize edip etmediğini nasıl bileceğiniz

SyncStatusObserver'u ContentProvider.addStatusChangeListener ile birlikte kullanmayı denedim. Ancak, bir SyncAdapter'ın aktif olarak çalışıp çalışmadığını kontrol edemiyorum. Ben sadece kontrol edebilirsiniz:

  1. SyncAdapter ContentResolver.isSyncPending
  2. kullanarak beklemede SyncAdapter beklemede VEYA aktif kombine edilebilir ContentResolver.isSyncActive

Bu bayraklar kullanarak çalışma: Bir SyncAdapter kontrol etmek o kadar mümkün olduğunu !isSyncPending && isSyncActive aktif olarak çalışıyor ve bekleyen herhangi bir işi yok. Ancak, bazı durumlarda SyncAdapter aktif olarak çalışır VE bunu bekleyen ikinci bir bekleyen istek var.

Çok basit görünüyor, ancak bu soruna bir çözüm bulamıyorum. SyncAdapter çalışmadığında ProgressBar'ın görünür olması, kullanıcılara senkronizasyonun çok yavaş olduğu izlenimini veriyor. ProgressBar'ı göstermemek, kullanıcının hiçbir şey olmadığını düşünmesini sağlar.

Yukarıdaki koddaki çözüm aşağıda gösterilmiştir. Biz activity.onResume gözlemciyi kayıt: Sonunda soruna bir çözüm bulduk

syncObserver = new SyncStatusObserver() 
{ 
    @Override 
    public void onStatusChanged(int which) 
    { 
     Account account = getSomeAccount(); 
     boolean syncActive = ContentResolver.isSyncActive(account, CONTENT_AUTHORITY); 
     boolean syncPending = ContentResolver.isSyncPending(account, CONTENT_AUTHORITY); 
     boolean isSynchronizing = syncActive && !syncPending; 
     updateRefreshButtonState(); 
    } 
} 

cevap

16

: olarak

int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING | ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE; 
syncHandle = ContentResolver.addStatusChangeListener(mask, syncObserver); 

syncObserver burada tanımlanır. Fikir, ContentResolver'ın getCurrentSyncs() veya getCurrentSync() yöntemlerini, hangisi müsaitse kullanmaktır. Aşağıdaki yöntemler, bir senkronizasyon işleminin şu anda bir hesap ve yetki için çalışıp çalışmadığını kontrol edecektir. API seviyesi 8 gerektirir (Froyo = Android 2.2).

private static boolean isSyncActive(Account account, String authority) 
{ 
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
    { 
     return isSyncActiveHoneycomb(account, authority); 
    } else 
    { 
     SyncInfo currentSync = ContentResolver.getCurrentSync(); 
     return currentSync != null && currentSync.account.equals(account) && 
       currentSync.authority.equals(authority); 
    } 
} 

@TargetApi(Build.VERSION_CODES.HONEYCOMB) 
private static boolean isSyncActiveHoneycomb(Account account, String authority) 
{ 
    for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs()) 
    { 
     if(syncInfo.account.equals(account) && 
      syncInfo.authority.equals(authority)) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

Bir Etkinlik Daha sonra onDestroy() yılında onResume() güncellemeleri ve Unregisters için kaydeder. Ayrıca, mevcut durumla yetinmek için durumun onResume() numaralı el ile güncellenmesi gerekir.

İşte bunu yapan bir uygulama. Alt sınıflar kendilerini Hangi hesabı

  • Ne authoritity (alan CONTENT_AUTHORITY)
  • sychronization durumunu görüntülemek için nasıl
  • kullanmak (getAccount() uygulanması) kullanmak için tanımlamalıdır (uygulayıcı updateState(boolean isSynchronizing))

umarım Gelecekte birisine yardımcı olacaktır.

import android.accounts.Account; 
import android.annotation.TargetApi; 
import android.app.Activity; 
import android.content.ContentResolver; 
import android.content.SyncInfo; 
import android.content.SyncStatusObserver; 
import android.os.Build; 
import android.os.Bundle; 

public abstract class SyncActivity extends Activity 
{ 
    private static final String CONTENT_AUTHORITY = "com.example.authority"; 
    private Object syncHandle; 
    private SyncStatusObserver observer; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     observer = new SyncStatusObserver() 
     { 
      @Override 
      public void onStatusChanged(int which) 
      { 
       runOnUiThread(new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         Account account = getAccount(); 
         boolean isSynchronizing = 
           isSyncActive(account, CONTENT_AUTHORITY); 
         updateState(isSynchronizing); 
        } 
       }); 
      } 
     }; 
    } 

    @Override 
    protected void onResume() 
    { 
     super.onResume(); 

     // Refresh synchronization status 
     observer.onStatusChanged(0); 

     // Watch for synchronization status changes 
     final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING | 
       ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE; 
     syncHandle = ContentResolver.addStatusChangeListener(mask, observer); 
    } 

    @Override 
    protected void onPause() 
    { 
     super.onPause(); 

     // Remove our synchronization listener if registered 
     if (syncHandle != null) 
     { 
      ContentResolver.removeStatusChangeListener(syncHandle); 
      syncHandle = null; 
     } 
    } 

    private static boolean isSyncActive(Account account, String authority) 
    { 
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) 
     { 
      return isSyncActiveHoneycomb(account, authority); 
     } else 
     { 
      SyncInfo currentSync = ContentResolver.getCurrentSync(); 
      return currentSync != null && currentSync.account.equals(account) 
        && currentSync.authority.equals(authority); 
     } 
    } 

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    private static boolean isSyncActiveHoneycomb(Account account, 
                 String authority) 
    { 
     for(SyncInfo syncInfo : ContentResolver.getCurrentSyncs()) 
     { 
      if(syncInfo.account.equals(account) && 
        syncInfo.authority.equals(authority)) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 

    protected abstract Account getAccount(); 
    protected abstract void updateState(boolean isSynchronizing); 
} 
+1

Eclair, Froyo, Gingerbread için, yukarıdaki çözüm yalnızca aygıtın yalnızca bir hesabı varsa çalışır. Bir cihazda birden fazla hesap varsa, ilk hesap yalnızca senkronize edilir; gerisi yok sayılır. – ChuongPham

İlgili konular