2012-06-14 9 views
12

मैं एक थर्ड-पार्टी लाइब्रेरी का उपयोग कर रहा हूं और कभी-कभी यह एक संवाद पॉप अप करता है। वर्तमान गतिविधि को समाप्त करने से पहले, मैं यह जांचना चाहता हूं कि वर्तमान संदर्भ में एक संवाद पॉप अप है या नहीं।कैसे जांचें कि वर्तमान गतिविधि में एक संवाद है या नहीं?

क्या इसके लिए कोई एपीआई है?

+1

आप किस तीसरे पक्ष की लाइब्रेरी का उपयोग कर रहे हैं और आप किस प्रकार का ऐप काम कर रहे हैं? –

उत्तर

7

AFAIK - इसके लिए कोई सार्वजनिक एपीआई नहीं है।

अनुशंसित तरीका संवाद का संदर्भ होना है, और isShowing() के लिए जांचें और यदि आवश्यक हो तो dismiss() पर कॉल करें, लेकिन चूंकि आप किसी तृतीय पक्ष लाइब्रेरी का उपयोग कर रहे हैं, तो यह आपके लिए कोई विकल्प नहीं हो सकता है।

आपकी सबसे अच्छी शर्त आपके द्वारा उपयोग की जाने वाली लाइब्रेरी के लिए दस्तावेज़ों की जांच करना है। अगर इससे मदद नहीं मिलती है, तो आप भाग्य से बाहर हैं।

संकेत: यदि कोई संवाद पॉप अप हो जाता है तो गतिविधि 'रुका हुआ' स्थिति में स्विच हो जाती है। आप इस व्यवहार को 'दुरुपयोग' करने में सक्षम हो सकते हैं;)

+0

क्या रोकथाम में संवाद आईडी का कोई तरीका है? – newme

+1

हम्म ... मुझे आपकी समस्या दिखाई देती है .... आप ऑनक्रेटडियलॉग विधि को ओवरराइड करने का प्रयास कर सकते हैं। वर्तमान में खुले संवाद के लिए आपको आईडी की एक सूची बनाए रखना होगा और जब आप बाहर निकलना चाहते हैं तो उन्हें बंद कर दें। केवल इस विधि का उपयोग करें यदि आप जिस लाइब्रेरी का उपयोग कर रहे हैं वह इसका समर्थन नहीं करता है।यदि आप अप्रत्याशित रूप से अपने संवाद बंद करते हैं तो आप तृतीय पक्ष लाइब्रेरी से समस्याओं में भाग ले सकते हैं। (शून्य सूचक मज़ेदार) – Madushan

+0

इसके अलावा, कृपया ध्यान दें कि इस पद्धति और खारिज डीअलॉग विधि को टुकड़े पैटर्न के पक्ष में बहिष्कृत किया गया है। तो मैं नहीं कहूंगा कि यह सबसे अच्छा तरीका है। और ऐसा लगता है कि जब कोई संवाद बंद हो जाता है तो आप इसका पता नहीं लगा सकते हैं (सिवाय इसके कि आप इसे रोक सकते हैं जब गतिविधि रोक से शुरू होती है। लेकिन यह सुनिश्चित करने के लिए जांचें कि स्क्रीन से फिर से शुरू होने पर यह भी होता है)। तो आपको सभी ज्ञात संवाद आईडी पर 'dismissDialog' को कॉल करना होगा, जो ... अच्छा है .... मैं हास्यास्पद कहूंगा। – Madushan

9

मुझे एक ही समस्या का सामना करना पड़ा, और उन सभी स्थानों को संशोधित नहीं करना चाहता था जहां संवाद बनाए जा रहे थे और दिखाए गए थे। मेरा समाधान यह देखने के लिए था कि मैं जिस दृश्य को दिखा रहा था वह hasWindowFocus() विधि के माध्यम से विंडो फोकस था। यह सभी परिस्थितियों में काम नहीं करेगा, लेकिन मेरे विशेष मामले में काम करता है (यह एक आंतरिक रिकॉर्डिंग ऐप के लिए था जो काफी प्रतिबंधित परिस्थितियों में उपयोग किया जाता था)।

इस समाधान को मजबूती के लिए पूरी तरह से परीक्षण नहीं किया गया था, लेकिन मुझे लगा कि मैं किसी की मदद करने के मामले में पोस्ट करूंगा।

+0

मुझे लगता है कि यह ज्यादातर मामलों के लिए अच्छा समाधान है – Pradeep

12

आप देख सकते हैं यह है कि गतिविधि के सक्रिय टुकड़े से अधिक चल रहा है और पता चल सके कि उनमें से एक DialogFragment है, जिसका अर्थ है वहाँ स्क्रीन पर एक सक्रिय संवाद है कि: के साथ काम कर

