¿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">📡</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.