web-dev-qa-db-ja.com

AndroidリソースでUnicodeを使用するには?

リソースファイルで this unicode文字を使用したい。

しかし、私が何をしても、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";
42
Pitel

あなたのキャラクター(U+1F4E1)はUnicode BMP(基本的な多言語面-U+0000からU+FFFFの範囲)の外にあります。

残念ながら、Androidは、もしあれば)非BMP文字のサポートが非常に弱いです。非BMP文字のUTF-8表現には4バイト(0xF0 0x9F 0x93 0xA1)が必要です。 Android UTF-8パーサーは最大3バイトしか理解しません(参照してくださいhereおよびここ)。

この文字UTF-16"\uD83D\uDCE1"サロゲートフォーム表現を使用する場合に役立ちます。変更されたUTF-16(別名UTF-8)で各サロゲートCESU-8文字をエンコードできた場合-合計6バイト(サロゲートの各メンバーに対してUTF-8で3バイト)ペア)、それは可能でしょう。ただし、AndroidはCESU-8も明示的にサポートしていません。

したがって、現在のソリューション-少なくともAndroidが非BMP UTF-16を完全にサポートし始めるまで、このシンボルをサロゲートUTF-8ペアとしてソースコードでハードコーディングするのが最も簡単です。

[〜#〜] update [〜#〜]:これは、Android 6.0。 このコミット は、Android 6にマージされ、XMLリソースに4バイトのUTF-8文字が存在することを許可します。完全なソリューションではありません。 -byte UTF-8を適切なサロゲートペアに変換しますが、ソースコードからXMLリソースに移動できます。残念ながら、アプリケーションがAndroid = 6.0以降を除くバージョン。

52
mvp

この方法で行う

問題のある絵文字をstrings.xmlに残さないでください

プログラムで追加する

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

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