Android 4.2 ACTION_OUTSIDE MotionEvent X и Y возвращают 0 вне собственного приложения
Я создал представление TYPE_SYSTEM_ALERT, установил флаги FLAG_NOT_TOUCH_MODAL и FLAG_WATCH_OUTSIDE_TOUCH и добавил его с помощью WindowManager.addView();
Когда я касаюсь за пределами представления своей собственной деятельности, все работает, и MotionEvent.getY() возвращает правильное значение.
Однако, если я выйду из своей деятельности и коснусь другого приложения, MotionEvent.getY() всегда возвращает 0.
Я не уверен, происходит ли это только на 4.2 или нет.
Любая помощь будет оценена!
1 ответ
К сожалению, этот вопрос оставался без ответа в течение 1,5 лет, но я столкнулся с тем же, что и вы, и выяснил, почему!
После изучения исходного кода я нашел источник проблемы:
// 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. Это определенно было сделано в целях безопасности, но я не уверен, что вижу полный объем угрозы, которую он призван смягчить. И этот джентльмен здесь (SO) сообщает, что вы можете получить данные о местоположении на 2.3.6, но кажется, что по крайней мере 4.x не откроет их вам (я пробовал 4.1.2, это не сработало).
Я открыл сообщение об ошибке, если вы хотите следовать за ним. По крайней мере, документация должна включать эту информацию... Я также хотел бы знать, действительно ли эта функция безопасности необходима.