2015-12-21 6 views
5

का उपयोग कर कुछ डिवाइसों पर विंडो सामग्री को पढ़ने में असमर्थ है मेरी आवश्यकता: विशेष ऐप के लिए पॉप अप, डायलॉग इत्यादि से टेक्स्ट पढ़ना।एंड्रॉइड एक्सेसिबिलिटी सेवा

मैंने एक पहुंच सेवा लागू की है और मुझे अपनी आवश्यकता के अनुसार उचित घटनाएं और डेटा प्राप्त हो रहा है। हालांकि परीक्षण के दौरान मुझे एहसास हुआ कि अलर्टडिअलॉग या संवाद का उपयोग करने के बजाय कुछ उपकरणों पर उन्होंने एक गतिविधि (एक संवाद के रूप में थीम्ड) का उपयोग किया है। इसलिए मेरी पहुंच योग्यता घटना में मुझे केवल गतिविधि शीर्षक प्राप्त होता है, क्या इस तरह के पॉप अप गतिविधि द्वारा प्रदर्शित पाठ को ढूंढने का कोई तरीका है?

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

धन्यवाद

+0

मैं इसे हतोत्साहित करता हूं। हालांकि सभी जानकारी तक पहुंचने के तरीके हैं। यदि आप यादृच्छिक तृतीय पक्ष ऐप्स में हैं, तो AlertDialog के रूप में उपयोग की जाने वाली गतिविधि और केवल एक गतिविधि के बीच पहचान करने का कोई विश्वसनीय तरीका नहीं है। इस व्यवहार को मजबूर करने के लिए बस एक यादृच्छिक परिदृश्य को ठीक करने के लिए जिसमें डेवलपर्स ने अजीब चीजें करने का फैसला किया है वास्तव में संगतता के मुद्दों को पेश कर रहा है। अनिवार्य रूप से वेब एक्सेसिबिलिटी दुनिया में उपयोगकर्ता एजेंट उल्लंघन के बराबर। – ChrisCM

+0

@ChrisCM: मैं आपसे सहमत हूं। हालांकि इस मामले में यह सच नहीं है, यह कुछ रैमडोम परिदृश्य नहीं है। ऐसा लगता है कि मध्यस्थ एसडीके के साथ ऐसा लगता है क्योंकि उन्होंने एंड्रॉइड डिफ़ॉल्ट "अलर्टडिअलॉग" के बजाय "अलर्टएक्टिविटी" का उपयोग किया है। मैं इस तरह की एक सुविधा के साथ एक ऐप विकसित कर रहा हूं, मैं सभी उपकरणों का समर्थन करना चाहता हूं और यदि मैं इसे अनदेखा करता हूं तो मैं संभावित बाजार खो दूंगा। – Ishaan

+0

एंड्रॉइड एक्सेसिबिलिटी में, कभी-कभी एक फ्रिंज परिदृश्य का समर्थन करने का मतलब अपेक्षित परिदृश्य के तहत खराब व्यवहार होता है। यह दुर्भाग्यपूर्ण है, लेकिन यह सच है। मुझे काफी आश्वस्त है कि यह उन मामलों में से एक है। एक्सेसिबिलिटी एपीआई में आपको आवश्यक जानकारी नहीं होती है। – ChrisCM

उत्तर

3

एक्सेसबिलिटी नोडइन्फो का उपयोग करें जब फोन वापस लौटने के मामले में जानकारी प्राप्त करने के लिए भी हमें यूएसएसडी प्रतिक्रिया प्राप्त होगी, तो कई विकल्प दर्ज करने का विकल्प होने पर यह संवाद को खारिज कर देगा।

[पोहेन] इवेंट क्लास नाम के मामले में सबसे पहले ussdalertactivty के रूप में वापस कर दिया गया है, इसलिए मैंने यूएसएसडी प्रतिक्रिया के अलर्ट संवाद की पहचान के लिए केवल "चेतावनी" का उपयोग किया।

