Java 在后台线程中模拟Android中的触摸事件
我曾经使用过一个服务,它每隔3秒向处理程序发布代码,以不断生成一个简单的触摸事件(按下按钮) 这是服务代码:Java 在后台线程中模拟Android中的触摸事件,java,android,Java,Android,我曾经使用过一个服务,它每隔3秒向处理程序发布代码,以不断生成一个简单的触摸事件(按下按钮) 这是服务代码: public class BackgroundTouchService extends IntentService { public BackgroundTouchService() { super("BackgroundTouchService"); } @Override protected void onHandleIntent(I
public class BackgroundTouchService extends IntentService
{
public BackgroundTouchService() {
super("BackgroundTouchService");
}
@Override
protected void onHandleIntent(Intent intent)
{
final MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_BUTTON_PRESS, 400, 400, 0);
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run()
{
View v = new View(getApplication());
v.onTouchEvent(event);
handler.postDelayed(this, 3000);
}
});
}
}
在我的UI中,我用按钮覆盖了屏幕(带有适当的侦听器),这样我就可以很容易地发现按下了哪个按钮。但是,主活动加载后什么也没有发生。为什么会这样
编辑:
正如Vojtěch Sáze正确指出的那样,上述代码中的处理程序与主线程没有关联,因此不能通过生成触摸事件来修改UI。因此,我在主活动本身中为处理程序编写了代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startTouch();
}
private void startTouch()
{
final MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_BUTTON_PRESS,400.0f, 400.0f, 0);
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run()
{
onTouchEvent(event);
handler.postDelayed(this, 3000);
}
});
}
}
然而,这仍然没有任何作用。有什么想法吗
解决方案:
好的,所以在MotionEvent.Acquire方法的事件类型参数中,我最初指定了ACTION\u BUTTON\u PRESS,但是,当我使用分隔事件来分别指定ACTION\u DOWN和ACTION\u UP时,这似乎是可行的。
欢迎解释为什么会发生这种情况。
如果有人需要此功能,以下是代码:
final MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN,400.0f, 400.0f, 0);
final MotionEvent event2 = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP, 400.0f, 400.0f, 0);
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run()
{
dispatchTouchEvent(event);
dispatchTouchEvent(event2);
handler.postDelayed(this, 3000);
}
});
我不确定这是否有用。但肯定有问题
final Handler handler = new Handler();
发件人:
默认构造函数将此处理程序与当前线程的循环器相关联。如果此线程没有循环器,则此处理程序将无法接收消息,因此会引发异常
但是在
onHandleIntent()中没有主线程。您需要在主线程中创建处理程序。我认为您需要使用dispatchTouchEvent方法将触摸事件发送到视图 只需使用下面的代码即可。使用Android处理程序,您还需要用于发布操作的活套
final Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run()
{
onTouchEvent(event);
handler.postDelayed(this, 3000);
}
});
你说得对。如果处理程序必须生成触摸事件(被归类为修改UI,因此只能在主线程中完成),则处理程序必须与主线程关联。请检查编辑。此方法将触摸事件发送到哪个视图?我们在没有对象的情况下调用它。当您在没有对象的情况下调用它时,方法调用将在“this”上。因此,我认为在你的情况下,它将是活动实例。我原以为我知道安卓系统中的事件传播是如何发生的,但我弄错了一些概念。我看到了这段视频,它非常清楚地解释了事件是如何从父母到孩子的。请仔细阅读,实际上我生成的触摸事件仅限于活动(正如您正确指出的,这是因为dispatchTouchEvent()在活动对象上调用。但是,我实际上希望生成系统范围的触摸事件。也就是说,即使活动关闭,触摸事件仍会持续运行。因此,如果我关闭活动并转到主屏幕,触摸事件应继续执行,并单击主屏幕上的某个图标。您知道我可以如何做到这一点吗?这是可能需要修改dispatchTouchEvent()方法。抱歉,系统范围的touch事件会使Android完全不安全。不可能做到这一点,您需要root用户才能做到这一点。