X, Y 마우스 좌표를 기반으로 안드로이드에서 드래그를 수행하는 방법을 알고 싶습니다. 원격 스마트 폰과 Windows Paint 펜에 각각 "비밀번호 패턴"을 그리는 Team Viewer / QuickSupport의 두 가지 간단한 예를 생각해보십시오.
내가 메이크업의 수있어 그 모든입니다 시뮬레이션 터치 (와 dispatchGesture()
도하고 AccessibilityNodeInfo.ACTION_CLICK
).
관련 링크를 찾았지만 유용한 지 알 수 없습니다.
아래는 마우스 좌표 ( PictureBox
제어 내부 )를 원격 전화 로 보내고 터치를 시뮬레이션 하는 데 사용되는 작업 코드입니다 .
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));
}
}
편집하다:
마지막 시도는 각각 마우스 좌표 (C # Windows Forms 응용 프로그램)와 사용자 지정 Android 루틴 (위의 "스 와이프 화면"코드 참조)을 사용하는 "스 와이프 화면"이었습니다.
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));
}
}
}
안드로이드 접근성 서비스 :
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);
}
}
다음 결과를 생성합니다 (그러나 여전히 TeamViewer와 같은 "패턴 암호"를 그릴 수는 없습니다). 그러나 아래 의견에서 언급했듯이 비슷한 접근 방식을 사용하면 아마도 연속 제스처를 사용하여이를 달성 할 수 있다고 생각합니다 . 이 방향에 대한 제안은 환영합니다.
편집 2 :
확실히, 해결책은 이전 Edit에서 언급 한 것처럼 계속되는 제스처 입니다.
그리고 아래에 내가 발견하는 가정 고정 코드 여기가 =>
안드로이드 접근성 서비스 :
// 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);
그렇다면 내 의심은 위의 코드에 대해 마우스 좌표를 올바르게 보내면 어떤 방향으로 드래그 할 수 있습니까? 어떤 아이디어?
편집 3 :
드래그를 수행하는 데 사용되는 두 가지 루틴을 찾았지만 UiAutomation +를 사용하고 있습니다 injectInputEvent()
. AFAIK, 이벤트 주입은 여기 와 여기에서 말한 것과 같은 시스템 앱에서만 작동하며 원하지 않습니다.
이것은 발견 된 루틴입니다.
- 공개 부울 스 와이프 (int downX, int downY, int upX, int upY, int steps, boolean drag)
- 공개 부울 스 와이프 (Point [] segment, int segmentSteps)
그럼 내 목표를 달성하기 위해, 그 2rd 루틴이 더에 보여 주었다 코드 (이벤트 주입을 제외한 논리 다음) 사용에 충당 생각 편집 2 그리고 모든 포인트를 전송 pictureBox1_MouseDown
하고 pictureBox1_MouseMove
각각 기입 (C #의 Windows Forms 응용 프로그램) Point[]
동적에 pictureBox1_MouseUp
보내기 cmd를 사용하여 루틴을 실행하고 채워진이 배열을 사용하십시오. 첫 번째 루틴에 대한 아이디어가 있다면 : D를 알려주십시오.
이 편집 을 읽은 후에 가능한 해결책 이 있다면 답을 알려주십시오.이 아이디어를 시험 해보고 시험해보십시오.
StrokeDescription.continueStroke()
가능한 해결책 일 수 있다고 생각합니다 . 여기에서 계속되는 제스처 섹션을 참조 하십시오 .
pictureBox1_MouseDown
좌표를 보내서는 안됩니다. 초기 좌표 만 저장 한 다음 pictureBox1_MouseUp
보내야합니다. 마우스 이동이