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

时间:2016-07-15 07:44:30

标签: java android

我使用的服务以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);
           }
        });
    }
}

在我的用户界面中,我用按钮(带有适当的听众)覆盖了屏幕,这样我就可以轻松找到按下了哪个按钮。但是,主要活动加载,然后没有任何反应。这是为什么?

编辑: 正如VojtěchSá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.obtain方法的事件类型参数中,我最初指定了ACTION_BUTTON_PRESS,但是,当我以前将事件分开来分别指定ACTION_DOWN和ACTION_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);
        }
    });

3 个答案:

答案 0 :(得分:2)

我认为您需要使用dispatchTouchEvent方法将touch事件发送到视图。

答案 1 :(得分:0)

我不确定这是否有帮助。但是肯定存在问题

  final Handler handler = new Handler();

来自documentation

默认构造函数将此处理程序与当前线程的Looper相关联。如果此线程没有looper,则此处理程序无法接收消息,因此会抛出异常。

但是你没有onHandleIntent()中的主线索。您需要在主线程中创建Handler

答案 2 :(得分:0)

只需使用以下代码即可。使用Android Handler,您还需要looper来发布操作。

    final Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        @Override
        public void run()
        {
            onTouchEvent(event);
            handler.postDelayed(this, 3000);
        }
    });