У меня есть приложение Java (API 23). В нем у меня есть MainActivity
и AccessibilityService
. В службе доступности:
@Override
public void onServiceConnected() {
oView = new LinearLayout(this);
oView.setBackgroundColor(0x88ff0000); // The translucent red color
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
width,
height,
xPos, yPos,
WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT
);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(oView, params);
}
Мне нужно настроить width
, height
, xPos
и yPos
, чтобы они покрывали весь экран, включая строку состояния и панель навигации. Это означает, что мне нужно найти размеры для строки состояния, экрана и панели навигации (я могу определить нужные мне значения, когда они у меня будут).
Я нашел высоту строки состояния? - лучший ответ, похоже,
ViewCompat.setOnApplyWindowInsetsListener(rootView, new OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
//THIS is the value you want.
int statusBarHeight = insets.getSystemWindowInsetTop();
int navigationBar = insets.getSystemWindowInsetBottom();
// Let the view handle insets as it likes.
return ViewCompat.onApplyWindowInsets(v, insets);
}
});
Но что rootView
я могу использовать, поскольку нет гарантии, что моя активность будет видна? И нужно ли переносить создание представления из onServiceConnected()
внутрь onApplyWindowInsets()
?
Это действительно лучший способ сделать это?
Дополнительные вопросы, которые следует учитывать в связи с вышеизложенным - в зависимости от вышеизложенного и от того, отвечает ли он на них, я задам здесь или в отдельном вопросе:
Что происходит при повороте экрана? Что делать, если строка состояния и/или панель навигации исчезают (например, если они переходят в полноэкранный режим)? Похоже, мне нужно справиться с этим, перечитать высоты и заново создать представление. Любые мысли или рекомендации о том, как это сделать, будут приветствоваться.
=== Обновление - Прогресс на данный момент ===
Я думал, что мне нужен только размер экрана плюс информация о строке состояния (размер, местоположение), но панель навигации иногда находится в левой части экрана, поэтому мне это нужно, и клавиатура тоже может влиять на вещи.
Я могу получить размер экрана с помощью
Display myDisplay = wm.getDefaultDisplay();
Display.Mode mode = myDisplay.getMode();
int height = mode.getPhysicalHeight();
int width = mode.getPhysicalWidth();
Я все еще работаю над различными локациями и размерами. Я попытался создать представление, а затем прочитать вставки, но это дало мне неправильные ответы. Поэтому, если не появится лучший ответ, мне, вероятно, придется использовать
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
Но в некоторых случаях это может давать неправильные ответы, если строка состояния скрыта, и она не говорит мне, где она находится на экране. Я все еще работаю над этим; есть несколько вещей, чтобы попробовать, так что мы посмотрим.
Обработка ротации в службе может быть выполнена с помощью onConfigurationChanged() - см. -in-android">Как использовать сервис для отслеживания изменения ориентации в Android
Надеюсь, это поможет кому-то - пожалуйста, отчаянно ищу эти последние части.
WindowInsets
применяются к представлению. Если у вас нет представления, вы не можете их получить. Есть и другие способы получитьstatus-bar
илиnavigation-bar
высоты, но они не на 100% надежны. - person Ahmad Sattout   schedule 02.01.2021