X, Y fare koordinatlarına dayalı android üzerinde bir sürükle gerçekleştirmek nasıl bilmek istiyorum? iki basit örnek olarak düşünün: Takım Görüntüleyicisi / QuickSupport, sırasıyla akıllı telefondaki "parola kalıbını" ve Windows Paint Kalemi'ni çiziyor.
Yapabildiğim tek şey dokunuşu simüle etmektir ( dispatchGesture()
ve ile AccessibilityNodeInfo.ACTION_CLICK
).
Bu ilgili bağlantıları buldum, ancak yararlı olup olmadıklarını bilmiyorum:
- AccessibilityService'i kullanarak ekranda hızlıca kaydırma gerçekleştirin
- örnek 1
- Devam eden hareketler
Aşağıda, PictureBox
uzaktan telefona fare koordinatları ( kontrolün içinde ) göndermek ve dokunmayı simüle etmek için kullanılan çalışma kodum aşağıdadır .
Windows Forms Uygulaması:
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));
}
}
Düzenle:
Son denemem, sırasıyla fare koordinatları (C # Windows Forms Application) ve özel bir android rutini (yukarıda bağlı "kaydırma ekranı" koduna atıfla) kullanan bir "kaydırma ekranı" idi:
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 Erişilebilirlik Hizmeti :
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);
}
}
Aşağıdaki sonucu üretir (ancak yine de TeamViewer gibi "desen şifresi" çizemez). Ancak aşağıdaki yorumda belirtildiği gibi, benzer bir yaklaşımla bunun muhtemelen Sürekli hareketler kullanılarak elde edilebileceğini düşünüyorum . Bu yönde herhangi bir öneri kabul edilecektir.
Düzenleme 2:
Kesinlikle, çözümdür devam jestler önceki üzerinde dediğin gibi düzenleyin .
- AccessibilityService kullanarak joystick hareketini simüle etme
- ContinueStroke işlevi neden çalışmıyor
Ve aşağıda burada bulduğum varsayalım sabit bir kod =>
android Erişilebilirlik Hizmeti:
// 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);
O zaman, şüphe: yukarıdaki kod için herhangi bir yöne sürükleme gerçekleştirebilir şekilde doğru fare koordinatları göndermek nasıl?Biraz fikir?
Düzenleme 3:
Sürükleme yapmak için kullanılan iki rutin buldum, ancak UiAutomation + kullanıyorlar injectInputEvent()
. AFAIK, olayın enjeksiyonu sadece burada söylendiği gibi bir sistem uygulamasında çalışıyor ve burada ve ben istemiyorum.
Bunlar bulunan rutinler:
- genel boolean hızlıca kaydırma (int downX, int downY, int upX, int upY, int adımlar, boolean sürükleme)
- herkese açık boole kaydırma (Nokta [] segmentleri, int segmentSteps)
Daha sonra hedefime ulaşmak için, 2. rutinin Düzenle 2'de gösterilen kodla (mantığı takip ederek, olay enjeksiyon hariç) kullanmak için daha uygun olduğunu pictureBox1_MouseDown
ve dinamik ve pictureBox1_MouseMove
doldurmak için sırasıyla ve (C # Windows Forms Uygulaması) tüm noktalarını göndereceğini düşünüyorum cmd yordamı yürütmek ve bu dizi dolu kullanın. 1. rutine ilişkin bir fikriniz varsa bana bildirin: D.Point[]
pictureBox1_MouseUp
Bu Düzenlemeyi okuduktan sonra olası bir çözümünüz varsa, lütfen bana bir cevap gösterin, bu fikri test edeceğim.
StrokeDescription.continueStroke()
olası bir çözüm olabileceğini düşünüyorum . Bölüm Bkz Devam hareketleri burada .
pictureBox1_MouseDown
koordinatları göndermemelidir. Sadece ilk koordinatları pictureBox1_MouseUp