How to detect emoji support on Android by code
Asked Answered
M

4

11

By code, I can make a button that inserts these 3 emojis into the text: ⚽️😈🐺

On many phones when the user clicks the button, though, the problem is that ⚽️😈🐺 displays as [X][X][X]. Or even worse, it displays only three empty spaces.

I would like to disable and hide my own built-in emoji-keypad on Android devices that do not display emojis correctly. Does anyone knows or have a tip on how to detect in code if a device has emoji support?

I have read that emoji is supported from android 4.1, but that is not my experience....

Matrix answered 28/8, 2016 at 18:42 Comment(4)
I suspect the X's are from an Apple iPhone or iPad, etc. I had a Galaxy for years and everyone in my family had iPhones. I would always get messages and then the X's rather than the emoticon it was supposed to be. – Gonzales
I might be an issue with iphone vs android emojis, but I would like to try detect the support of an emoji-symbol by code, I think that would be safest. – Matrix
If you already ended up solving your problem, I would be interested in seeing the details of what you did. – Dominican
Check this github.com/google/mozc/blob/master/src/android/src/com/google/… – Yingyingkow
S
11

I just implemented a solution for this problem myself. The nice thing with Android is that it is open source so that when you come around problems like these, there's a good chance you can find an approach to help you.

In the Android Open Source Project, you can find a method where they use Paint.hasGlyph to detect whether a font exists for a given emoji. However, as this method is not available before API 23, they also do test renders and compare the result against the width of 'tofu' (the [x] character you mention in your post.)

There are some other failings with this approach, but it should be enough to get you started.

Google source:

Scorekeeper answered 21/9, 2016 at 20:24 Comment(1)
flag/penguin test failed on my 4.1 device, which definitely has emoji :( – Oligopsony
P
10

Based on Jason Gore answer:

For example create boolean canShowFlagEmoji:

 private static boolean canShowFlagEmoji() {
        Paint paint = new Paint();
        String switzerland = "\uD83C\uDDE8\uD83C\uDDED"; //  Here enter Surrogates of Emoji
        try {
            return paint.hasGlyph(switzerland);
        } catch (NoSuchMethodError e) {
            // Compare display width of single-codepoint emoji to width of flag emoji to determine
            // whether flag is rendered as single glyph or two adjacent regional indicator symbols.
            float flagWidth = paint.measureText(switzerland);
            float standardWidth = paint.measureText("\uD83D\uDC27"); //  U+1F427 Penguin
            return flagWidth < standardWidth * 1.25;
            // This assumes that a valid glyph for the flag emoji must be less than 1.25 times
            // the width of the penguin.
        }
    }

And then in code whenever when you need to check if emoji is available:

if (canShowFlagEmoji()){
    // Code when FlagEmoji is available
} else {
    // And when not
}

Surrogates of emoji you can get here, when you click on detail.

Prostration answered 30/1, 2017 at 17:9 Comment(1)
I haven't had a chance to test this yet, but getting some actual code in an answer is definitely an improvement over just links. – Dominican
L
3

An alternative option might be to include the Android "Emoji Compatibility" library, which would detect and add any required Emoji characters to apps running on Android 4.4 (API 19) and later: https://developer.android.com/topic/libraries/support-library/preview/emoji-compat.html

Lustick answered 18/8, 2017 at 13:1 Comment(1)
Thank you but that Library is not fun to deal with. You have to do special timely initializing of the library not to mention other concerns – Autopsy
L
0
        final Paint paint = new Paint();
        final boolean isEmojiRendered;
        if (VERSION.SDK_INT >= VERSION_CODES.M) {
            isEmojiRendered = paint.hasGlyph(emoji);
        }
        else{
            isEmojiRendered = paint.measureText(emoji) > 7;
        }

The width > 7 part is particularly hacky, I would expect the value to be 0.0 for non-renderable emoji, but across a few devices, I found that the value actually ranged around 3.0 to 6.0 for non-renderable, and 12.0 to 15.0 for renderable. Your results may vary so you might want to test that. I believe the font size also has an effect on the output of measureText() so keep that in mind.

The second part was answerd by RogueBaneling here how can I check if my device is capable to render Emoji images correctly?

Lacy answered 1/7, 2021 at 5:30 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.