Android Get Country Emoji Flag Using Locale
Asked Answered
K

6

24

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.

Kunming answered 27/5, 2015 at 22:36 Comment(0)
S
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.

Stratify answered 17/6, 2015 at 23:42 Comment(1)
Thank you for the help. I was able to use the device country code to find the emoji flag.Kunming
E
68

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.

Eusporangiate answered 7/3, 2016 at 17:4 Comment(17)
can i get all coutnries flag ?Embowed
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.Eusporangiate
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!Philia
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 : google.com/get/noto/#emoji-zsye-color)Denudate
@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.Vercingetorix
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 (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...)Denudate
@Vercingetorix 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)Denudate
@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.Vercingetorix
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)Indelicacy
@MickaëlA. you can embed your own font where there is no missing flags, for example the last version of Noto EmojiEusporangiate
@Eusporangiate 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 integrateIndelicacy
This doesn't work for Caribbean Netherlands, Falkland Islands, Mayotte, Martinique, New Caledonia, St. Martin, St. Helen... and quite a few others.Gurule
How can do square?Vivisect
It's working for me Perfectly. Thank boss. save my daySpiffy
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.Teletype
Or, you can use EmojiCompat lib as others proposedTeletype
Convert country code (en.wikipedia.org/wiki/ISO_3166-1_alpha-2) to Flag emoji using Kotlin functions. gist.github.com/asissuthar/cf8fcf0b3be968b1f341e537eb423163Bricker
S
24

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://mcmap.net/q/541972/-android-get-country-emoji-flag-using-locale
 * 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/[email protected]/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://mcmap.net/q/541972/-android-get-country-emoji-flag-using-locale
     * 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>
Skerl answered 21/6, 2018 at 8:24 Comment(2)
does this work on kitkat? When i debug it i see question marks?Underground
This works perfecly on my phone but will it work for older apis?Inherence
V
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.

Vercingetorix answered 28/9, 2017 at 3:12 Comment(0)
S
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.

Surround answered 22/4, 2020 at 12:31 Comment(0)
W
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

Winch answered 17/9, 2018 at 1:34 Comment(0)
S
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.

Stratify answered 17/6, 2015 at 23:42 Comment(1)
Thank you for the help. I was able to use the device country code to find the emoji flag.Kunming

© 2022 - 2025 — McMap. All rights reserved.