Je veux savoir comment faire un glisser sur Android basé sur les coordonnées de la souris X, Y? considérez comme deux exemples simples, le Team Viewer / QuickSupport dessinant le "modèle de mot de passe" sur le smartphone distant et le stylet de Windows Paint respectivement.
Tout ce que je peux faire, c'est simuler le toucher (avec dispatchGesture()
et aussi AccessibilityNodeInfo.ACTION_CLICK
).
J'ai trouvé ces liens pertinents, mais je ne sais pas s'ils peuvent être utiles:
Voici mon code de travail qui est utilisé pour envoyer les coordonnées de la souris (à l'intérieur du PictureBox
contrôle) au téléphone distant et simuler le toucher.
Application Windows Forms:
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));
}
}
Éditer:
Ma dernière tentative a été un "écran de balayage" utilisant les coordonnées de la souris (application Windows Forms C #) et une routine Android personnalisée (en référence au code de "l'écran de balayage" lié ci-dessus), respectivement:
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);
}
}
qui produit le résultat suivant (mais n'est toujours pas capable de dessiner un "mot de passe de modèle" comme TeamViewer par exemple). Mais comme dit dans le commentaire ci-dessous, je pense qu'avec une approche similaire, cela peut être réalisé en utilisant probablement des gestes continus . Toute suggestion dans ce sens sera la bienvenue.
Modifier 2:
Certainement, la solution consiste à poursuivre les gestes comme dit lors de l' édition précédente .
- Simuler le mouvement du joystick à l'aide d'AccessibilityService
- Pourquoi la fonction continueStroke ne fonctionne pas
Et ci-dessous est un supposé code fixe que j'ai trouvé ici =>
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);
Ensuite, mon doute est: comment envoyer correctement les coordonnées de la souris pour le code ci-dessus, de la façon dont vous pouvez effectuer le glisser dans n'importe quelle direction? Une idée?
Modifier 3:
J'ai trouvé deux routines utilisées pour effectuer un glissement, mais elles utilisent UiAutomation + injectInputEvent()
. AFAIK, l'injection d'événement ne fonctionne que dans une application système comme dit ici et ici et je ne le veux pas.
Ce sont des routines trouvées:
- balayage booléen public (int downX, int downY, int upX, int upY, étapes int, booléen glisser)
- balayage booléen public (segments Point [], segments intSteps)
Ensuite, pour atteindre mon objectif, je pense que la 2ème routine est plus appropriée à utiliser (en suivant la logique, à l'exception de l'injection d'événements) avec le code affiché sur Edit 2 et envoyer tous les points de pictureBox1_MouseDown
et pictureBox1_MouseMove
(C # Windows Forms Application) respectivement pour remplir Point[]
dynamiquement et lors de l' pictureBox1_MouseUp
envoi cmd pour exécuter la routine et utiliser ce tableau rempli. Si vous avez une idée de la 1ère routine, faites le moi savoir: D.
Si après avoir lu cette édition, vous avez une solution possible, montrez-moi une réponse s'il vous plaît, pendant que j'essaierai de tester cette idée.
StrokeDescription.continueStroke()
peut être une solution probable. Voir la section Gestes continus ici .
pictureBox1_MouseDown
ne doit pas envoyer les coordonnées. Il ne doit stocker que les coordonnées initiales, puis pictureBox1_MouseUp
vous les envoyez, car cela marque la fin du mouvement de la souris