public static boolean hasOpenedDialogs(FragmentActivity activity) { 
     List<Fragment> fragments = activity.getSupportFragmentManager().getFragments(); 
     if (fragments != null) { 
      for (Fragment fragment : fragments) { 
       if (fragment instanceof DialogFragment) { 
        return true; 
       } 
      } 
     } 

     return false; 
    } 
+0

क्या खारिज संवाद संवाद फ्रैगमेंट मैनेजर – twlkyao

+0

से हटा दिया जाएगा, मैं पॉप देखता हूं और पल को खारिज कर देता हूं आंतरिक, लेकिन विधि getFragments केवल उसी लाइब्रेरी समूह के भीतर से ही बुलाया जा सकता है। रूट दृश्य (सजावट दृश्य) से – twlkyao

1

मैं यह सोचते हैं रहा हूँ, आप कर रहे हैं तृतीय पक्ष लाइब्रेरी और आपके पास संवाद ऑब्जेक्ट तक पहुंच नहीं है।

आप गतिविधि से जड़ दृश्य प्राप्त कर सकते

तो फिर तुम पेड़ ट्रेवर्सल एल्गोरिथ्म का उपयोग आप बच्चे को देखने के लिए किसी भी पहुँच सकते हैं, तो देखने के लिए कर सकते हैं। यदि अलर्ट बॉक्स प्रदर्शित होता है तो आपको अपने किसी भी बच्चे के दृश्य तक नहीं पहुंचना चाहिए।

जब अलर्ट व्यू प्रदर्शित होता है (यू ऑटोमेटर के साथ जांचें), यूआई पेड़ में मौजूद एकमात्र तत्व डायलॉगबॉक्स/डायलॉग एक्टिविटी से है। आप इस चाल का उपयोग यह देखने के लिए कर सकते हैं कि स्क्रीन पर संवाद प्रदर्शित होता है या नहीं। हालांकि यह महंगा लगता है, इसे अनुकूलित किया जा सकता है।

+0

आप डायलॉग तक नहीं पहुंच सकते क्योंकि संवाद एक और विंडो में है। मैं क्या कर सकता हूं सजावट से केवल एकमात्र सदस्य तक पहुंचता है जो 'mPrivateFlags' है और यह संवाद खुला होने पर '25201976' से' 29363512' तक जाता है। अगला काम यहां से उपयोगी उपयोगी झंडे ढूंढना है https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/View.java#L1737 हार्ड –

+0

हम्म होना चाहिए, शायद 'हैविंडोफोकस' ऐसा करेगा लेकिन मुझे अधिक परीक्षण –

6

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

मैंने एंड्रॉइड 4.1 से एंड्रॉइड 6.0 तक संगतता की पुष्टि की है लेकिन निश्चित रूप से यह पहले या बाद के एंड्रॉइड संस्करणों में काम नहीं कर सकता है।

मैंने बहु-विंडो मोड के लिए व्यवहार की जांच नहीं की है।

@SuppressWarnings("unchecked") 
public static List<ViewParent> getViewRoots() { 

    List<ViewParent> viewRoots = new ArrayList<>(); 

    try { 
     Object windowManager; 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
      windowManager = Class.forName("android.view.WindowManagerGlobal") 
        .getMethod("getInstance").invoke(null); 
     } else { 
      Field f = Class.forName("android.view.WindowManagerImpl") 
        .getDeclaredField("sWindowManager"); 
      f.setAccessible(true); 
      windowManager = f.get(null); 
     } 

     Field rootsField = windowManager.getClass().getDeclaredField("mRoots"); 
     rootsField.setAccessible(true); 

     Field stoppedField = Class.forName("android.view.ViewRootImpl") 
       .getDeclaredField("mStopped"); 
     stoppedField.setAccessible(true); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
      List<ViewParent> viewParents = (List<ViewParent>) rootsField.get(windowManager); 
      // Filter out inactive view roots 
      for (ViewParent viewParent : viewParents) { 
       boolean stopped = (boolean) stoppedField.get(viewParent); 
       if (!stopped) { 
        viewRoots.add(viewParent); 
       } 
      } 
     } else { 
      ViewParent[] viewParents = (ViewParent[]) rootsField.get(windowManager); 
      // Filter out inactive view roots 
      for (ViewParent viewParent : viewParents) { 
       boolean stopped = (boolean) stoppedField.get(viewParent); 
       if (!stopped) { 
        viewRoots.add(viewParent); 
       } 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    return viewRoots; 
} 
+1

की आवश्यकता है अब हमें यह पता लगाने का एक तरीका चाहिए कि यह कार्रवाई कब हुई थी। अब तक ऐसा लगता है कि 'ऑनसिस्टम यूविज़िबिलिटी चेंजलिस्टर' _first_ समय को एक गतिविधि पर एक संवाद दिखाता है, लेकिन बाद में नहीं। मैं खुदाई रखूंगा। – VicVu

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