Android API 35+ Статус/цвет/высота панели навигации из JavaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Android API 35+ Статус/цвет/высота панели навигации из Java

Сообщение Anonymous »

До сих пор я использую для установки цвета фона и получения statusBar/navigationBar/cutout программно из функции Java,
однако он уже очень устарел, и, скорее всего, он устарел в текущем Android API 35+.
Поэтому я гуглил столько, сколько мог, использовал множество примеров для переписывания новых функций, однако высота statusBar, NavigationBar и выреза всегда возвращает ноль, что явно неправильно.
В следующем примере я закомментировал с помощью «OLD» то, как я использую рабочий код, с помощью «NEW» — что не работает новый код и «ПРИМЕЧАНИЕ» — открытый вопрос. Я даже не знаю, как заменить СТАРЫЙ на НОВЫЙ.

Код: Выделить всё

package org.myapp.activity;

import org.qtproject.qt.android.QtNative;
import org.qtproject.qt.android.bindings.QtActivity;

import android.os.*;
import android.content.*;
import android.app.*;

import android.content.res.Resources;
import android.content.res.Configuration;
import android.util.DisplayMetrics;

import android.view.Display;

import android.hardware.display.DisplayManager;
import android.view.Surface;
import android.view.View;
import android.view.DisplayCutout;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.graphics.Color;

import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowInsetsCompat.Type.InsetsType;

public class MyActivity extends QtActivity
{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setCustomStatusAndNavigationBar();
} // onCreate

void setCustomStatusAndNavigationBar() {

// First check sdk version, custom/transparent System_bars are only available after LOLLIPOP
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();

// OLD: // The Window flag 'FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS' will allow us to paint the background of the status bar ourself and automatically expand the canvas
// OLD: // If you want to simply set a custom background color (including transparent) for the statusBar/navigationBar, use the following addFlags call
// OLD: window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// NOTE: I found no mention if this is even needed when not using setStatusBarcolor() anymore, but will use WindowInsets.Type.statusBars() - my guess its not needed anymore

// OLD: // The Window flag 'FLAG_TRANSLUCENT_NAVIGATION' will allow us to paint the background of the navigation bar ourself
// OLD: // But we will also have to deal with orientation and OEM specifications, as the navigationBar may or may not depend on the orientation of the device
// OLD: window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);     // DEPRECATED (NOTE: is this even needed as setStatusBarColor() and setNavigationBarColor() are deprecated?)

// OLD: window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);                 // DEPRECATED
// NOTE: Use WindowInsetsController instead (NOTE: is this even needed as setStatusBarColor() and setNavigationBarColor() are deprecated?)

// OLD: Set StatusBar Transparent
// OLD: window.setStatusBarColor(Color.TRANSPARENT);            // DEPRECATED
// NOTE: Draw proper background behind WindowInsets.Type#statusBars()} instead

// OLD: // Set NavigationBar to desired color (0xAARRGGBB) set alpha value to 0 if you want a solid color
// OLD: window.setNavigationBarColor(Color.TRANSPARENT);        // DEPRECATED
// NOTE: Draw proper background behind WindowInsets.Type#navigationBars() instead

// OLD: // Statusbar background is now transparent, but the icons and text are probably white and not really readable, as we have a bright background color
// OLD: // We set/force a light theme for the status bar to make those dark
// OLD: View decor = window.getDecorView();
// OLD: decor.setSystemUiVisibility(decor.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);          // DEPRECATED
// NOTE: Use WindowInsetsController#APPEARANCE_LIGHT_NAVIGATION_BARS instead.  I guess something like:
window.insetsController?.setSystemBarsAppearance(WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);     // for light mode, therefore dark foreground (text/icons)... NOTE: does it works on its own or do I need to set something specific, like addFlags() to make this work?
//window.insetsController?.setSystemBarsAppearance(0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);     // for dark mode, therefore light foreground (text/icons)... NOTE: does it works on its own or do I need to set something specific, like addFlags() to make this work

// NOTE: Use WindowInsetsController#APPEARANCE_LIGHT_STATUS_BARS instead. I guess something like:
window.insetsController?.setSystemBarsAppearance(WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS, WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS);     // for light mode, therefore dark foreground (text/icons)... NOTE: does it works on its own or do I need to set something specific, like addFlags() to make this work?
//window.insetsController?.setSystemBarsAppearance(0, WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS);     // for dark mode, therefore light foreground (text/icons)...  NOTE: does it works on its own or do I need to set something specific, like addFlags() to make this work

}
}

// NOTE: used info from: outdated https://medium.com/javarevisited/how-to-get-status-bar-height-in-android-programmatically-c127ad4f8a5d / unfortunately not link to github so I cant use whole example inluding includes, which I assume is my main problem
public double statusBarHeight() {

// OLD: Using Resources (still working, but preferable use current API solution)
// double result = 0;
// int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
// if (resourceId > 0) {
//    result = getResources().getDimension(resourceId);
// }
// return result;

// NEW: Using Window Insets (API 30+)
WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets();
double statusBarHeight = windowInsets.getInsets(WindowInsets.Type.statusBars()).top;    // returns 0 all the time, why?
}

public int safeAreaTop() {

// OLD
// DisplayCutout cutout = getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
// if(cutout != null) {
//     int cutoutHeight = cutout.getSafeInsetTop();
//     if (cutoutHeight > 0) {
//         return cutoutHeight;
//      }
// }
// return 0;

// NEW: Using Window Insets (API 30+)
WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets();
int cutoutHeight = windowInsets.getInsets(WindowInsets.Type.displayCutout()).top;   // returns 0 all the time, but not sure if correctly as I use only Android Simualtor, but if statusBarHeight() solution is not working, I assume also this does not work
return cutoutHeight;
}

public double navigationBarHeight() {

// OLD: Using Resources (still working, but preferable use current API solution)
// double result = 0;
// int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
// if (resourceId > 0) {
//    result = getResources().getDimension(resourceId);
// }
// return result;

// New: Using Window Insets (API 30+)
WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets();
double navigationBarHeight = windowInsets.getInsets(WindowInsets.Type.navigationBars()).bottom;     // returns 0 all the time, but not sure if correctly as I use only Android Simualtor without navigationBar, but if statusBarHeight() solution is not working, I assume also this does not work
return navigationBarHeight;
}

public int getNavigationBarPosition() {

Resources res = getResources();
int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
boolean hasMenu = false;
if (resourceId > 0) {
hasMenu =  res.getBoolean(resourceId);
}
if (!hasMenu) {
return -1;
}

// NOTE: https://stackoverflow.com/questions/69724946/getdisplay-return-display
// Display display = getWindowManager().getDefaultDisplay();        // OLD: getDefaultDisplay() DEPRECATED
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);     // NEW solution, currently untested
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
int rotation = display.getRotation();

switch (rotation) {
case Surface.ROTATION_90:
return 1;
case Surface.ROTATION_180:
return 3;
case Surface.ROTATION_270:
return 2;
default:
return 0;
}
}
}
могу ли я попросить проверить и объяснить, что я здесь сделал не так, а также исправить то, как должен выглядеть правильный рабочий код?
PS: я не эксперт по Java, я работаю в QT (то есть C++/QML), это единственное, что нужно для управления моим приложением из интерфейса Java


Подробнее здесь: https://stackoverflow.com/questions/788 ... -from-java
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»