2016-07-15 11 views
1

単純なタッチイベント(ボタンを押す)を生成し続けるために、コードをハンドラにポストするサービスを3秒間隔で使用しています。これは、サービスコードであるバックグラウンドスレッドでAndroidのタッチイベントをシミュレートする

:私のUIで

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); 
      } 
     }); 
    } 
} 

私は簡単に押されたボタン見分けることができるように、私は(適切なリスナーに)ボタンで画面をカバーしています。ただし、主なアクティビティがロードされ、何も起こりません。どうしてこれなの?

EDIT: 上記のコードのハンドラはメインスレッドと関連付けられていないため、タッチイベントを生成して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); 
      } 
     }); 
    } 
} 

しかし、これはまだ何もしません。何か案は?

SOLUTION: 私は別にACTION_DOWNとACTION_UPを指定するには、イベントを分離するために使用された場合さて、私はもともとACTION_BUTTON_PRESSを指定したMotionEvent.obtain方式のイベント型パラメータのため、しかし、これが動作するように見えました。 これがなぜ起こったのかについての説明は大歓迎です。 場合、誰かがこれを必要とする、ここでのコードは次のとおりです。

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); 
     } 
    }); 

答えて

0

私はこれが役立つかはわかりません。

デフォルトのコンストラクタを関連付け現在のスレッドのルーパーと、このハンドラ:しかし、間違いなく

final Handler handler = new Handler(); 

documentationからに問題があります。このスレッドにルーパーがない場合、このハンドラはメッセージを受け取ることができないため、例外がスローされます。

しかし、onHandleIntent()にメインスレッドはありません。メインスレッドにHandlerを作成する必要があります。

+0

あなたはそうです。タッチイベントを生成する必要がある場合(UIの変更と分類されるため、メインスレッドでのみ実行可能)、ハンドラはメインスレッドに関連付けられている必要があります。編集内容を確認してください。 –

2

touchイベントをビューに送信するには、dispatchTouchEventメソッドを使用する必要があると思います。

+0

このメソッドは、どのビューにタッチイベントを送信しますか?私たちはそれを物体なしで呼びます。 –

+0

私はこれを試しても、まだ動作しません –

+0

オブジェクトなしで呼び出すと、メソッド呼び出しは "this"になります。だから私はあなたのケースでは、それは活動のインスタンスと思う。私は、イベントの伝播がどのようにアンドロイドで起こるかを知っていると思ったが、いくつかのコンセプトが間違っていた。このビデオでは、イベントが親から子にどのように移行するかを非常にはっきりと説明しています。それを見てください。https://newcircle.com/s/post/1567/mastering_the_android_touch_system – prashant

0

下記のコードを使用してください。 Android Handlerを使用すると、投稿アクションのルーパーも必要です。

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