20

I have seen that since Lollipop, Android has built in Emoji flags for different countries. Is it possible to use the devices locale to retrieve the Emoji flag for that country?

I wanted to insert the Emoji flag into a TextView which contains the user's location.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Mike Walker
  • 2,944
  • 8
  • 30
  • 62

6 Answers6

63

Emoji is a Unicode symbols. Based on the Unicode character table Emoji flags consist of 26 alphabetic Unicode characters (A-Z) intended to be used to encode ISO 3166-1 alpha-2 two-letter country codes (wiki).

That means it is possible to split two-letter country code and convert each A-Z letter to regional indicator symbol letter:

private String localeToEmoji(Locale locale) {
    String countryCode = locale.getCountry();
    int firstLetter = Character.codePointAt(countryCode, 0) - 0x41 + 0x1F1E6;
    int secondLetter = Character.codePointAt(countryCode, 1) - 0x41 + 0x1F1E6;
    return new String(Character.toChars(firstLetter)) + new String(Character.toChars(secondLetter));
}

Or in Kotlin, for example (assuming UTF-8):

val Locale.flagEmoji: String
    get() {
      val firstLetter = Character.codePointAt(country, 0) - 0x41 + 0x1F1E6
      val secondLetter = Character.codePointAt(country, 1) - 0x41 + 0x1F1E6
      return String(Character.toChars(firstLetter)) + String(Character.toChars(secondLetter))
    }

Where 0x41 represents uppercase A letter and 0x1F1E6 is REGIONAL INDICATOR SYMBOL LETTER A in the Unicode table.

Note: This code example is simplified and doesn't have required checks related to country code, that could be not available inside the locale.

milosmns
  • 3,595
  • 4
  • 36
  • 48
