Hat Talkback ein Privileg, damit das Ergebnis der Framelayout -Klasse von AccessitilityNodeInfo.getContentDescription ()Android

Forum für diejenigen, die für Android programmieren
Anonymous
 Hat Talkback ein Privileg, damit das Ergebnis der Framelayout -Klasse von AccessitilityNodeInfo.getContentDescription ()

Post by Anonymous »

Ich arbeite derzeit daran, eine App zu entwickeln, die von einer Chating -App über AccessilitySerivce Paket von einer Chat -App abgerufen wird.
Ich habe gelernt Traversalfunktion, AccessiafityNodeInfo Knoten mit der Framelayout -Klasse in RecyClerview Gibt die ContentDescription des UI -Elements zurück. Aber ich habe Null zurückgegeben, als ich die Methode verwendet habe, indem ich das einzige AccessIBilityservice -Paket verwendet habe. Inhalt von AccessibilityNodeInfo.getContentDescription () , die den Inhalt der Nachrichten -Chat -Blasen erfolgreich zurückgegeben hat. S Privilegien Erlaubnis, damit es möglich ist. Ich habe herausgefunden, dass der derzeit besuchende Framelayout ContentDescription erfolgreich eingeht, wenn Talkback eingeschaltet ist, sodass die Chat -Blase den intakten Inhalt zurückgibt (wie Nachrichtentext, Lautsprecher und Zeitstempel).
Die Programmdetails, die ich angegeben habe />

Code: Select all




























Accessibility_Service_Config.xml:

Code: Select all


MyAccessibilityService.java:

Code: Select all

package com.example.test1;
import android.accessibilityservice.AccessibilityService;
import android.os.Looper;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.util.Log;
import java.lang.String;
import java.util.List;
import java.util.logging.Handler;

public class MyAccessibilityService extends AccessibilityService {
private void extractChatBubbles(AccessibilityNodeInfo node) {
// base case
if (node == null) return;

CharSequence nodeClassName = node.getClassName();
// TextView
if (nodeClassName != null && nodeClassName.toString().contains("TextView")) {
CharSequence text = node.getText();

if(text == null) {
Log.i("ChatContent", "[Contents] " + node.getContentDescription());
}

if (text != null && text.length() > 0) {
Log.i("ChatContent", "[Name] "  + text.toString());
}
}

// RecyclerView
if (node.getClassName().equals("androidx.recyclerview.widget.RecyclerView")) {
Log.d("RecyclerView", "RecyclerView Detected!");

for (int i = 0; i < node.getChildCount(); i++) {
AccessibilityNodeInfo child = node.getChild(i);
Log.d("RecyclerView", "DetectedItem: " + child.getContentDescription() + "/ " + child.toString());
extractChatBubbles(child);
}
}

// FrameLayout
if (node.getChildCount() > 0 && node.getClassName().toString().contains("FrameLayout")) {
Log.i("FrameLayout", "FrameLayout children");
for (int i = 0; i < node.getChildCount(); i++){
if(node.getChild(i) != null) {
Log.i("FrameLayout", node.getChild(i).toString());
} else {
Log.i("FrameLayout", i+"th child is null");
}
}
}

// ViewGroup
if (node.getChildCount() > 0 && node.getClassName().toString().contains("ViewGroup")) {
Log.i("ViewGroup", "ViewGroup children");
for (int i = 0; i < node.getChildCount(); i++){
AccessibilityNodeInfo currentClass = node.getChild(i);
if(node.getChild(i) != null) {
Log.i("ViewGroup", "Class: " + currentClass.getClassName() + ", " + currentClass.getText() + ", " +currentClass.getContentDescription());
if(currentClass.getClassName().toString().contains("ImageView")) {
Log.d("ImageView", currentClass.toString());
}
} else {
Log.i("ViewGroup", i+"th child is null");
}
}
}

// Recursively traverse child nodes
for (int i = 0; i < node.getChildCount(); i++) {
extractChatBubbles(node.getChild(i));
}
}

// For traversing other windows
private void traverseNode(AccessibilityNodeInfo node) {
if (node == null) return;

// print current node text
CharSequence text = node.getText();
if (text != null) {
Log.d("Other Windows", "Text: " + text.toString() + ", Description: " + node.getContentDescription());
}

// Recursively traverse child nodes
for (int i = 0; i < node.getChildCount(); i++) {
AccessibilityNodeInfo childNode = node.getChild(i);
traverseNode(childNode);
}
}

@Override
public void onServiceConnected() {
super.onServiceConnected();
AccessibilityServiceInfo info = this.getServiceInfo();

info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
info.flags |= AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
info.flags |= AccessibilityServiceInfo.DEFAULT;
info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;

this.setServiceInfo(info);
}

@Override
public void onInterrupt() {
Log.d("AccessibilityService", "Service Stopped.");
}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED ||
event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED ||
event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED ||
event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED ||
event.getEventType() == AccessibilityEvent.TYPE_VIEW_SELECTED ||
event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY) {

// Find out current foreground app is the target chat app
if (event.getPackageName() != null &&  event.getPackageName().toString().equals("com.target.chat")) {
if(event.getSource() != null) {
Log.i("Accessibility", "Current Event name: " + event.getSource().getClassName());
}
Log.i("Accessibility", "Target Chat app detected! start extracting chat bubbles");

List windows = getWindows();
if(windows.isEmpty()) {
Log.d("WindowsDetect", "No windows found" );
} else {
Log.d("WindowsDetect", windows.size() + " windows detected" );
}

for (AccessibilityWindowInfo window : windows) {
Log.d("WindowsDetect", "current window: " + window.toString());
AccessibilityNodeInfo root = window.getRoot();

if(root == null) {
Log.d("WindowsDetect", "root is null" );
continue;
} else {
Log.d("WindowsDetect", "current root: " + root.toString());
}

traverseNode(root);
}

AccessibilityNodeInfo rootNode = getRootInActiveWindow();
rootNode.performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
Log.i("Accessibility", "Root Node " + rootNode.getClassName() + "'s number of children: " + rootNode.getChildCount());
new android.os.Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {

if (rootNode != null) {
extractChatBubbles(rootNode);
} else {
Log.e("RootNode", "rootNode is null");
}
}
}, 2000);
}
}
}
}
< /code>
Und was ich getan habe, sind wie folgt: < /p>
[list]
[*] Versuchte alle Flags, Sie können es unter myAccessibilityService.onserviceConnected () 
[*] Versucht, jede Option in Accessibility_Service_Config.xml (wie Android: CanRetReveWindowContent = "TRUE" )
[*] Analysierte die gesamten Barrierefreiheitsklassen wie AccessisileService , AccessibilityInteractionClient , AccessibilityNodeInfo , aber nichts schien für meine Frage so besonders zu sein etwas verpasste. /Code> Innen, aber jeder Code -Teil des Talkback Github -Inhalt scheint so besonders für Talkback Privilegien zu haben.
[/list]
p.s.>

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post