Italian Gestione USB e alimentazione

Fulvio75

Well-Known Member
Licensed User
non funziona perchè davanti c'è il layout trasparente dell'applicazione attiva quindi non clicca sulle icone della home page, ma se metti un bottone sul tuo layout e utilizzi il click virtuale su un bottone della tua app dove c'è il codice funziona.
Idem per il menù di spegnimento che non fa parte della app quindi il click virtuale non va.😭😭
 

Star-Dust

Expert
Licensed User
Longtime User
in alcune mie app utilizzo "accessibility service" per automatizzare certe procedure (ad esempio l'invio di messaggi tramite whatsapp) senza l'intervento dell'utente.
Finora non ho mai avuto grosse difficoltà e le app funzionano, ma quando ho visto questo thread di @Fulvio75 mi sono reso conto che potrei incontrare schermate dove potrebbero esserci degli oggetti che non cliccabili e quindi, in previsione di ciò, mi piacerebbe capire come eventualmente risolvere il problema con un touch in un punto preciso dello schermo



Si, questo l'ho fatto anche io, a me serviva farlo su elementi non cliccabili
Riavvio da codice, usando Accessibility Service. Apro il pannello di scelta e clicco su spegni, confermo, tutto da codice.

ezgif.com-crop.gif
 
Last edited:

sirjo66

Well-Known Member
Licensed User
Longtime User
Premetto che sto usando la libreria di @moster67

(mi referisco alla pagina https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo )

Nell'evento acs_OnAccessibilityEvent(Event As Object, Node As Object), tramite "Node", riesco ad analizzare tutti gli elementi che costituiscono la schermata.
Usando JavaObject riesco ad accedere alle View, ed a estrarre tutte le proprietà che mi servono, quali, ad esempio:
B4X:
    For x = 0 To nodesCount - 1
        Dim obj As JavaObject = nodes.RunMethodJO("get", Array As Object(x)) ' get the node
        Dim ViewId As String = obj.RunMethod("getViewIdResourceName", Null).As(String)
        Dim ClassName As String = obj.RunMethod("getClassName", Null).As(String)
        Dim isClickable As Boolean = obj.RunMethod("isClickable", Null).As(Boolean)
        Dim text As String = obj.RunMethod("getText", Null).As(String)

        ......... analisi dell'elemento

    Next

Come vedi c'è la proprietà isClickable che mi dice se l'oggetto che sto analizzando è cliccabile.
Se è cliccabile nessun problema, faccio
B4X:
obj.RunMethod("performAction", Array As Object(AccServConstants.ACTION_CLICK))
e funziona perfettamente

Sul mio telefono con Android 12, faccio
B4X:
acs.PerformGlobalAction(AccServConstants.GLOBAL_ACTION_POWER_DIALOG)
per aprire la schermata di spegnimento, analizzo la schermata, quando trovo isClickable = True e text = "Spegni", eseguo il click, mi si apre la seconda schermata, faccio la stessa analisi, faccio click e funziona perfettamente, il telefono si spegne da solo.

Ma su un telefono Android 8, quando appare la schermata di spegnimento, analizzandola non c'è nessun oggetto isClickable, sebbene ho trovato tutti gli oggetti regolarmente, anche quello con il text = "Spegni".
Se provo comunque a fare il ACTION_CLICK su quell'oggetto non succede nulla, non è proprio cliccabile da accessibility_service

Ecco il perchè mi piacerebbe capire come poter fare un touch su un punto qualsiasi dello schermo semplicemente passandogli le coordinate.
Il codice java che avevo postato è corretto ?
Perchè la funzione dispatchGesture mi ritorna True ma in realtà non ha fatto nulla ??
 

Star-Dust

Expert
Licensed User
Longtime User
Ho provato sia il metodo JavaObject sia il metodo Inline Java Code, ma entrambe non funzionano :(
Mi sono ricavato le coordinate del pulsante "Spegni", e mi sono calcolato il punto centrale (su cx e cy)

Poi ho tradotto il codice in

B4X:
            Dim clickPath As JavaObject
            clickPath.InitializeNewInstance("android.graphics.Path", Null)
            clickPath.RunMethod("moveTo",Array As Object(cx, cy))

            Dim startTime As Long = 0
            Dim duration As Long = 10
            Dim clickStroke As JavaObject
            clickStroke.InitializeNewInstance("android.accessibilityservice.GestureDescription.StrokeDescription", Array As Object(clickPath, startTime, duration))
          
            Dim clickBuilder As JavaObject
            clickBuilder.InitializeNewInstance("android.accessibilityservice.GestureDescription.Builder", Null)
            clickBuilder.RunMethod("addStroke", Array As Object(clickStroke))
          
            Dim gestureDescription As JavaObject
            gestureDescription = clickBuilder.RunMethodJO("build", Null)
          
            Dim accServ As JavaObject
            accServ.InitializeContext
            Dim ok As Boolean
            ok = accServ.RunMethod("dispatchGesture", Array As Object(gestureDescription, Null, Null)).As(Boolean)

alla fine la variabile ok = True ma sul telefono il pulsante non viene premuto

Ho provato anche il Inline Java Code ma niente da fare.
Ho definito la routine
B4X:
#If JAVA
public boolean clickOnWindow(float x, float y) {
    // for a single tap a duration of 1 ms is enough
    final int DURATION = 1;

    android.graphics.Path clickPath = new android.graphics.Path();
    clickPath.moveTo(x, y);
    android.accessibilityservice.GestureDescription.StrokeDescription clickStroke =
            new android.accessibilityservice.GestureDescription.StrokeDescription(clickPath, 0, DURATION);
    android.accessibilityservice.GestureDescription.Builder clickBuilder = new android.accessibilityservice.GestureDescription.Builder();
    clickBuilder.addStroke(clickStroke);
    return dispatchGesture(clickBuilder.build(), null, null);
}
#End If

e poi chiamata così:
B4X:
            Dim jo As JavaObject
            jo.InitializeContext
            Dim flag As Boolean = jo.RunMethod("clickOnWindow", Array As Object(cx, cy))

anche stessa cosa, la variabile "flag" è true ma sul telefono nessun segno di vita
Sembra giusto. Duration mettilo a 100 altrimenti non percepisci nemmeno il tocco. Le impostazioni di Windows il minimo di un click e è tra i 50ms e 200ms
 
Last edited:

sirjo66

Well-Known Member
Licensed User
Longtime User
Ho provato sia con 100 che con 200 ma non accade nulla
Vedrò di fare un piccolo progettino di test
 

Star-Dust

Expert
Licensed User
Longtime User
Comunque è fattibile, Se vedi anche il progetto che ha venduto @sfsameer riusciva a fare qualcosa di simile a TeamViewer e comandare lo smartphone a distanza dal PC. Muovendo il mouse e eseguendo il click
 

Star-Dust

Expert
Licensed User
Longtime User
Quindi sei a buon punto se riesci a far apparire il menu. Ti manca solo il click

Vedi questo link
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Non ho idea di come farlo non ho fatto nulla, compare il menù di spegnimento e faccio a mano chiudi
come ti ho già detto devi analizzare la schermata da dentro l'evento acs_OnAccessibilityEvent, ma se non mostri un po' di codice non possiamo aiutarti
 

Fulvio75

Well-Known Member
Licensed User
come ti ho già detto devi analizzare la schermata da dentro l'evento acs_OnAccessibilityEvent, ma se non mostri un po' di codice non possiamo aiutarti
Il codice è quello che ho scritto sopra per fare comparire il menù
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Quindi sei a buon punto se riesci a far apparire il menu. Ti manca solo il click

Vedi questo link

Purtroppo su quel link dicono che non si riesce a fare il "click".
Il valore di ritorno di dispatchGesture è True ma non succede nulla, praticamente lo stesso problema che ho io con il mio codice.
 

Star-Dust

Expert
Licensed User
Longtime User
Purtroppo su quel link dicono che non si riesce a fare il "click".
Il valore di ritorno di dispatchGesture è True ma non succede nulla, praticamente lo stesso problema che ho io con il mio codice.
Si, bisogna solo correggere qualcosina...
 

sirjo66

Well-Known Member
Licensed User
Longtime User
eccoti uno spunto
B4X:
Sub acs_OnAccessibilityEvent(Event As Object, Node As Object)
    
    Dim evento As JavaObject = Event
    Dim nodo As JavaObject = Node

    Dim EventType As Int = evento.RunMethod("getEventType", Null).As(Int)
    Dim PackageName As String = evento.RunMethod("getPackageName", Null).As(String)

    Dim nodes As JavaObject = nodo.RunMethod("get", Array As Object(0)) ' get all nodes
    Dim nodesCount As Int = nodes.RunMethod("size", Null).As(Int) ' get the nodes count
    
    For x = 0 To nodesCount - 1
        Dim obj As JavaObject = nodes.RunMethodJO("get", Array As Object(x)) ' get the node
        Dim ViewId As String = obj.RunMethod("getViewIdResourceName", Null).As(String) ' get the ViewId
        Dim ClassName As String = obj.RunMethod("getClassName", Null).As(String)
        Dim isClickable As Boolean = obj.RunMethod("isClickable", Null).As(Boolean)

        ' ..... adesso faccio l'analisi dell'oggetto che ho trovato e se devo farci click sopra.........
        If devoFarciClickSopra Then
            obj.RunMethod("performAction", Array As Object(AccServConstants.ACTION_CLICK))
            Return
        End If

    Next
    
End Sub
 

Fulvio75

Well-Known Member
Licensed User
eccoti uno spunto
B4X:
Sub acs_OnAccessibilityEvent(Event As Object, Node As Object)
   
    Dim evento As JavaObject = Event
    Dim nodo As JavaObject = Node

    Dim EventType As Int = evento.RunMethod("getEventType", Null).As(Int)
    Dim PackageName As String = evento.RunMethod("getPackageName", Null).As(String)

    Dim nodes As JavaObject = nodo.RunMethod("get", Array As Object(0)) ' get all nodes
    Dim nodesCount As Int = nodes.RunMethod("size", Null).As(Int) ' get the nodes count
   
    For x = 0 To nodesCount - 1
        Dim obj As JavaObject = nodes.RunMethodJO("get", Array As Object(x)) ' get the node
        Dim ViewId As String = obj.RunMethod("getViewIdResourceName", Null).As(String) ' get the ViewId
        Dim ClassName As String = obj.RunMethod("getClassName", Null).As(String)
        Dim isClickable As Boolean = obj.RunMethod("isClickable", Null).As(Boolean)

        ' ..... adesso faccio l'analisi dell'oggetto che ho trovato e se devo farci click sopra.........
        If devoFarciClickSopra Then
            obj.RunMethod("performAction", Array As Object(AccServConstants.ACTION_CLICK))
            Return
        End If

    Next
   
End Sub
Ok grazie provo
 

Fulvio75

Well-Known Member
Licensed User
E' molto instabile, l'apertura del menù di chiusura funzionava fino a qualche giorno fa, ora senza toccare nulla continua a propormi la pagina di consenso di accessibility per l'applicazione anche se già su ON, AccessibilitySevices.IsAccessibilityServiceEnabled è sempre = False anche se realmente è impostato su ON.
 

sirjo66

Well-Known Member
Licensed User
Longtime User
E' molto instabile, l'apertura del menù di chiusura funzionava fino a qualche giorno fa, ora senza toccare nulla continua a propormi la pagina di consenso di accessibility per l'applicazione anche se già su ON, AccessibilitySevices.IsAccessibilityServiceEnabled è sempre = False anche se realmente è impostato su ON.

Si, succede spesso, devi spostare su OFF, e poi riselezionare su ON, a quel punto funziona
 
Top