android unicode utf-8 surrogate-pairs

¿Cómo usar Unicode en un recurso de Android?



utf-8 surrogate-pairs (1)

Quiero usar this carácter Unicode en mi archivo de recursos.

Pero haga lo que haga, termino con dalvikvm crash (probado con Android 2.3 y 4.2.2):

W/dalvikvm( 8797): JNI WARNING: input is not valid Modified UTF-8: illegal start byte 0xf0 W/dalvikvm( 8797): string: ''📡'' W/dalvikvm( 8797): in Landroid/content/res/StringBlock;.nativeGetString:(II)Ljava/lang/String; (NewStringUTF) E/dalvikvm( 8797): VM aborting F/libc ( 8797): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 8797 (cz.ipex...)

Intenté esta versión en mi archivo de recursos:

<string name="geolocation_icon" translatable="false">&#x1f4e1;</string> <!-- HTML --> <string name="geolocation_icon" translatable="false">/uD83D/uDCE1</string> <!-- escaped unicode --> <string name="geolocation_icon" translatable="false">📡</string> <!-- unicode character -->

Tenga en cuenta que usarlo en Java String en el código funciona bien:

final String geolocation_icon = "/uD83D/uDCE1";


Su personaje ( U+1F4E1 ) está fuera de Unicode BMP (plano multilingüe básico: rango de U+0000 a U+FFFF ).

Desafortunadamente, Android tiene soporte muy débil (si hay alguno) para caracteres que no son BMP. UTF-8 representación UTF-8 para caracteres que no son BMP requiere 4 bytes ( 0xF0 0x9F 0x93 0xA1 ). Sin embargo, el analizador UTF-8 Android solo comprende 3 bytes como máximo (ver here y here ).

Funciona para usted cuando utiliza la representación en forma sustituta UTF-16 de este caracter: "/uD83D/uDCE1" . Si pudieras codificar cada personaje sustituto UTF-16 en UTF-8 modificado (también conocido como CESU-8 ), tomaría 6 bytes en total (3 bytes en UTF-8 para cada miembro del par suplente), entonces sería posible . Pero, Android tampoco es compatible con CESU-8 explícitamente.

Entonces, su solución actual: codificar con fuerza este símbolo en el código fuente como el par sustituto UTF-16 parece ser el más fácil, al menos hasta que Android comience a soportar completamente el UTF-8 no BMP.

ACTUALIZACIÓN : esto parece estar parcialmente resuelto en Android 6.0. Este compromiso se ha fusionado con Android 6 y permite la presencia de caracteres UTF-8 de 4 bytes en recursos XML. No es la solución perfecta, simplemente convertirá automáticamente 4 bytes UTF-8 en el par sustituto apropiado. Sin embargo, permite moverlos de su código fuente a recursos XML. Desafortunadamente, no puede usar esta solución hasta que su aplicación pueda dejar de admitir cualquier versión de Android, excepto 6.0 y posteriores.