2010-02-06 14 views
13

हम कोड के माध्यम से विजेट को सक्षम या अक्षम करना चाहते हैं। जब हम "अक्षम" कहते हैं तो हमारा मतलब है कि किसी एप्लिकेशन में पंजीकृत एक विजेट उपयोगकर्ता को उपलब्ध विजेट्स की सूची में दिखाई नहीं दे सकता है जब वे विजेट को अपनी होम स्क्रीन पर जोड़ने का प्रयास करते हैं। दुर्भाग्यवश, उत्तर के बिना कई बार यह सवाल पूछा गया है।गतिशील रूप से विजेट को सक्षम या अक्षम करने से

PackageManager pm = context.getPackageManager(); 
pm.setComponentEnabledSetting(new ComponentName("com.example.android.apis", ".appwidget.ExampleBroadcastReceiver"), 
    PackageManager.COMPONENT_ENABLED_STATE_ENABLED, // or DISABLED 
    PackageManager.DONT_KILL_APP); 

लेकिन यह काम नहीं करता है:

एक अलग विजेट सवाल जो सुझाव दिया है कि यह विजेट निष्क्रिय करने के लिए पैकेज मैनेजर उपयोग संभव हो गया था करने के लिए एक प्रतिक्रिया डायने Hackborn से हुई थी। विजेट घटक विजेट की सूची में अभी भी दिखाई देगा। हो सकता है कि AppWidgetService है, जो उपलब्ध विजेट सूची लोड करता है, उपलब्ध विजेट की इस सूची कैश (\ src \ आधार \ सेवाओं \ जावा \ कॉम \ एंड्रॉयड \ सर्वर पर एंड्रॉयड स्रोत के Base.git में स्थित है)। यदि यह मामला था, तो उपर्युक्त कोड जो विजेट घटक को सक्षम या अक्षम करता है, डिवाइस रीसेट के बाद काम करेगा क्योंकि कोई कैश नहीं होगा; ऐसा नहीं होता।

मैंने AppWidgetProvider के कुछ तरीकों को ओवरराइड करने की कोशिश की है, जैसे किसी भी ईवेंट को फ़िल्टर करना। मुझे नहीं लगता कि यह कहीं भी जाएगा, क्योंकि ऐपविड्ज सेवा, जो सूची को पॉप्युलेट करती है, स्टार्टअप पर ACTION_APPWIDGET_UPDATE कार्रवाई को पकड़ने के लिए पैकेज प्रबंधक का उपयोग करती है और जब पैकेज जोड़ा जाता है (यानी एक नया ऐप है स्थापित)। एकमात्र ऐसा समय है जब प्रदाता इस सूची से हटाया गया है ACTION_PACKAGE_REMOVED प्रसारण पर है। इसलिए दिया गया है कि प्रदाता हमेशा घटक की सक्षम/अक्षम स्थिति की परवाह किए बिना, मैंने वास्तविक सूची गतिविधि को देखा है जो लॉन्चर ऐप से दिखाया गया है जब उपयोगकर्ता लंबे समय तक डेस्कटॉप पर क्लिक करता है और जोड़ता है एक विजेट: सेटिंग्स में AppWidgetPickActivity com.android.settings में सेटिंग्स। जीआईटी। यह, दुर्भाग्य से, सूची सीधे AppWidgetService से, भरता घटक के सक्षम की स्थिति के लिए किसी भी छानने के बिना: शून्य putInstalledAppWidgets (सूची आइटम) { सूची स्थापित = mAppWidgetManager.getInstalledProviders(); putAppWidgetItems (स्थापित, शून्य, आइटम); }

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

+1

3 साल के बाद इस मुद्दे पर किसी भी अद्यतन:

यहाँ मैं बनाया सहायक विधि है? –

उत्तर

3

हो सकता है कि AppWidgetService (\ src \ आधार \ सेवाओं पर एंड्रॉयड स्रोत के Base.git में स्थित \ जावा \ कॉम \ एंड्रॉयड \ सर्वर) है, जो उपलब्ध विजेट सूची लोड , उपलब्ध विजेट्स की इस सूची को कैश करता है।

