diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 09f1145e94b11746d3fda331eade23c1b2dc391d..61805286dd9bf7b2ecc521c5bd32d05d99af4752 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -306,8 +306,15 @@ public class Key implements Comparable<Key> {
         }
         mActionFlags = actionFlags;
 
+        final int code = KeySpecParser.parseCode(style.getString(keyAttr,
+                R.styleable.Keyboard_Key_code), params.mCodesSet, CODE_UNSPECIFIED);
         if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
             mLabel = params.mId.mCustomActionLabel;
+        } else if (code >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            // This is a workaround to have a key that has a supplementary code point in its label.
+            // Because we can put a string in resource neither as a XML entity of a supplementary
+            // code point nor as a surrogate pair.
+            mLabel = new StringBuilder().appendCodePoint(code).toString();
         } else {
             mLabel = KeySpecParser.toUpperCaseOfStringForLocale(style.getString(keyAttr,
                     R.styleable.Keyboard_Key_keyLabel), needsToUpperCase, locale);
@@ -320,8 +327,6 @@ public class Key implements Comparable<Key> {
         }
         String outputText = KeySpecParser.toUpperCaseOfStringForLocale(style.getString(keyAttr,
                 R.styleable.Keyboard_Key_keyOutputText), needsToUpperCase, locale);
-        final int code = KeySpecParser.parseCode(style.getString(keyAttr,
-                R.styleable.Keyboard_Key_code), params.mCodesSet, CODE_UNSPECIFIED);
         // Choose the first letter of the label as primary code if not specified.
         if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText)
                 && !TextUtils.isEmpty(mLabel)) {