Je veux utiliser ce caractère unicode dans mon fichier de ressources.
Mais quoi que je fasse, je termine avec un crash de dalvikvm (testé avec Android 2.3 et 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...)
J'ai essayé ces versions dans mon fichier de ressources:
<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 -->
Notez que son utilisation dans Java String dans le code fonctionne bien:
final String geolocation_icon = "\uD83D\uDCE1";
Votre personnage (U+1F4E1
) Est en dehors d'Unicode BMP (Plan multilingue de base - plage de U+0000
À U+FFFF
)).
Malheureusement, Android a une prise en charge très faible (le cas échéant) pour les caractères non BMP. La représentation UTF-8
Pour les caractères non BMP nécessite 4 octets (0xF0 0x9F 0x93 0xA1
). Mais, Android UTF-8
L'analyseur ne comprend que 3 octets maximum (voir ici et ici).
Cela fonctionne pour vous lorsque vous utilisez UTF-16
Une représentation de forme de substitution de ce caractère: "\uD83D\uDCE1"
. Si vous pouviez encoder chaque caractère de substitution UTF-16
Dans UTF-8
(Alias CESU-8
) - cela prendrait 6 octets au total (3 octets dans UTF-8
Pour chaque membre de la paire de substitution), alors ce serait possible. Mais, Android ne prend pas non plus explicitement en charge CESU-8
.
Ainsi, votre solution actuelle - coder en dur ce symbole dans le code source en tant que paire de substitution UTF-16
Semble la plus simple, au moins jusqu'à ce que Android commence à prendre pleinement en charge les non-BMP UTF-8
.
[~ # ~] mise à jour [~ # ~] : cela semble être partiellement corrigé dans Android 6.0. - Ce commit a été fusionné en Android 6, et permet la présence de caractères UTF-8 à 4 octets dans les ressources XML. Sa solution n'est pas parfaite - il convertira simplement automatiquement 4 octet UTF-8 dans la paire de substitution appropriée. Toutefois, cela permet de les déplacer de votre code source vers des ressources XML. Malheureusement, vous ne pouvez pas utiliser cette solution tant que votre application ne peut plus prendre en charge Android = version sauf pour 6.0 et versions ultérieures.
Faites-le de cette façon
Ne conservez pas les emoji problématiques dans le fichier strings.xml
l'ajouter par programme
<string name="hi_welcome_msg">Hi %1$s</string>
getString(R.string.hi_welcome_msg, user.getFullName() + " \uD83D\uDC4B" );