2012-06-26 13 views
6

तो, मेरा प्रश्न तब बाकी है जब आप सेटिंग्स पर जाएं -> खाते & सिंक करें और उस खाते का चयन करें जो बनाया गया था कि आपका SyncAdapter क्लाउड सर्वर से समन्वयित हो रहा है, और खाता निकालें का चयन करें, जहां तक ​​आपका SyncAdapter संबंधित है ? एक संवाद है जो आपको पुष्टि करने के लिए कहता है और उस खाते से जुड़े फोन पर डेटा हटा दिया जाएगा। मैं आसानी से विश्वास नहीं कर सकता कि ढांचा स्थानीय डेटा में संग्रहीत मेरे SyncAdapter डेटा को स्वचालित रूप से हटा सकता है, लेकिन ऐसा लगता है कि खाते को हटाने से (और मैं सहमत हूं कि यह होना चाहिए) उस डेटा को हटा देगा। क्या मेरे SyncAdapter में कोई अतिरिक्त वृद्धि है जो स्थानीय डेटाबेस से सभी उचित डेटा को हटाने के लिए खाता हटाने के लिए कॉलबैक के रूप में कार्य करेगा? शायद इसे AccountManager के माध्यम से किया जाना चाहिए; मेरा AccountManager अधिसूचित हो जाता है जब खाता हटा दिया जाता है और वहां से मैं SyncAdapter के बिना डेटा हटाना ट्रिगर कर सकता हूं।क्या खाता प्रबंधक खाता हटा देता है जब सिंक एडाप्टर अधिसूचित हो जाता है?

संपादित करें: संबंधित नोट पर, सिंक प्रबंधक प्रत्येक खाते के लिए मेरे SyncAdapter पर कॉल करता है जो एक नया खाता जोड़े जाने पर सिंक्रनाइज़ करता है? मैं onPerformSync(...) को पहले जोड़े गए खातों के साथ निष्पादित किया जा रहा हूं, जब मैं खाता जोड़ता हूं, और इसे रोकना चाहता हूं।

उत्तर

7

मुझे पता चला कि ऐप का ContentProviderOnAccountsUpdateListener लागू करना है। account_manager.addOnAccountsUpdatedListener(this, null, false) के साथ अपने onCreate विधि में एक श्रोता के रूप में ContentProvider संलग्न और उसके बाद की तरह

@Override 
public void onAccountsUpdated(final Account[] accounts) { 
    Ln.i("Accounts updated."); 
    final Iterable<String> account_list = new Iterable<String>() { 
     @Override 
     public Iterator<String> iterator() { 
      return new Iterator<String>() { 
       private final Iterator<Account> account_list = Arrays.asList(accounts).iterator(); 

       @Override 
       public boolean hasNext() { 
        return account_list.hasNext(); 
       } 

       /** Extracts the next account name and wraps it in single quotes. */ 
       @Override 
       public String next() { 
        return "'" + account_list.next().name + "'"; 
       } 

       @Override 
       public void remove() { throw new UnsupportedOperationException("Not implemented"); } 
      }; 
     } 
    }; 
    final String account_set = TextUtils.join(", ", account_list); 
    Ln.i("Current accounts: %s", account_set); 

    // Removes content that is associated with accounts that are not currently connected 
    final SelectionBuilder builder = new SelectionBuilder(); 
    builder.table(Tables.CALENDARS) 
      .where(Calendars.CALENDAR_USER + " NOT IN (?)", account_set); 

    new SafeAsyncTask() { 
     @Override 
     public Void call() throws Exception { 
      _model.openWritableDatabase(); 
      _model.delete(builder); 
      return null; 
     } 
    }.execute(); 


    getContext().getContentResolver().notifyChange(Calendars.NO_SYNC_URI, null, false); 
} 

