2016-11-05 68 views
4

我正在尋找一種方法,如何將輸入事件(如觸摸或鍵盤事件)從該特定應用程序中的代碼注入到自己的應用程序中。 不是到Android操作系統或其他應用程序b/c需要簽名級權限android.permission.INJECT_EVENTS或根設備,我必須避免這兩個。我尋找在沒有任何提升權限的情況下運行在無根設備上的代碼。如何在Android上將輸入事件注入自己的應用程序?

我不知何故使得基於以下概念進行了一些與代碼的進展:

View v = findViewById(android.R.id.content).getRootView(); 
v.dispatchTouchEvent(e); 
+0

爲什麼你需要這樣做?如果它是你自己的應用程序,直接調用函數不是更方便和可維護,而不是模擬觸摸事件?除非你正在編寫一個測試框架,在這種情況下,我會看看現有的框架是如何實現的。 –

+0

@GabeSechan - 它是一個與任意應用程序鏈接的庫的一部分,所以我沒有這種可能性。測試框架是一個很好的近似值,但它應該是生產級應用程序的一部分。 –

回答

1

我覺得getRootView和派遣它應該工作得很好,如果有任何與它的問題。請簡單介紹一下。

或者有更高層次但棘手的方法來做到這一點。 在View.java中,有一個名爲getViewRootImpl()的隱藏API,它將返回此Activity的android.view.ViewRootImpl對象。並且有一個名爲enqueueInputEvent(InputEvent事件)的方法。所以你可以使用反射來獲得這個方法。

因爲我剛剛完成了一個使用鍵盤向屏幕發送觸摸命令的項目,我認爲當您嘗試將這些事件注入到活動時,多點觸摸可能會成爲問題。當您嘗試將另一個手指發送到屏幕時。事件操作必須是ACTION_POINTER_DOWN,並且名稱爲properties的數組的索引移位。而且,即使您此時只需移動一根手指,也應該處理每次包括所有手指信息的屬性和座標數組。手指的id被設置爲屬性[i] .id用於識別你的手指。但是數組的索引並不穩定。

 for (int i = 0; i < size; i++) { 
      properties[i].id = fingerId; 
      properties[i].toolType = MotionEvent.TOOL_TYPE_FINGER; 

      coordses[i].x = currentX; 
      coordses[i].y = currentY; 
      coordses[i].pressure = 1; 
      coordses[i].size = DEFAULT_SIZE; 
     } 
     event = MotionEvent.obtain(
        mDownTime, SystemClock.uptimeMillis(), 
        ((size - 1) << MotionEvent.ACTION_POINTER_INDEX_SHIFT) 
          + MotionEvent.ACTION_POINTER_DOWN, 
        size, 
        properties, coordses, DEFAULT_META_STATE, DEFAULT_BUTTON_STATE, 
        DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y, DEFAULT_DEVICE_ID, 
        DEFAULT_EDGE_FLAGS, InputDevice.SOURCE_TOUCHSCREEN, DEFAULT_FLAGS); 
+0

我正在嘗試這種方法。我觀察到的問題是用戶能夠打開菜單但不能關閉。 –