Почему ACTION_OUTSIDE каждый раз возвращает 0 на KitKat 4.4.2?
Я реализовал окно с размером 1 и хочу поймать ACTION_OUTSIDE
событие.
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(1,1,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
Я получил триггер, и я получил ACTION_OUTSIDE
событие, но при чтении event.getRawX()
а также event.getRawY()
они оба возвращают 0 каждый раз. Я протестировал то же самое с Android 2.3.6, и это сработало. И я не могу найти ничего, что устарело.
Это проблема Android или кто-нибудь знает решение? Спасибо
1 ответ
Tniederm, я ответил на аналогичный вопрос здесь для справки, но я перефразирую его здесь с некоторыми незначительными правками:
После изучения исходного кода я нашел источник проблемы:
// Check whether windows listening for outside touches are owned by the same UID. If it is
// set the policy flag that we will not reveal coordinate information to this window.
if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
sp<InputWindowHandle> foregroundWindowHandle =
mTempTouchState.getFirstForegroundWindowHandle();
const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
mTempTouchState.addOrUpdateWindow(inputWindowHandle,
InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
}
}
}
}
Если "внешнее касание" попадает в представление, которое не использует свой UID ( читайте об этом здесь) с представлением, которое прослушивает внешние касания, диспетчер событий устанавливает свои координаты в 0,0. Это определенно было сделано в целях безопасности, но я не уверен, что вижу полный объем угрозы, которую он призван смягчить. Вы можете попытаться найти более старые версии InputDispatcher, чтобы узнать, когда именно была введена эта функция - я сам не смотрел.
Я открыл сообщение об ошибке, если вы хотите следовать за ним. По крайней мере, документация должна включать эту информацию... Я также хотел бы знать, действительно ли эта функция безопасности необходима.