मैं वर्तमान में कनेक्ट किए गए खातों की एक String का निर्माण, तो उस String के साथ एक SQL क्वेरी निर्माण इंटरफ़ेस विधि को लागू। मैं वर्तमान में जुड़े खातों से जुड़े डेटा को हटाने के लिए उस क्वेरी पर पृष्ठभूमि थ्रेड में डेटाबेस पर एक डिलीट निष्पादित करता हूं। और मैं सूचित करता हूं कि सामग्री बदल गई है, लेकिन सर्वर के साथ सिंक्रनाइज़ करने की आवश्यकता नहीं है।

+0

क्या आप अपने उत्तर पर थोड़ा सा विस्तार कर सकते हैं? आप किस बारे में बात कर रहे हैं? – akirk

+0

... सामग्री प्रदाता, पहली पंक्ति को करीब पढ़ें।मुझे नहीं पता कि आप "विस्तृत" डी –

+0

और क्या चाहते हैं, ContentProviders जीवन चक्र में प्रासंगिक बिंदु पर OnAccountsUpdateListener को निकालना संभव है? – fr1550n

5

नहीं, लेकिन आपका प्रमाणक [1] करता है। पहले खाते निकाल दिया जाता है इस विधि कहा जाता है:

AbstractAccountAuthenticator.getAccountRemovalAllowed(AccountAuthenticatorResponse, Account) 

खाता परम खाता हटा दिया जा रहा है - डिफ़ॉल्ट व्यवहार खाते को हटाने के लिए अनुमति देने के लिए है:

return super.getAccountRemovalAllowed(response, account); // returns Bundle[{booleanResult=true}] 

.. लेकिन मुझे लगता है कि यह एक हुक है जिसे आप साफ-सुथरा चीजों के लिए उपयोग कर सकते हैं या हटाए गए खाते को अवरुद्ध कर सकते हैं।

[1] - यह एक गंदे हैक है; कृपया डांडे की टिप्पणी देखें।

+2

मुझे विश्वास नहीं है कि विधि का उद्देश्य "साफ-सुथरा चीजों" के लिए उपयोग किया जाना है। 'AbstractAccountAuthenticator' में अपना नाम और स्थान दिया गया है, यह संभवतः आपके ऐप के उपयोग के लिए उपयोग किए जा सकने वाले आंतरिक खातों को रोकने के लिए उपयोग किया जा सकता है। मुझे व्यक्तिगत रूप से उपयोग केस नहीं मिला है। मेरे लिए बड़ा इरादा उपसर्ग के रूप में "मिलता है" है। आपको "पाने" विधियों में साइड इफेक्ट्स से बचना चाहिए, जिससे प्रवाह का पालन करना मुश्किल हो जाता है। क्या आपको अपने सभी डेटा को हटाने के लिए "पाने" पर संदेह होगा? –

+0

कोई संदेह नहीं है कि आप सही हैं और यह एक गंदा हैक है। मैं अपना जवाब इस प्रकार अपडेट कर दूंगा। – fr1550n

3

एक और विकल्प android.accounts.LOGIN_ACCOUNTS_CHANGED प्रसारण के लिए पंजीकरण करना है कि AccountManager भेजता है। दुर्भाग्यवश, इस प्रसारण को भेजा गया है जब भी खाता बदल जाता है और प्रसारण आगे की जानकारी को और अधिक जानकारी प्रदान नहीं करता है।

तो आपको खाता प्रबंधक से पूछना होगा और देखें कि कितने "आपके" खाते शेष हैं और गायब लोगों के डेटा को हटा दें।

+0

ठीक है, @ डंड्रे एलिसन द्वारा इसके ऊपर का समाधान इस पर आधारित है। तो इस जवाब को प्राथमिकता दी जानी चाहिए। जब आप 'addOnAccountsUpdatedListener' कहते हैं, तो खाता प्रबंधक एक गतिशील प्रसारण रिसीवर पंजीकृत कर रहा है जो श्रोता को अपने' ऑनसेसिव 'में कॉल करता है। तो, यह मूल रूप से वही है। जब भी डिवाइस में कोई भी खाता (Google खाता, ट्विटर खाता इत्यादि) बदल जाता है तो दोनों समाधान अधिसूचित किए जाते हैं। – blindOSX

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