Fun with Flags

The Emoji Experiment

Barry Irvine
5 min readJan 17, 2017

Those of you who read the first thrilling instalment of Fun with Flags will know that I had some issues with the performance of using vector drawables in my country picker and I hit on the idea of using flag emojis instead of drawables.

Flag emojis were introduced in Android KitKat as part of the 2010 Unicode 6.0 standard. Initially the Unicode standard launched with just 10 flags but the way was paved for an extensible solution.

The way that flag emojis are defined is actually quite cunning. There are 26 regional indicator symbols from 🇦 to 🇿. These are represented in hex from 0x1F1E6 to 0x1F1FF. If you combine any two of these characters to form a valid ISO-3166 country code (or even some other combinations like EU or UN) then it will show a flag emoji for that country/entity. These numbers are bigger than the 16-bit limit on a char object in Java so we often have to combine surrogate pairs when displaying an emoji in Android or convert them from a hex number to a pair of chars.

Method

With some very simple logic it’s easy to convert an ISO country name to produce its flag emoji string. Those of you who remember your ASCII tables will know that the character A is represented by the number 65 (0x41). Therefore we can create an ASCII offset constant that is equivalent to 0x1F1E6 minus 0x41.

/**
* The regional indicators go from 0x1F1E6 (A) to 0x1F1FF (Z).
* This is the A regional indicator value minus 65 decimal so
* that we can just add this to the A-Z char
**/
private static final int REGIONAL_INDICATOR_OFFSET = 0x1F1A5;

We can then use this to get each regional indicator symbol that will form part of our flag emoji.

public static String getRegionalIndicatorSymbol(final char character) {
if (character < 'A' || character > 'Z') {
throw new IllegalArgumentException("Invalid character: you must use A-Z");
}
return String.valueOf(Character.toChars(REGIONAL_INDICATOR_OFFSET + character));
}

We can map this on to our original enum with another simple method:

public String getEmojiFlag() {
return getRegionalIndicatorSymbol(name().charAt(0)) + getRegionalIndicatorSymbol(name().charAt(1));
}

And now we have the emoji flag for every country in our list.

Results

“this is probably the first and last time that these words will ever be uttered: Samsung is better than Google”.

The result of using emojis instead of drawables obviously improved the performance and memory use of the country adapter. Unfortunately, on a typical Google phone (Nexus, Pixel etc.) there are quite a few missing emoji flags.

These fall into one of two categories:

  1. Countries that have an official flag from another country (US, NL or FR) and only an unofficial flag or coat of arms (examples include Caribbean Netherlands (BQ), Wallis & Futuna (WF) and St Martin (MF))
  2. Countries that are disputed (e.g. Western Sahara–EH or Falkland Islands –FK)

In this, and this is probably the first and last time that these words will ever be uttered: Samsung is better than Google. If you refer to http://emojipedia.org/ you can see that although Samsung and LG have defined emojis for those flags, Google’s name is often conspicuous by its absence. Instead, when I render 🇫 🇰 on a Google device, I get an uninspired empty wavy flag shape.

There’s also no easy way of determining (at least that I know of) if the device that you’re rendering the emoji flag on is actually going to display:

  • a real flag
  • the two regional letters side-by-side
  • or an empty flag emoji/unknown symbol.

To do this you’d probably have to create a mapping between the ISO country code, the Android version that the user is running on and the device manufacturer. And then you’d need to test that with real devices for each flag. And once you know that you have one of those edge cases then you’d need to show a different regional indicator symbol pairing for that country code (for example mapping BQ to NL instead of showing the Bonaire flag).

That seems like a lot of work for something that is really just improving the visual presentation of your country picker without actually delivering any real value to the user.

These are not the emoji flags you’re looking for

Conclusion

If your country picker dialog doesn’t need to include every single ISO-3166 country in the world then you should probably use emojis rather than using complex svg files or increasing your APK size with lots of different density png files of all the flags. And probably just a plain text list when the Build SDK version is less than Android KitKat.

For the moment, here at Depop, I’ve stuck with the svg images for our country picker and given the user the perception that it actually loads quite quickly by creating the drawables that we need first in the dialog before adding the remainder in the background. Although I don’t imagine we have a huge amount of (potential) users in most of the countries for which the emojis are missing I’d rather keep the visual enrichment of not just using plain text and I’d rather not create an international incident by showing a UK or Argentinian flag for the Falklands/Las Malvinas. There are other use cases where I have started to use the emoji flags when I have a smaller subset of countries.

You can find an example country picker dialog, all the svgs and the emoji flag methods mentioned in both parts of this post on this GitHub repo. I’m more than happy to review any pull requests that might be optimising the often cumbersome or missing vector drawables or any other improvements that you can think of.

As usual, if you enjoyed this post, I’d appreciate a recommend, follow, share or tweet.

--

--

Barry Irvine

Writing elegant Android code is my passion — but with 20+ years experience in roles from programme delivery to working at the coal face, I’ve seen it all.