java - ventana - Verifique la barra de navegación
jinternalframe sin barra de titulo (10)
Estoy tratando de verificar si la barra de navegación de Android está presente en la carga para que pueda ajustar un diseño en consecuencia, ¿alguien tiene alguna sugerencia?
Esta es la barra de navegación que estoy tratando de detectar:
PD: Todo lo que he encontrado hasta ahora son "malas" formas de intentar y eliminar la barra, lo que no quiero hacer.
Algo que probablemente debería funcionar mejor es medir la pantalla.
Comenzando con API 17 hay getWindowManager().getDefaultDisplay().getRealSize()
, que se puede comparar con el tamaño devuelto por getWindowManager().getDefaultDisplay().getSize()
.
Si obtienes resultados diferentes, creo que es seguro decir que hay una barra de navegación y si obtienes los mismos resultados, no hay ninguno. Una cosa a tener en cuenta es el SDK de destino y las pantallas compatibles, lo que puede hacer que el resultado de getSize()
si Android piensa que tu aplicación no funcionará bien en el dispositivo actual sin escalar.
Debajo de API 17 puedes medir la pantalla a través de getWindowManager().getDefaultDisplay().getMetrics()
en modo paisaje y retrato, y de nuevo, diferentes resultados probablemente signifiquen que hay una barra de navegación.
Sin embargo, si obtiene los mismos resultados, en realidad no lo sabe, ya que los teléfonos pueden mantener la barra de navegación en el borde más corto, incluso cuando está en el paisaje. Una suposición educada sería que si el ancho o la altura es de 4% a 8% más pequeño que los tamaños estándar como 1280x800
, 1280x720
, 1024x600
, mientras que la otra dimensión es igual, entonces probablemente haya una barra de navegación. No apuestes, sin embargo. Hay demasiadas resoluciones, que difieren demasiado poco entre sí para que esto funcione bien.
Aquí hay una respuesta rápida que combina las soluciones de Pauland y Philask. Me temo que no tengo suficientes dispositivos disponibles para probar si funciona en todas partes. Me interesaría escuchar los resultados de otros.
boolean hasNavBar(Context context) {
Resources resources = context.getResources();
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0) {
return resources.getBoolean(id);
} else { // Check for keys
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
return !hasMenuKey && !hasBackKey;
}
}
Este método funcionó para mi
int id = getResources().getIdentifier("config_showNavigationBar","bool","android");
boolean result = id > 0 && getResources().getBoolean(id);
//
if(result) {
// Do whatever you need to do, this device has a soft Navigation Bar
}
Funcionó para mí y probado en muchos dispositivos.
Me tomó un tiempo, pero encontré una manera más confiable que confiar en PerEntremeMenuKey () que no funciona para teléfonos más nuevos como el HTC One que no tienen una tecla de menú pero tienen teclas de inicio y atras para no necesitar (o mostrar) la barra de navegación suave. Para evitar esto, intente con el siguiente código que también busca un botón de retroceso:
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
if(!hasMenuKey && !hasBackKey) {
// Do whatever you need to do, this device has a navigation bar
}
No hay una manera confiable de buscar una barra de navegación. Usando KeyCharacterMap.deviceHasKey
puede verificar si ciertas teclas físicas están presentes en el dispositivo, pero esta información no es muy útil ya que los dispositivos con claves físicas aún pueden tener una barra de navegación. Los dispositivos como OnePlus One o cualquier dispositivo que ejecute una rom personalizada tienen una opción en la configuración que deshabilita las teclas físicas y agrega una barra de navegación. No hay forma de comprobar si esta opción está habilitada, y deviceHasKey
aún devuelve verdadero para las claves que están deshabilitadas por esta opción.
Esto es lo más cercano que puede obtener:
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
if (hasBackKey && hasHomeKey) {
// no navigation bar, unless it is enabled in the settings
} else {
// 99% sure there''s a navigation bar
}
Si la parte posterior y el botón de inicio no están físicamente presentes en el dispositivo, debe tener una barra de navegación, porque de lo contrario el usuario no podría navegar. Sin embargo, nunca puede estar 100% seguro de esto, ya que los fabricantes pueden implementar deviceHasKey
incorrectamente.
Otra solución (una parte de mi clase UtilsUISystem )
public static boolean hasNavBar (Resources resources)
{
//Emulator
if (Build.FINGERPRINT.startsWith("generic"))
return true;
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && resources.getBoolean(id);
}
Solución: solo los dispositivos que no tienen teclas de hardware permanentes tienen la barra de navegación, por lo tanto, puede verificar la versión de la API y usar hasPermanentMenuKey () para buscar claves de hardware
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
Veo las respuestas de arriba, quiero indicar que el "no existir" puede considerarse como la altura de 0; entonces puede ser así:
public static int getScreenH(Context context) {
DisplayMetrics dm = new DisplayMetrics();
dm = context.getResources().getDisplayMetrics();
int h = dm.heightPixels;
return h;
}
public static int getDpi(Context context) {
DisplayMetrics displayMetrics1 = context.getResources().getDisplayMetrics();
int height1 = displayMetrics1.heightPixels;
int dpi = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
@SuppressWarnings("rawtypes")
Class c;
try {
c = Class.forName("android.view.Display");
@SuppressWarnings("unchecked")
Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
method.invoke(display, displayMetrics);
dpi = displayMetrics.heightPixels;
} catch (Exception e) {
e.printStackTrace();
}
return dpi;
}
public static int getBottomStatusHeight(Context context) {
int totalHeight = getDpi(context);
int contentHeight = getScreenH(context);
return totalHeight - contentHeight;
}
`` `
podría agregar este código al método onCreate () de su actividad:
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
// TODO: The navigation bar is visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
} else {
// TODO: The navigation bar is NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
}
}
});
boolean hasNavBar(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// navigation bar was introduced in Android 4.0 (API level 14)
Resources resources = context.getResources();
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
if (id > 0) {
return resources.getBoolean(id);
} else { // Check for keys
boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
return !hasMenuKey && !hasBackKey;
}
} else {
return false;
}
}