Ответ 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 и более поздних.