Dmitry
  • 1,427
  • 15
  • 16
  • can i get all coutnries flag ? – Khizar Hayat Aug 04 '16 at 11:16
  • The java.util.Locale.getISOCountries() method returns a list of all 2-letter country codes defined in ISO 3166. You can use these strings to generate emojis. – Dmitry Aug 05 '16 at 09:48
  • This should be the accepted answer. This is how it should be done, and how it is done on iOS too. And more kudos for the educational simplification note! – Stéphane Péchard Sep 16 '16 at 12:52
  • Android 4.4 and lower don't have these emojis in the default fonts. If you want it to work on those, you will need to embark your own font in the app (the official Android font for 5.0 and above is Noto Color Emoji : https://www.google.com/get/noto/#emoji-zsye-color) – Julien Arzul Dec 08 '16 at 14:55
  • @JulienArzul: Just adding a new font may not be sufficient. Flag emojis are different to most Unicode characters and even to most other emoji characters in that it takes two whole codepoints to map to one glyph. That is not the same as surrogates, which are made up of two JavaScript "characters". Each half of the flag emoji is an "astral" codepoint made up of two surrogate halves, so actually *four* JavaScript "characters". So the font rendering engine of the OS needs to be aware of this. I don't have a way to test this across Android versions so can't say what actually happens. – hippietrail Sep 28 '17 at 03:15
  • I've tested embedding the font on an application that support 4.2 as the minSdk and it was working fine. From what I've been able to find (https://developer.android.com/reference/java/util/Locale.html), Unicode 6 is supported since Android 4.0, so theoretically it should work since that version (but I would expect some bugs in the first version...) – Julien Arzul Oct 02 '17 at 06:55
  • @hippietrail I think you're mixing native Android applications with web-based rendering (you're talking about Javascript characters in your comment). I personally have no idea how a Webview would render those unicode characters (at least before Android 4.4 where they introduced Chromium) – Julien Arzul Oct 02 '17 at 06:57
  • @JulienArzul: Sorry I'm using React Native so it has an embedded JS engine. V8 on Android, not using any webviews, just native rendering. But I forgot about my platform when I wrote that comment. I'm not sure whether native Android internally uses UTF-8 or UTF-16, but I assume the former which means there should be no surrogates to worry about. But some programmers don't grok this, especially if they have a background in platforms based on UTF-16, such as Java, Javascript, and Windows. Unfortunately with my underpowered systems I don't have a way to test native Android at this time. – hippietrail Oct 03 '17 at 01:27
  • Very good idea, unfortunately most of the time it returns the country code (e.g. `AU` for *Australia*) in uppercase, bold and blue format instead of the flag glyph. – (tested on a tablet running Android 5.1.1) – Mickäel A. Jun 21 '18 at 13:50
  • @MickaëlA. you can embed your own font where there is no missing flags, for example the last version of [Noto Emoji](https://github.com/googlei18n/noto-emoji/tree/master/fonts) – Dmitry Jun 21 '18 at 14:38
  • 1
    @Dmitry I ended up using the `EmojiCompat` API (from the support library) which I didn't know about – it solves this exact problem and it's literally two lines of code to integrate – Mickäel A. Jun 21 '18 at 20:12
  • This doesn't work for Caribbean Netherlands, Falkland Islands, Mayotte, Martinique, New Caledonia, St. Martin, St. Helen... and quite a few others. – Danish Khan Jan 06 '19 at 11:40
  • How can do square? – Nitin Karale Feb 09 '19 at 19:43
  • It's working for me Perfectly. Thank boss. save my day – Shohel Rana Oct 24 '19 at 05:22
  • For Android I used google/libphonenumber to get various data about phone numbers, locales, etc. I used this method to get regions: `com.google.i18n.phonenumbers.PhoneNumberUtil#getSupportedRegions` and then something like `Locale("", region).getDisplayCountry(locale)` to get the country name and `"+" + phoneNumberUtil.getCountryCodeForRegion(region).toString()` to get the country dialing code. It's a bit of work but it seems pretty reliable so far. – milosmns Jan 16 '20 at 16:58
  • Or, you can use `EmojiCompat` lib as others proposed – milosmns Jan 17 '20 at 09:30
  • 1
    Convert country code (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) to Flag emoji using Kotlin functions. https://gist.github.com/asissuthar/cf8fcf0b3be968b1f341e537eb423163 – asissuthar Oct 04 '22 at 10:05
21

Based on this answer, I wrote a Kotlin version below using extension function.

I also added some checks to handle unknown country code.

/**
 * This method is to change the country code like "us" into 
 * Stolen from https://stackoverflow.com/a/35849652/75579
 * 1. It first checks if the string consists of only 2 characters: ISO 3166-1 alpha-2 two-letter country codes (https://en.wikipedia.org/wiki/Regional_Indicator_Symbol).
 * 2. It then checks if both characters are alphabet
 * do nothing if it doesn't fulfil the 2 checks
 * caveat: if you enter an invalid 2 letter country code, say "XX", it will pass the 2 checks, and it will return unknown result
 */
fun String.toFlagEmoji(): String {
    // 1. It first checks if the string consists of only 2 characters: ISO 3166-1 alpha-2 two-letter country codes (https://en.wikipedia.org/wiki/Regional_Indicator_Symbol).
    if (this.length != 2) {
        return this
    }

    val countryCodeCaps = this.toUpperCase() // upper case is important because we are calculating offset
    val firstLetter = Character.codePointAt(countryCodeCaps, 0) - 0x41 + 0x1F1E6
    val secondLetter = Character.codePointAt(countryCodeCaps, 1) - 0x41 + 0x1F1E6

    // 2. It then checks if both characters are alphabet
    if (!countryCodeCaps[0].isLetter() || !countryCodeCaps[1].isLetter()) {
        return this
    }

    return String(Character.toChars(firstLetter)) + String(Character.toChars(secondLetter))
}

Runnable Code Snippet

I also included a runnable Kotlin snippet using Kotlin Playground. In order to run the snippet you need to:

  1. click "Show code snippet"
  2. click "Run Code Snippet"
  3. click the play button at the right top of the generated console
  4. scroll to the bottom to see the result (it's hidden..)
    <script src="https://unpkg.com/kotlin-playground@1.6.0/dist/playground.min.js" data-selector=".code"></script>
    
    
    <div class="code" style="display:none;">
    
    /**
     * This method is to change the country code like "us" into 
     * Stolen from https://stackoverflow.com/a/35849652/75579
     * 1. It first checks if the string consists of only 2 characters: ISO 3166-1 alpha-2 two-letter country codes (https://en.wikipedia.org/wiki/Regional_Indicator_Symbol).
     * 2. It then checks if both characters are alphabet
     * do nothing if it doesn't fulfil the 2 checks
     * caveat: if you enter an invalid 2 letter country code, say "XX", it will pass the 2 checks, and it will return unknown result
     */
    fun String.toFlagEmoji(): String {
        // 1. It first checks if the string consists of only 2 characters: ISO 3166-1 alpha-2 two-letter country codes (https://en.wikipedia.org/wiki/Regional_Indicator_Symbol).
        if (this.length != 2) {
            return this
        }
    
        val countryCodeCaps = this.toUpperCase() // upper case is important because we are calculating offset
        val firstLetter = Character.codePointAt(countryCodeCaps, 0) - 0x41 + 0x1F1E6
        val secondLetter = Character.codePointAt(countryCodeCaps, 1) - 0x41 + 0x1F1E6
    
        // 2. It then checks if both characters are alphabet
        if (!countryCodeCaps[0].isLetter() || !countryCodeCaps[1].isLetter()) {
            return this
        }
    
        return String(Character.toChars(firstLetter)) + String(Character.toChars(secondLetter))
    }
    
    fun main(args: Array&lt;String&gt;){
      println("us".toFlagEmoji())
      println("AF".toFlagEmoji())
      println("BR".toFlagEmoji())
      println("MY".toFlagEmoji())
      println("JP".toFlagEmoji())
    }
    
    </div>
I'm a frog dragon
  • 7,865
  • 7
  • 46
  • 49
3

When I first wrote this answer I somehow overlooked that I've only worked on Android via React Native!

Anyway, here's my JavaScript solution that works with or without ES6 support.

    function countryCodeToFlagEmoji(country) {
      return typeof String.fromCodePoint === "function"
        ? String.fromCodePoint(...[...country].map(c => c.charCodeAt() + 0x1f185))
        : [...country]
            .map(c => "\ud83c" + String.fromCharCode(0xdd85 + c.charCodeAt()))
            .join("");
    }

console.log(countryCodeToFlagEmoji("au"));
console.log(countryCodeToFlagEmoji("aubdusca"));

If you want to pass in the country codes as capital letters instead, just change the two offsets to 0x1f1a5 and 0xdda5.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
3

You can get the country code very simple. I want to talk about flag selection according to country code.

I wrote a class about it and it is very simple to use.

usage:

String countryWithFlag = CountryFlags.getCountryFlagByCountryCode("TR") + " " + "Türkiye";

Output : Türkiye

You can use it with Android TextView too :)

You can check out the class here

It works very well on Android 6 and above.

Burak Dizlek
  • 4,805
  • 2
  • 23
  • 19
1

I am using this so easily. Get the Unicode from here.

For Bangladesh flag it is U+1F1E7 U+1F1E9 Now,

{...

 String flag = getEmojiByUnicode(0x1F1E7)+getEmojiByUnicode(0x1F1E9)+ " Bangladesh";
    }
    public String getEmojiByUnicode(int unicode){
        return new String(Character.toChars(unicode));
    }

It will show > (Bangladeshi flag) Bangladesh

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
abir-cse
  • 507
  • 3
  • 12
0

I was looking for that too but I don't think it's possible yet.

Have a look here: http://developer.android.com/reference/java/util/Locale.html

No mentioning about flags.

_

Alternately you can check the answer here:

Android Countries list with flags and availability of getting iso mobile codes

that might help you.

Community
  • 1
  • 1
The Berga
  • 3,744
  • 2
  • 31
  • 34