Оверлей Android, чтобы захватить ALL touch и передать их?
В основном я пытаюсь получить все данные о событиях касания от чего-то вроде оверлей системы, переместить мои спрайты на основе этих данных касания, а затем позволить OS/homecreen/browser действовать на данные по мере необходимости (или наоборот) Versa). Я нашел похожие вопросы, но ничего, что меня куда-то заводило, я еще не был:
Получение представления, которое получает все события касания
(Реализовано, с результатами ниже)
Создание окна оверлея системы (всегда сверху)
Что я могу сделать:
Я могу ЭТО взять все события касания и действовать на них, перемещая мои спрайты и не позволяя OS/homecreen/browser видеть любой из них, ИЛИ ELSE. Я могу позволить событиям касания пройти и получить только "TOUCH_OUTSIDE" для моего приложения.
Моя недостигнутая цель:
Я НЕ МОЖЕТСЯ для жизни, когда я выясняю способ обойти работу с данными. Единственные методы, о которых я могу думать, что я не могу реализовать, - это:
Перехват данных в моем APP и передача его на OS/homecreen/browser для работы с
Позволяя оператору/домашнему экрану/браузеру сначала получить данные, а затем получить обратный вызов с информацией как-то
Разрешение OS/homecreen/browser получать данные, воздействовать на данные и опросить их за то, что их значения прокрутки/местоположения, чтобы воздействовать на него в моем APP.
Я боюсь, что это просто невозможно, я думаю, что я где-то читал в некоторых документах, которые я не могу найти сейчас:
"Все или ничего, либо ваше представление получает все события, либо ни один из них"
(Чтобы избежать путаницы, я не имею в виду, что у меня есть две точки зрения. Я имею в виду, что у меня есть один вид, контролируемый с помощью активности/службы, накладывающейся на OS/homecreen/browser. Как и панель стекла, если вы это сделаете.)
Спасибо за любую полезную информацию, которую вы можете предложить, она очень ценится!
[ОБНОВЛЕНИЕ]
Написал мою собственную документацию по этому вопросу ниже, чтобы не путать.
Ответы
Ответ 1
Нашел эту документацию, которая в значительной степени заявляет, что сделать это невозможно:
Android: Multi touch и TYPE_SYSTEM_OVERLAY
Они обсуждают обходные пути, но я не думаю, что любой из них действительно будет работать именно для того, что я пытаюсь сделать. Оба передают события в основное приложение и могут отслеживать их, чтобы действовать на них для себя.
Чтобы создать представление наложения, при настройке LayoutParams вам нужно для установки типа TYPE_SYSTEM_OVERLAY и использования флага FLAG_WATCH_OUTSIDE_TOUCH. Это создает проблему, поскольку В документации на Android указано: "вы не получите полную вниз/движение/вверх, только местоположение первого вниз, как ACTION_OUTSIDE." Чтобы получить полный набор сенсорных событий вам нужно использовать тип TYPE_SYSTEM_ALERT, но это вызывает наложение, чтобы захватить экран и прекратить взаимодействие с другими элементы.
Кто-то хочет не согласиться, я бы хотел услышать хорошие новости:-D
Ответ 2
Вы можете использовать GestureOverlayView, если вы хотите скрыть линии, которые он рисует, вы можете установить цвет на Transparent # 00000000, чтобы он не отображался, а затем вы можете захватывать все касания и жесты.
http://developer.android.com/resources/articles/gestures.html
Ответ 3
Я искал то же самое.
Этот флаг помогает мне FLAG_NOT_TOUCH_MODAL
Работает на настройках Android 7 и 8, как показано ниже.
Единственное действие, которое я реализовал, - это прикосновение, чтобы закрыть окно наложения.
Я также использовал здесь код " Пример наложения системного кода" на Github, который был необходим для получения событий.
Кстати, Google Maps действительно хорошо справляются с этим на Android 8. Вы можете перетаскивать их окно наложения, изменять его размер или закрывать. И все остальные приложения работают нормально, пока оно работает.
var type = 0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
}
var flags = FLAG_NOT_TOUCH_MODAL
mOverlayLayoutParams = WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, type, flags, PixelFormat.TRANSLUCENT)
Ответ 4
Это не оптимальное решение, но оно работает. Перезапустите сервис, переключая флаг, который нельзя коснуться. установите логическое значение extra в Intent, которое используется для запуска службы для определения предыдущего значения переключения состояния. Лучшей реализацией было бы использование намерения при касании, когда окно слушает, и по истечении определенного периода, когда оно не слушается.
public class bleh extends Service {
public void onCteqwer(int i) {
Context context; Class <bleh> context1 = bleh.class;
WindowManager.LayoutParams params = null;
WindowManager mang = (WindowManager) getSystemService(WINDOW_SERVICE);
//check previous state of service
if(i==0)
params = new WindowManager.LayoutParams(arg0,arg1,arg2,arg3,arg4,arg5);
if(i==1)
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,arg0,arg1,arg2,arg3,arg4);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View mViw = inflater.inflate(arg, null);
mViw.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
mang.addView(mViw, params);
Intent z = new Intent(context, context1);
if(i==0)
z.putExtra("name", 1);
if(i==1)
z.putExtra("name", 0);
stopSelf();
startService(z);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Bundle i=intent.getExtras();
int userName = 0;
if (i != null)
{
userName = i.getInt("name");
onCteqwer(userName);
}
}
}