यह बताता है कि मैं कह सकता हूं।यह सूची को mInstalledProviders में संग्रहीत करता है; यह सूची readStateFromFileLocked() के माध्यम से जोड़ दी गई है, जो सिस्टम स्टार्टअप तर्क से कहा जाता है।

अगर ऐसी बात कर रहे थे, हालांकि, तो ऊपर कोड है जो सक्षम बनाता है या को निष्क्रिय विजेट घटक होगा क्योंकि कोई कैश होगा एक डिवाइस रीसेट के बाद काम; ऐसा नहीं होता।

आप रैम कैश मानते हैं। कैश एक एक्सएमएल फ़ाइल है।

यह, दुर्भाग्य से, सूची सीधे AppWidgetService से, भरता घटक के लिए किसी भी छानने के बिना स्थिति

सक्षम और यह एंड्रॉयड में एक बग प्रतीत होता। आम तौर पर, मुझे लगता है कि पूरी कैशिंग चीज बग है - अगर यह कैश सिंक हो जाता है तो मुझे पुनर्प्राप्त करने का कोई तरीका नहीं दिखता है।

मैं आपको public Android issue tracker पर किसी समस्या के रूप में अपना लेखन पोस्ट करने की सलाह दूंगा, अगर आपने पहले से ऐसा नहीं किया है।

1

सुविधा आईसीएस में

pm.setComponentEnabledSetting() 

काम करता है। जब विजेट अक्षम हो जाता है, तो इसे उपलब्ध विगेट्स की सूची से निकाल दिया जाता है। इस पल के लिए छोटे सांत्वना, लेकिन कम से कम इसे सही किया गया है।

2

यह मेरे लिए काम किया! मुझे DONT_KILL_APP का उपयोग करना पड़ा था या यह तुरंत मेरे ऐप को मार देगा। इसके अलावा, मुझे यह जांचने के लिए शर्त लगनी पड़ी कि क्या यह पहले से ही एक ही राज्य में है या नहीं।

public void setMyCustomWidgetEnabled(boolean bEnable) 
    { 
     Log.d(LOG_TAG_NAME, "Entering setMyCustomWidgetEnabled(" + bEnable + ")..."); 

     PackageManager rPackageManager = getPackageManager(); 
     if(rPackageManager != null) 
     { 
      ComponentName rComponentName = new ComponentName(getBaseContext(), MyCustomWidget.class); 

      int nComponentEnabledState = rPackageManager.getComponentEnabledSetting(rComponentName); 

      if(bEnable) 
      { 
       //if(nComponentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) 
       { 
        // Change the State to Enabled 
        rPackageManager.setComponentEnabledSetting(rComponentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); 

        Log.d(LOG_TAG_NAME, "-> Changed My Custom Widget' to ENABLED!"); 
       } 
      } 
      else 
      { 
       //if(nComponentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) 
       { 
        // Change the State to Disabled 
        rPackageManager.setComponentEnabledSetting(rComponentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 

        Log.d(LOG_TAG_NAME, "-> Changed 'My Custom Widget' to DISABLED!"); 
       } 
      } 
     } 

     Log.d(LOG_TAG_NAME, "Leaving setMyCustomWidgetEnabled(" + bEnable + ")..."); 
} 
+3

यह केवल सक्षम/अक्षम कार्यों की तरह दिखता है जब मैनिफेस्ट में रिसीवर मूल रूप से सक्षम होता है। अगर इसे मैनिफेस्ट द्वारा अक्षम किया गया है, तो सक्षम/अक्षम प्रोग्रामेटिक रूप से काम नहीं करता है। कृपया आप इस व्यवहार की पुष्टि कर सकते हैं? –

+0

@ पीटर.बर्टोस हाँ, यह केवल तभी काम करता है जब यह मूल रूप से मैनिफेस्ट में सक्षम हो। इसके अलावा ऐप को विजेट को अक्षम करने के लिए, उपयोगकर्ता को विजेट सूची को 'अपडेट' करने के लिए ऐप को छोड़ने की आवश्यकता होती है यदि यह प्रोग्रामेटिक रूप से इसे मार नहीं देती है। – Cheruby

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