7

I'm trying to put together a small android app that can randomly return an emoji to the user. My intention is to just use actual unicode emoji characters, and return them as unicode string characters.

I built a full array of unicode strings that could be randomly chosen from, and many will display correctly. However some are showing up as unsupported characters (a rectangle with an x through it).

Obviously not every platform will support every unicode emoji character, but if possible I'd like a way to determine what is and isn't a supported character. The ideal would be to query for a list of supported characters, but being able to test individual characters would also do the job just fine.

SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73
  • did you find a solution for this? Thanks! – Maragues Sep 21 '16 at 11:06
  • 1
    @Maragues Unfortunately not, I resigned myself to just have a constant array where I manually defined the safe emoji that I could expect to work. – SuperBiasedMan Sep 21 '16 at 11:14
  • It looks like Android 23 does include something (https://developer.android.com/reference/android/graphics/Paint.html#hasGlyph(java.lang.String)), but the code invokes a native function, so I guess I'm out of luck. Thanks for the quick response – Maragues Sep 21 '16 at 11:16
  • @Maragues, why are you out of luck? Is it because you need to support pre-API 23 or because `hasGlyph` is not working for you? – Suragch Feb 02 '17 at 05:54
  • I don't even remember what I was trying to do :( – Maragues Feb 02 '17 at 14:09

3 Answers3

6

Also check out Paint.hasGlyph(String), which was added in API level 23. You can use this to test if a character like an emoji has a glyph available.

This is what the documentation says:

boolean hasGlyph (String string)

Determine whether the typeface set on the paint has a glyph supporting the string. The simplest case is when the string contains a single character, in which this method determines whether the font has the character. In the case of multiple characters, the method returns true if there is a single glyph representing the ligature. For example, if the input is a pair of regional indicator symbols, determine whether there is an emoji flag for the pair.

Finally, if the string contains a variation selector, the method only returns true if the fonts contains a glyph specific to that variation.

Checking is done on the entire fallback chain, not just the immediate font referenced.

See also

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
5

So, when you talk about a character being "unsupported", it sounds like what you mean is that the current font doesn't have a glyph for the character (and either the application doesn't have fallback logic to find a different font that does, or the system doesn't have any font that does).

In regular Java, this is pretty easy: given an instance of java.awt.Font, you can see if it has a glyph for a given Unicode character by using the canDisplay method.

The Android APIs, for whatever reason, don't seem to expose a way to figure out what font you're actually working with. (android.graphics.Typeface keeps that information private: see "Check the family of a Typeface object in Android".) However, you might at least try something like new java.awt.Font("SansSerif", java.awt.Font.PLAIN, 12) to get a basic 12-point sans-serif font. You'll want to test, of course, to see if that gives a usable approximation for the emoji that the real font will be able to display.

Community
  • 1
  • 1
ruakh
  • 175,680
  • 26
  • 273
  • 307
  • You are exactly right about what I mean. Thanks for the info! It seems that the Android api doesn't include `java.awt.Font` at all, so I can't import it and use that method. But I'll see what I can do with a Typeface, and try wrangling it into a more usable font or possibly just trying to set a default font where I know when glyphs aren't supported. – SuperBiasedMan Jul 03 '16 at 10:23
  • Oh, weird -- I didn't realize that Android omitted parts of the JDK. (I'm not an Android dev, if you can't tell. :-P ) – ruakh Jul 03 '16 at 15:26
3

You can use Character.isDefined to check if a character is defined in the version of Unicode on the device.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • Ah, this is a good lead. Thanks! Unfortunately it's only occasionally catching problems. There's a lot of false positives, which makes me think it wasn't properly implemented in Android. – SuperBiasedMan Jul 02 '16 at 19:54
  • `Character.isDefined` means "does the JVM know what kind of character this is?" (e.g. whether it's whitespace, or a digit, or . . .), whereas the OP wants "does the current font have a glyph for this character?". – ruakh Jul 02 '16 at 23:58