Подтвердить что ты не робот

Как использовать юникод в ресурсе Android?

Я хочу использовать этот символ юникода в файле ресурсов.

Но что бы я ни делал, я заканчиваю крах dalvikvm (тестировался с Android 2.3 и 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...)

Я пробовал эту версию в файле ресурсов:

<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 -->

Обратите внимание, что использование его в Java String в коде работает нормально:

final String geolocation_icon = "\uD83D\uDCE1";
4b9b3361

Ответ 1

Ваш персонаж (U+1F4E1) находится за пределами Unicode BMP (базовая многоязычная плоскость - диапазон от U+0000 до U+FFFF).

К сожалению, в Android очень слабая (если есть) поддержка не-BMP персонажей. UTF-8 для символов, отличных от BMP, требуется 4 байта (0xF0 0x9F 0x93 0xA1). Но парсер Android UTF-8 понимает максимум 3 байта (см. Здесь и здесь).

Это работает для вас, когда вы используете UTF-16 суррогатное представление формы этого символа: "\uD83D\uDCE1". Если бы вы могли кодировать каждый суррогатный символ UTF-16 в модифицированном UTF-8 (он же CESU-8) - это заняло бы всего 6 байтов (3 байта в UTF-8 для каждого члена суррогатной пары), тогда это было бы возможно, Но Android также явно не поддерживает CESU-8.

Итак, ваше текущее решение - жесткое кодирование этого символа в исходном коде в виде суррогатной пары UTF-16 кажется наиболее простым, по крайней мере, до тех пор, пока Android не начнет полностью поддерживать не-BMP UTF-8.

ОБНОВЛЕНИЕ: это, кажется, частично исправлено в Android 6.0. Этот коммит был объединен с Android 6 и разрешает присутствие 4-байтовых символов UTF-8 в ресурсах XML. Это не идеальное решение - он просто автоматически преобразует 4-байтовый UTF-8 в соответствующую суррогатную пару. Тем не менее, это позволяет переместить их из вашего исходного кода в ресурсы XML. К сожалению, вы не можете использовать это решение, пока ваше приложение не перестанет поддерживать любую версию Android, кроме 6.0 и более поздних.

Ответ 2

Сделай так

Не храните проблемные эмодзи в strings.xml

добавить его программно

<string name="hi_welcome_msg">Hi %1$s</string>

getString(R.string.hi_welcome_msg, user.getFullName() + " \uD83D\uDC4B" );