Ich möchte wissen, wie man ein Ziehen auf Android basierend auf X-, Y-Mauskoordinaten durchführt. Betrachten Sie als zwei einfache Beispiele den Team Viewer / QuickSupport, der das "Kennwortmuster" auf dem Remote-Smartphone bzw. dem Stift von Windows Paint zeichnet.
Alles was ich machen kann ist eine Berührung zu simulieren (mit dispatchGesture()
und auch AccessibilityNodeInfo.ACTION_CLICK
).
Ich habe diese relevanten Links gefunden, weiß aber nicht, ob sie nützlich sein können:
- Führen Sie mit AccessibilityService ein Wischen auf dem Bildschirm durch
- Beispiel 1
- Fortsetzung der Gesten
Unten ist mein Arbeitscode, der verwendet wird, um Mauskoordinaten (innerhalb der PictureBox
Steuerung) an ein entferntes Telefon zu senden und Berührungen zu simulieren.
Windows Forms-Anwendung:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
foreach (ListViewItem item in lvConnections.SelectedItems)
{
// Remote screen resolution
string[] tokens = item.SubItems[5].Text.Split('x'); // Ex: 1080x1920
int xClick = (e.X * int.Parse(tokens[0].ToString())) / (pictureBox1.Size.Width);
int yClick = (e.Y * int.Parse(tokens[1].ToString())) / (pictureBox1.Size.Height);
Client client = (Client)item.Tag;
if (e.Button == MouseButtons.Left)
client.sock.Send(Encoding.UTF8.GetBytes("TOUCH" + xClick + "<|>" + yClick + Environment.NewLine));
}
}
Bearbeiten:
Mein letzter Versuch war ein "Wischbildschirm" mit Mauskoordinaten (C # Windows Forms-Anwendung) und eine benutzerdefinierte Android-Routine (unter Bezugnahme auf den oben verlinkten Code des "Wischbildschirms"):
private Point mdownPoint = new Point();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
foreach (ListViewItem item in lvConnections.SelectedItems)
{
// Remote screen resolution
string[] tokens = item.SubItems[5].Text.Split('x'); // Ex: 1080x1920
Client client = (Client)item.Tag;
if (e.Button == MouseButtons.Left)
{
xClick = (e.X * int.Parse(tokens[0].ToString())) / (pictureBox1.Size.Width);
yClick = (e.Y * int.Parse(tokens[1].ToString())) / (pictureBox1.Size.Height);
// Saving start position:
mdownPoint.X = xClick;
mdownPoint.Y = yClick;
client.sock.Send(Encoding.UTF8.GetBytes("TOUCH" + xClick + "<|>" + yClick + Environment.NewLine));
}
}
}
private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
{
foreach (ListViewItem item in lvConnections.SelectedItems)
{
// Remote screen resolution
string[] tokens = item.SubItems[5].Text.Split('x'); // Ex: 1080x1920
Client client = (Client)item.Tag;
if (e.Button == MouseButtons.Left)
{
xClick = (e.X * int.Parse(tokens[0].ToString())) / (pictureBox1.Size.Width);
yClick = (e.Y * int.Parse(tokens[1].ToString())) / (pictureBox1.Size.Height);
client.sock.Send(Encoding.UTF8.GetBytes("MOUSESWIPESCREEN" + mdownPoint.X + "<|>" + mdownPoint.Y + "<|>" + xClick + "<|>" + yClick + Environment.NewLine));
}
}
}
android AccessibilityService :
public void Swipe(int x1, int y1, int x2, int y2, int time) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
System.out.println(" ======= Swipe =======");
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
Path path = new Path();
path.moveTo(x1, y1);
path.lineTo(x2, y2);
gestureBuilder.addStroke(new GestureDescription.StrokeDescription(path, 100, time));
dispatchGesture(gestureBuilder.build(), new GestureResultCallback() {
@Override
public void onCompleted(GestureDescription gestureDescription) {
System.out.println("SWIPE Gesture Completed :D");
super.onCompleted(gestureDescription);
}
}, null);
}
}
Dies führt zu folgendem Ergebnis (kann jedoch immer noch kein "Musterkennwort" wie z. B. TeamViewer zeichnen). Aber wie im Kommentar unten erwähnt, denke ich, dass dies mit einem ähnlichen Ansatz wahrscheinlich mit fortgesetzten Gesten erreicht werden kann . Vorschläge in diese Richtung sind willkommen.
Bearbeiten 2:
Auf jeden Fall ist die Lösung weiterhin Gesten wie bei der vorherigen Bearbeitung gesagt .
- Simulation der Joystickbewegung mit AccessibilityService
- Warum die Funktion continueStroke nicht funktioniert
Und unten ist ein angeblicher fester Code, den ich hier gefunden habe =>
android AccessibilityService:
// Simulates an L-shaped drag path: 200 pixels right, then 200 pixels down.
Path path = new Path();
path.moveTo(200,200);
path.lineTo(400,200);
final GestureDescription.StrokeDescription sd = new GestureDescription.StrokeDescription(path, 0, 500, true);
// The starting point of the second path must match
// the ending point of the first path.
Path path2 = new Path();
path2.moveTo(400,200);
path2.lineTo(400,400);
final GestureDescription.StrokeDescription sd2 = sd.continueStroke(path2, 0, 500, false); // 0.5 second
HongBaoService.mService.dispatchGesture(new GestureDescription.Builder().addStroke(sd).build(), new AccessibilityService.GestureResultCallback(){
@Override
public void onCompleted(GestureDescription gestureDescription){
super.onCompleted(gestureDescription);
HongBaoService.mService.dispatchGesture(new GestureDescription.Builder().addStroke(sd2).build(),null,null);
}
@Override
public void onCancelled(GestureDescription gestureDescription){
super.onCancelled(gestureDescription);
}
},null);
Dann ist mein Zweifel: Wie kann man richtig Mauskoordinaten für den obigen Code senden, wie man in jede Richtung ziehen kann? Irgendeine Idee?
Edit 3:
Ich habe zwei Routinen gefunden, die zum Ziehen verwendet werden, aber UiAutomation + verwenden injectInputEvent()
. AFAIK, Injection von Event funktioniert nur in einer System-App wie hier und hier gesagt und ich will es nicht.
Dies sind Routinen gefunden:
- öffentliches boolesches Wischen (int downX, int downY, int upX, int upY, int Schritte, boolesches Ziehen)
- public boolean swipe (Point [] -Segmente, int segmentSteps)
Um mein Ziel zu erreichen, ist die 2. Routine meiner Meinung nach besser geeignet, um (gemäß der Logik, ohne Ereignisinjektion) den in Edit 2 gezeigten Code zu verwenden und alle Punkte von pictureBox1_MouseDown
und pictureBox1_MouseMove
(C # Windows Forms-Anwendung) zu senden , um sie Point[]
dynamisch und beim pictureBox1_MouseUp
Senden zu füllen cmd, um die Routine auszuführen und dieses gefüllte Array zu verwenden. Wenn Sie eine Idee zur ersten Routine haben, lassen Sie es mich wissen: D.
Wenn Sie nach dem Lesen dieses Edits eine mögliche Lösung haben, zeigen Sie mir bitte eine Antwort, während ich versuchen werde, diese Idee zu testen.
StrokeDescription.continueStroke()
kann eine wahrscheinliche Lösung sein. Siehe Abschnitt Fortsetzung Gesten hier .
pictureBox1_MouseDown
darf die Koordinaten nicht senden. Es sollte nur die Anfangskoordinaten speichern, und dann pictureBox1_MouseUp
senden Sie sie weiter, da dies das Ende der Mausbewegung markiert