Upgrade to Pro — share decks privately, control downloads, hide ads and more …

NO MORE □  —  MASTERING EMOJI ON ANDROID (Droidcon Berlin)

NO MORE □  —  MASTERING EMOJI ON ANDROID (Droidcon Berlin)

Tofus (□) are representations used when a specific character (like an Emoji) cannot be displayed. You have seen them and so your users.

Thanks to EmojiCompat now Android developers have a way to provide Emoji compatibility for older devices but does it solve all the issues developers have with Emoji?

Have you wondered why Twitter counts characters differently depending on the Emoji? Or how gender and skin tone Emoji modifiers work? How can I have a similar functionality as Slack on my app with custom Emoji? Do all your users see the same Emoji?

On this talk you will learn about the different pitfalls developers face when working with Emoji like code points the Fitzpatrick modifiers and short-names you will learn how to use EmojiCompat and I will show you alternatives to it. In this talk you will learn:

- How Emoji was created
- How Emoji works
- What are the problems developers face with Emoji
- How to use EmojiCompat including dynamic font downloading
- What is EmojiCompat not solving and what can you do
- What alternatives are there to EmojiCompat and how to implement them

After this talk you will be an Emoji expert no longer afraid of showing □ (tofu) to your users!

Miguel Beltran

June 27, 2018
Tweet

More Decks by Miguel Beltran

Other Decks in Technology

Transcript

  1. Why Emoji matters? What problems do Android developers face? What

    solutions do we have? Is EmojiCompat the greatest thing ever?
  2. Emotions Source: People interpret the same emoji in completely different

    ways https://www.theverge.com/2016/4/11/11406944/emoji-meaning-difference-ios-android
  3. Extra-short-intro to Unicode Hello U+0048 U+0065 U+006C U+006C U+006F Unicode:

    Single character set that contains ALL characters of the Universe Each character maps to a Codepoint A Codepoint may be represented in memory differently! Codepoint UTF-8 UTF-16 H U+0048 48 0048 U+1F602 F0 9F 98 82 D83D DE02
  4. How Emoji works Emoji: Graphic representation of one or more

    Unicode chars (Codepoints) "Face With Tears of Joy” U+1F602 val emoji = "\uD83D\uDE02"
  5. How Emoji works “Woman Technologist: Medium-Dark Skin Tone” val emoji

    = “\uD83D\uDC69\uD83C\uDFFE\u200D\uD83D\uDCBB" U+1F469 U+1F3FE U+200D U+1F4BB
  6. How long is an Emoji? Challenge: How many “Woman Technologist:

    Medium-Dark Skin Tone” Emojis can you fit on a Tweet? A: 280 B: 140 C: 40 Solution: 40 280 / 7 = 40
  7. How long is an Emoji? —> Improvement emoji.length = 7

    emoji.codePointCount(0, emoji.length) = 4 val emoji = “\uD83D\uDC69\uD83C\uDFFE\u200D\uD83D\uDCBB"
  8. How long is an Emoji? —> Improvement val it =

    BreakIterator.getCharacterInstance() it.setText(emoji) var count = 0 while (it.next() != BreakIterator.DONE) { count++ } count = 3 on API 23 count = 1 on API 25
  9. Let’s look at three solutions Custom solution: Images and Spans

    Custom solution: Font file Using EmojiCompat
  10. Images and Spans Strategy: 1. Find an Emoji on a

    String 2. Replace with an ImageSpan 3. Repeat for the whole String
  11. Finding Emoji on Strings Get a nice dictionary: EmojiOne “emoji.json”:

    1.38 MB! Fast JSON parsing: com.jsoniter —> but you won’t need to Efficient pattern matching —> Regular Expression
  12. Emoji assets Download: emojione/emojione-assets • Free: PNG 32px, 64px, 128px

    • Paid: SVG and larger PNG Example: SLICE OF PIZZA (U+1F355) —> 1f355.png
  13. Matching and displaying val PATTERN = “\\ud83c\\udf55".toRegex() val matches =

    PATTERN.findAll(text) for (match in matches) { spannableString.setSpan( ImageSpan(context, R.drawable.emoji_1f355), match.range.start, match.range.endInclusive + 1, SpannableString.SPAN_INCLUSIVE_INCLUSIVE ) } Solution: DynamicDrawableSpan (and resize the drawable)
  14. Custom font file Strategy: 1. Include font file with Emoji

    2. Set font file containing Emoji to TextView 3. Set text to TextView
  15. Custom font file: Setup 1. Download Android font 2. Place

    in assets/fonts Download: https://www.emojione.com/download
  16. Custom font file: Hold on… textView.text = "Numbers: 1 2

    3 4" Solution: Parse Emoji and create TypefaceSpans
  17. EmojiCompat: Setup (downloadable) val fontRequest = FontRequest( "com.google.android.gms.fonts", "com.google.android.gms", "Noto

    Color Emoji Compat", R.array.com_google_android_gms_fonts_certs) val config = FontRequestEmojiCompatConfig(this, fontRequest) EmojiCompat.init(config) Init takes 150 ms! But happens asynchronously
  18. EmojiCompat: Setup (downloadable) Downloadable fonts get updated automatically! Find it

    in data/data/com.google.android.gms/files/fonts/opentype Noto_Color_Emoji_Compat-400-100_0-0_0.ttf Version 2.003;GOOG;noto-emoji:20171030:a5efe6ca61db
  19. EmojiCompat: Handling init delay EmojiCompat.get().registerInitCallback(object : EmojiCompat.InitCallback() { override fun

    onInitialized() { textView.text = EmojiCompat.get().process(string) } override fun onFailed(throwable: Throwable?) { // handle error? textView.text = string } } )