Java 在后台线程中模拟Android中的触摸事件

Java 在后台线程中模拟Android中的触摸事件,java,android,Java,Android,我曾经使用过一个服务,它每隔3秒向处理程序发布代码,以不断生成一个简单的触摸事件(按下按钮) 这是服务代码: public class BackgroundTouchService extends IntentService { public BackgroundTouchService() { super("BackgroundTouchService"); } @Override protected void onHandleIntent(I

我曾经使用过一个服务,它每隔3秒向处理程序发布代码,以不断生成一个简单的触摸事件(按下按钮)

这是服务代码:

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用户才能做到这一点。