2016-07-15 66 views
1

我已經使用了一種服務,以3秒爲間隔將代碼發佈到處理程序,以繼續生成簡單的觸摸事件(按下按鈕)。在後臺線程中模擬Android中的觸摸事件

這是該服務的代碼:

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

但是,這仍然沒有任何作用。有任何想法嗎?

SOLUTION: 好,所以我原本指定ACTION_BUTTON_PRESS的MotionEvent.obtain方法的事件類型的參數,但是,當我用不同的活動來分別指定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); 
     } 
    }); 

回答

0

我不知道這是否會有所幫助。但肯定是有與

final Handler handler = new Handler(); 

documentation問題:

默認的構造同夥這個處理器與樂句當前線程。如果此線程沒有活套,則此處理程序將無法接收消息,因此引發異常。

但是,您在onHandleIntent()中沒有主線程。您需要在主線程中創建Handler

+0

你說得對。如果處理程序必須生成觸摸事件(它被分類爲修改UI,因此只能在主線程中完成),則該處理程序必須與主線程關聯。請檢查編輯。 –

2

我認爲您需要使用dispatchTouchEvent方法將觸摸事件發送到視圖。

+0

此方法將觸發事件發送給哪個視圖?我們稱之爲沒有對象。 –

+0

我試過了,它仍然不起作用 –

+0

當您在沒有對象的情況下調用它時,方法調用將在「this」上。所以我認爲在你的情況下,這將是活動實例。我以爲我知道事件傳播是如何在Android中發生的,但我有一些概念錯誤。我偶然看到這段視頻,非常清楚地解釋事件是如何從父母到孩子的。請通過https://newcircle.com/s/post/1567/mastering_the_android_touch_system – prashant

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