¿Cómo manejar idiomas mixtos RTL y LTR en las notificaciones?

Fondo

Android 4.3 ha añadido una gran cantidad de soporte para los idiomas RTL (de derecha a izquierda), como el hebreo y el árabe.

El problema

Aunque hay "textDirection", "layoutDirection" y "gravity", no puedo encontrar los equivalentes para el constructor de notificaciones, ni siquiera en la biblioteca de compatibilidad.

Esto significa que si hay palabras hebreas e inglesas juntas, el orden es incorrecto. Por ejemplo (y escribo en inglés para simplificar):

En lugar de "X llamado Y", se obtiene "Y llamado X" (supongamos que "called" es una palabra en hebreo), como se supone que la cadena está en este formato:

<string name="notification">%1$s called %2$s</string> 

Nota: X e Y pueden ser palabras RTL o LTR (y números pares).

Los requisitos son que en hebreo, la palabra a la derecha debe ser X, entonces la palabra "llamado" (pero en hebreo, por supuesto), y luego Y a la izquierda. Como he intentado mostrar en el ejemplo de la analogía inglesa, es todo lo contrario.

Lo que he intentado

a. He intentado buscar en la documentación, y todo lo que he encontrado es que probablemente tendrá que anular el diseño, pero eso no es una buena solución. Las razones:

  1. Es posible que no utilice el estilo correcto de Android.
  2. No es una prueba futura para las próximas versiones de Android, que podrían utilizar un estilo diferente.
  3. No admite el texto del ticker.

segundo. También he intentado investigar qué caracteres especiales forzarán la dirección del texto a ser diferente, y funcionó agregando '\ u200f' al principio y al final del texto para mostrar, pero tiene algunos defectos:

  1. No es tan flexible como los otros atributos.
  2. No estoy seguro de usar la forma oficial de manejar este problema.
  3. Tengo que añadir esto para cada vez que uso una notificación
  4. No funciona en absoluto para tickerText. Sólo para las notificaciones, e incluso entonces, no para todos los casos.

He aquí un ejemplo de código:

 /** prepares a string to be shown in a notification, so that it will be shown even on RTL languages */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static String prepareNotificationText(final Context context, final String text) { if (VERSION.SDK_INT < VERSION_CODES.JELLY_BEAN_MR1) return text; final boolean isRTL = context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; if (!isRTL) return text; return '\u200f' + text + '\u200f'; } 

do. También podría cambiar entre '1' y '2' en la cadena, pero esto no maneja todos los casos, además de que es aún más confuso para los traductores.

La pregunta

¿Hay alguna forma de hacer que el constructor de notificaciones maneje correctamente los textos (tanto para las notificaciones como para TickerText)?

Cualquier manera de ajustarlo sin realmente hacer diseños totalmente nuevos para las notificaciones (o cambiar cadenas), que podría no estar en el mismo estilo nativo de Android?

¿Cuál es la forma oficial de manejar tal cosa?

OK, encontró una respuesta, basada en esto , esto y esto .

Para el caso anterior:

% 1 $ s llamado% 2 $ s

Para cambiarlo correctamente a hebreo, debe agregar el carácter especial "\ u200f", como tal:

  <string name="notification">%1$s התקשר ל %2$s</string> NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); if (VERSION.SDK_INT >= VERSION_CODES.O) { String id = "my_channel_01"; CharSequence name = "channelName";// getString(R.string.channel_name); String description = "channelDesc";//getString(R.string.channel_description); int importance = NotificationManager.IMPORTANCE_LOW; NotificationChannel channel = new NotificationChannel(id, name, importance); channel.setDescription(description); channel.enableLights(true); channel.setLightColor(Color.RED); channel.enableVibration(true); channel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400}); notificationManager.createNotificationChannel(channel); } Intent resultIntent = new Intent(this, MainActivity.class); PendingIntent resultPendingIntent = PendingIntent.getActivity( this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT ); String[] names1 = new String[]{"משה", "Moses"}; String[] names2 = new String[]{"דוד", "David"}; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { String name1, name2; name1 = names1[i]; name2 = names2[j]; name1 = "\u200f" + name1 + "\u200f"; name2 = "\u200f" + name2 + "\u200f"; final String text = getString(R.string.notification, name1, name2); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "TEST") .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(text) .setContentIntent(resultPendingIntent) .setChannelId("my_channel_01") .setContentText(text); int notificationId = i*2+j; notificationManager.notify(notificationId, mBuilder.build()); } } } 

También puede comprobar si la configuración regional actual es RTL, antes de elegir utilizar esta solución. Ejemplo:

 public static boolean isRTL() { return Character.getDirectionality(Locale.getDefault().getDisplayName().charAt(0)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT; } 

El resultado:

Introduzca aquí la descripción de la imagen

  • @IntDef anotación y devolver valor de otro código que no se puede anotar o cómo desactivar temporalmente la anotación de afectar el código?
  • 'No se pudo cargar RSSupport: findLibrary returned null' cuando se usa RenderScript en el emulador 2.3
  • Enum vs android @Intdef - cual es mejor optimizado
  • Android DialogFragment no descarta
  • ¿Cómo manejar los problemas de la nueva hoja inferior de la biblioteca de soporte / diseño?
  • Grabación de la barra de herramientas en la barra de herramientas extendida
  • WearableListView setEnableGestureNavigation no disponible
  • Implementación de un TabListener utilizando la biblioteca de soporte
  • Barra de herramientas de soporte de Android: Cambiar el tamaño no realineará los elementos del menú
  • No se puede encontrar android.support.design.widget.Snackbar en la biblioteca de diseño de asistencia
  • Proyecto de Android se queja "Los tornillos de tipo.Task no se puede resolver. Se hace referencia indirectamente a los archivos .class necesarios "
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.