public void onAccessibilityEvent(AccessibilityEvent event) { 
    if (event.getPackageName().toString().equals("com.android.phone") 
         && event.getClassName().toString().toLowerCase() 
           .contains("alert")) { 

        AccessibilityNodeInfo source = event.getSource(); 

        if (source != null) { 
        String pcnResponse = fetchResponse(source); 
        } 
    } 

अब मैं एक समारोह fetchResponse कहा जाता है जो स्ट्रिंग के रूप में PCN से प्रतिक्रिया वापस आ जाएगी और यह भी खारिज करेगा संवाद तो performGlobalAction (GLOBAL_ACTION_BACK) क्या करने की जरूरत बना दिया है।

private String fetchResponse(AccessibilityNodeInfo accessibilityNodeInfo) { 

     String fetchedResponse = ""; 
     if (accessibilityNodeInfo != null) { 
      for (int i = 0; i < accessibilityNodeInfo.getChildCount(); i++) { 
       AccessibilityNodeInfo child = accessibilityNodeInfo.getChild(i); 
       if (child != null) { 

        CharSequence text = child.getText(); 

        if (text != null 
          && child.getClassName().equals(
            Button.class.getName())) { 

         // dismiss dialog by performing action click in normal 
         // cases 
         if (isUSSDFromApp 
           && (text.toString().toLowerCase().equals("ok") || text 
             .toString().toLowerCase() 
             .equals("cancel"))) { 

          child.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
          return fetchedResponse; 

         } 

        } else if (text != null 
          && child.getClassName().equals(
            TextView.class.getName())) { 

         // response of normal cases 
         if (text.toString().length() > 10) { 
          fetchedResponse = text.toString(); 
         } 

        } else if (child.getClassName().equals(
          ScrollView.class.getName())) { 

         // when response comes as phone then response can be 
         // retrived from subchild 
         for (int j = 0; j < child.getChildCount(); j++) { 

          AccessibilityNodeInfo subChild = child.getChild(j); 
          CharSequence subText = subChild.getText(); 

          if (subText != null 
            && subChild.getClassName().equals(
              TextView.class.getName())) { 

           // response of different cases 
           if (subText.toString().length() > 10) { 
            fetchedResponse = subText.toString(); 
           } 

          } 

          else if (subText != null 
            && subChild.getClassName().equals(
              Button.class.getName())) { 

           // dismiss dialog by performing action click in 
           // different 
           // cases 
           if (isUSSDFromApp 
             && (subText.toString().toLowerCase() 
               .equals("ok") || subText 
               .toString().toLowerCase() 
               .equals("cancel"))) { 
            subChild.performAction(AccessibilityNodeInfo.ACTION_CLICK); 
            return fetchedResponse; 
           } 

          } 
         } 
        } 
       } 
      } 
     } 
     return fetchedResponse; 
    } 

आशा है कि यह डिवाइस के बावजूद इस मुद्दे को हल करेगा।

+0

धन्यवाद विशाल। मेरे पास मध्यस्थ उपकरण नहीं है क्योंकि अब मुझे इसे देखने के बाद इसे जांचने दें। – Ishaan

+0

यह वास्तव में काम करता है, मैंने इसे दोबारा जांच लिया है! – Ishaan

2

इस कोड का उपयोग मैं है और यह मेरे लिए काम करता है:

public class USSDService extends AccessibilityService { 

public static String TAG = USSDService.class.getSimpleName(); 

@Override 
public void onAccessibilityEvent(AccessibilityEvent event) { 
    Log.d(TAG, "onAccessibilityEvent"); 

    AccessibilityNodeInfo source = event.getSource(); 
    if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && !String.valueOf(event.getClassName()).contains("AlertDialog")) { 
     return; 
    } 
    if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED && (source == null || !source.getClassName().equals("android.widget.TextView"))) { 
     return; 
    } 
    if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED && TextUtils.isEmpty(source.getText())) { 
     return; 
    } 

    List<CharSequence> eventText; 

    if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { 
     eventText = event.getText(); 
    } else { 
     eventText = Collections.singletonList(source.getText()); 
    } 

    String text = processUSSDText(eventText); 

    if(TextUtils.isEmpty(text)) return; 

    // Close dialog 
    performGlobalAction(GLOBAL_ACTION_BACK); // This works on 4.1+ only 

    Log.d(TAG, text); 
    // Handle USSD response here 

} 

private String processUSSDText(List<CharSequence> eventText) { 
    for (CharSequence s : eventText) { 
     String text = String.valueOf(s); 
     // Return text if text is the expected ussd response 
     if(true) { 
      return text; 
     } 
    } 
    return null; 
} 

@Override 
public void onInterrupt() { 
} 

@Override 
protected void onServiceConnected() { 
    super.onServiceConnected(); 
    Log.d(TAG, "onServiceConnected"); 
    AccessibilityServiceInfo info = new AccessibilityServiceInfo(); 
    info.flags = AccessibilityServiceInfo.DEFAULT; 
    info.packageNames = new String[]{"com.android.phone"}; 
    info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED | AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED; 
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; 
    setServiceInfo(info); 
} 
} 

एंड्रॉयड में यह घोषित प्रकट

<service android:name=".USSDService" 
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> 
<intent-filter> 
    <action android:name="android.accessibilityservice.AccessibilityService" /> 
</intent-filter> 
<meta-data android:name="android.accessibilityservice" 
    android:resource="@xml/ussd_service" /> 

एक xml फ़ाइल का वर्णन करता है बनाएं ussd_service

नामक अभिगम्यता सेवा
<?xml version="1.0" encoding="utf-8"?> 
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" 
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged" 
android:accessibilityFeedbackType="feedbackGeneric" 
android:accessibilityFlags="flagDefault" 
android:canRetrieveWindowContent="true" 
android:description="@string/accessibility_service_description" 
android:notificationTimeout="0" 
android:packageNames="com.android.phone" /> 
+0

यह अभी भी माइक्रोमैक्स, लेनोवो डिवाइस –

+0

@ हेनबॉय 331 के लिए मदद नहीं कर रहा है: आपके कोड के लिए धन्यवाद। मुझे इसे आज़माएं। – Ishaan

+0

मुझे event.gettext() का उपयोग करके ussd संवाद संदेश नहीं मिल रहा है; मैं "फोन" प्राप्त कर रहा हूं .. ussd संवाद के मूल संदेश के लिए मदद करने की आवश्यकता है। –

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