2017-07-04 56 views
8

我很好奇,前幾天我看到這個應用程序允許它打開其他應用程序並自動爲您設置某些功能。我已經意識到它必須使用某種屏幕上的點擊功能,但我似乎無法找到任何像這樣的文檔。例如,如果我們知道從其他應用程序屏幕上的文字是「就緒」,有沒有辦法來閱讀這些文字,也許這樣做:Android可點擊屏幕上的文字

protected void processText(String text) 
{ 
    if (text.contains("Ready")) 
     // click the ready text 
} 
+0

你想點擊文字或使文字的一部分可點擊,或獲得屏幕點擊座標嗎?有關前者的信息可以在此處獲得:https://www.google.com.ng/url?url=https://stackoverflow.com/questions/10696986/how-to-set-the-part-of-the -text - 視圖 - 是 - 點擊&RCT = J&SA = U&VED = 0ahUKEwilotjX6-7UAhXIYlAKHfF8BwgQFggbMAA&q =的Android +讓+ +文字+的一部分+點擊與USG = AFQjCNEVpYcyHrHbO5NKt5jBPVqAjpNiFg –

+0

@財經部,hendyEjegi我想點擊的文本,而無需自己做的用戶。但由於它在另一個應用程序上,我無法點擊它,這正是我想要解決的問題。 – Jayce

+0

檢查輔助功能api,所有我可以幫助更多的信息閱讀https://stackoverflow.com/questions/35842762/how-to-read-window-content-using-accessibilityservice-and-evoking-ui-using-dra – ingsaurabh

回答

3

我已經使用AccessibilityService完成了這項工作。它只會在API級別> = 16時正常工作。您需要延長AccessibilityService。例如,這個類將獲得USSD響應文本並關閉對話框。

// .... 
public class UssdAccessibilityService extends AccessibilityService { 
    public UssdAccessibilityService() { 
    } 

    @TargetApi(16) 
    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
     if (!"com.android.phone".equalsIgnoreCase((String)event.getPackageName())){ 
      // In this example we are only interested in events comming 
      // from "com.android.phone" package 
      event.recycle(); 
      return; 
     } 

     String className = (String)event.getClassName(); 
     if (className == null || (!className.contains("AlertDialog") && !className.contains("AlertDialog"))){ 
      // Class is not an USSD dialog 
      event.recycle(); 
      return; 
     } 

     AccessibilityNodeInfo source = event.getSource(); 
     if (source == null) { 
      // getSource() is annotated @Nullable, so we do this to be 
      // safe just in case 
      event.recycle(); 
      return; 
     } 

     AccessibilityNodeInfo acceptButton = null; 
     String ussdText = null; 

     int childCount = source.getChildCount(); 
     for (int i = 0; i < childCount; i++){ 
      AccessibilityNodeInfo current = source.getChild(i); 
      if (current == null) 
       continue; 

      String currentText = (String)current.getText(); 
      if (current.isClickable()){ 
       // In the case of USSD dialogs, there is only one clickable. 
       // May be necessary to do more robust search in other scenarios 
       acceptButton = current; 
       continue; 
      } 

      ussdText = currentText; 

      current.recycle(); 
     } 

     if (ussdText!= null) { 
      if (acceptButton != null) 
       acceptButton.performAction(AccessibilityNodeInfo.ACTION_CLICK); 

     } 

     source.recycle(); 
     event.recycle(); 
    } 

    // .... 
} 

您必須<application>

<service 
     android:name=".UssdAccessibilityService" 
     android:enabled="true" 
     android:label="Read USSD codes and dismiss" 
     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/accessibility_service_config" /> 
</service> 

下申報清單中的輔助服務在res/xml創建accessibility_service_config.xml

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" 
    android:description="@string/accessibility_service_description" 
    android:packageNames="com.android.phone,com.ats.android.activationcodebot" 
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged" 
    android:accessibilityFlags="flagDefault" 
    android:accessibilityFeedbackType="feedbackSpoken" 
    android:notificationTimeout="100" 
    android:canRetrieveWindowContent="true" 
    /> 

當然你有這個代碼適應自己的需要。

最後,您必須在Android上手動啓用無障礙服務設置>輔助功能(或要求用戶這樣做)。

閱讀全文...Developing an Accessibility Service

+0

我會盡快嘗試,只要我今天回家,並讓你知道它是否適合我。它與我已有的代碼類似,但由於某些原因,我的代碼並不總是「點擊」屏幕。 – Jayce

+0

我還沒有看到你的代碼,但一定要遍歷整個樹,尋找你想要的可點擊的視圖。 –

+0

此外,請確保不要在'onAccessibilityEvent()'內部使用任何實例或類字段進行臨時存儲,因爲這會使線程不安全。如果您確實需要使用實例字段,請使用'synchronized(lockObject){}'以確保對'onAccessibilityEvent()'的所有調用都能夠嚴格執行。 –

3

爲了能夠做到這一點從其他應用程序,你需要捕獲屏幕並使用文本識別服務確定文本位置。

當另一個應用程序處於活動狀態時,則應用程序應處於活動狀態才能捕獲屏幕。所以你只能使用總是起作用背景的android服務。

但是捕捉截圖爲您的活動,你必須需要你activity的視圖,哪一個是不存在於你的service,所以你必須做出TimerTask將打電話給你的活動在每一個小時,你的activity響應它以當前出現的視圖,您可以從中捕獲ScreenShot。

,或者如果你想利用你的當前設備屏幕的截圖(任何應用程序),那麼你有root權限,讀framebuffer對於這將給當前畫面的原始數據,然後將其轉換爲位圖或任何圖片文件,你可以在你的服務中做到這一點。

簡而言之,它可能有根電話。否則,如果您沒有植根,則無法截取其他應用程序的屏幕截圖。只允許截取你的應用程序的屏幕截圖。

爲了能夠分析屏幕是否存在任何「就緒」文本。您的應用程序應該是生活/活動的,以便能夠捕捉屏幕。

+0

我正在使用AccessibilityNodeInfo,我相信現在可以使用它了,無需root。只需要搞清楚一些調整,我應該走在正確的軌道上。 – Jayce

0

而不是嘗試閱讀文本使用廣播接收器,並在每次廣播檢查textviews長度設置時,啓動應用程序或做任何你想做的事情。

+0

你有一個例子嗎? – Jayce