2012-10-16 13 views
11

सिंक्रनाइज़ करने के बारे में कैसे पता चलेगा कि मैं एक्शनबार में प्रोग्रेसबार दिखाना चाहता हूं, जबकि मेरा सिंक एडाप्टर सक्रिय रूप से वेब से सामग्री को सिंक्रनाइज़ कर रहा है।सिंकएडाप्टर चल रहा एनीमेशन - सिंक एडाप्टर सक्रिय रूप से

मैंने का उपयोग ContentProvider.addStatusChangeListener के साथ करने का प्रयास किया है। हालांकि, मैं यह नहीं देख सकता कि सिंक एडाप्टर सक्रिय रूप से चल रहा है या नहीं। मैं केवल देख सकते हैं:

  1. SyncAdapter ContentResolver.isSyncPending
  2. का उपयोग कर लंबित है SyncAdapter लंबित है या सक्रिय रूप से ContentResolver.isSyncActive

ये झंडे जोड़ा जा सकता है का उपयोग कर काम कर रहे हैं: एक SyncAdapter कि जाँच करने के लिए !isSyncPending && isSyncActive इतना है कि यह संभव है सक्रिय रूप से काम कर रहा है और उसके पास कोई लंबित काम नहीं है। हालांकि, कुछ मामलों में सिंक एडाप्टर सक्रिय रूप से काम कर रहा है और इसके लिए एक दूसरा लंबित अनुरोध इंतजार कर रहा है।

यह बहुत आसान लगता है लेकिन मुझे इस समस्या के आसपास कोई रास्ता नहीं मिल रहा है। प्रोग्रेसबार तब दिखाई देता है जब सिंकएडाप्टर नहीं चल रहा है, उपयोगकर्ताओं को यह इंप्रेशन दे रहा है कि सिंक्रनाइज़ेशन बहुत धीमा है। यह प्रोग्रेसबार दिखाने के लिए उपयोगकर्ता को लगता है कि कुछ भी नहीं हो रहा है।

कोड में उपरोक्त समाधान नीचे दिखाया गया है। हम activity.onResume में पर्यवेक्षक रजिस्टर:

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

syncObserver यहाँ के रूप में परिभाषित किया गया है:

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

उत्तर

16

मैं अंत में समस्या का समाधान मिल गया। विचार ContentResolver के getCurrentSyncs() या getCurrentSync() विधियों का उपयोग करना है, जो भी उपलब्ध हो। नीचे दी गई विधियां जांचेंगी कि सिंक ऑपरेशन वर्तमान में किसी खाते और प्राधिकारी के लिए काम कर रहा है या नहीं। इसके लिए एपीआई स्तर 8 (फियोयो = एंड्रॉइड 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; 
} 

एक गतिविधि तो onDestroy() में onResume() में अद्यतन और unregisters के लिए पंजीकृत करता है। साथ ही, किसी को वर्तमान स्थिति को पकड़ने के लिए onResume() में मैन्युअल रूप से राज्य को अद्यतन करना होगा।

यहां एक कार्यान्वयन है जो बस यही करता है। उपवर्गों खुद को

  • क्या खाते (getAccount() को लागू करने)
  • क्या authoritity (क्षेत्र CONTENT_AUTHORITY)
  • कैसे तुल्यकालन स्थिति प्रदर्शित करने का उपयोग करने के उपयोग करने के लिए परिभाषित करना चाहिए (लागू करने updateState(boolean isSynchronizing))

मुझे आशा है कि यह भविष्य में किसी की मदद करेगा।

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

एक्लेयर, फ्रायओ, जिंजरब्रेड के लिए, केवल उपरोक्त समाधान के लिए समाधान केवल डिवाइस पर ही है। यदि किसी डिवाइस पर एक से अधिक खाते मौजूद हैं, तो पहला खाता केवल समन्वयित होगा; बाकी को नजरअंदाज कर दिया जाता है। – ChuongPham

संबंधित मुद्दे