Unusual android logic operator not working comparing two strings - android

I'm trying a simple check. If a string name locale has "es" as value.
public String locale =
Locale.getDefault().getLanguage().toLowerCase().toString();
// ...
Log.v(tag, "Idioma del sistema: «" + locale +"»");
if (locale != "es") {
showDialog(R.string.warningTitleDialog,
"We are sorry that this tool is only available in Spanish " +
"language. See Author menu item for more information. [" +
locale + "]");
locale = "en";
}
adb logcat shows "es" as content of string "locale" but code inside the condition is being executed.

It seem that problem is not of android or of logic this is in JAVA.
Try this and tell us what is happening
if(!locale.equals("en"))
{
//Your Code
}

Never use != or == in association with strings. Try the method equals like this:
if(locale.equals("es"))
This will return true if the strings locale and "es" contain the same character
sequence. Because the equals( ) method compares the characters inside a String object. The == operator compares two object references to see whether they refer to the same instance.
See What is the difference between == vs equals() in Java? for more information.

Related

Android Get Country Emoji Flag Using Locale

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.
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.
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:
click "Show code snippet"
click "Run Code Snippet"
click the play button at the right top of the generated console
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<String>){
println("us".toFlagEmoji())
println("AF".toFlagEmoji())
println("BR".toFlagEmoji())
println("MY".toFlagEmoji())
println("JP".toFlagEmoji())
}
</div>
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.
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.
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
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.

Getting Locale variant for simplified chinese

How can I get simplified chinese description (简体)? From the available locale Locale.SIMPLIFIED_CHINESE, no method seems to return this description:
getDisplayLanguage() returns the correct language name, but without the variant.
getDisplayName() returns the correct language name and country, but also without the variant.
getDisplayVariant() returns an empty string.
I've also tried to build a new Locale using the different constructors, also to no avail.
new Locale("zh", "CN");
new Locale("zh", "CN", "Hans");
I've checked the Android source code for LocalePicker and I've concluded that it is loaded from the resources (special_locale_codes and special_locale_names).
Any solutions besides having to hardcode/include this string in my resources?
Let me explain my process on how I tackled this. First, I found this block of code in LocalePicker.java
private static String getDisplayName(Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) {
String code = l.toString();
for (int i = 0; i < specialLocaleCodes.length; i++) {
if (specialLocaleCodes[i].equals(code)) {
return specialLocaleNames[i];
}
}
return l.getDisplayName(l);
}
which takes in a Locale as you already know. Then it tries to find the locale code in the specialLocaleCodes string array. The specialLocaleNames you are seeking are obtained from arrays.xml as you've helpfully stated:
<string-array translatable="false" name="special_locale_codes">
<item>ar_EG</item>
<item>zh_CN</item>
<item>zh_TW</item>
</string-array>
and the corresponding languages
<string-array translatable="false" name="special_locale_names">
<item>العربية</item>
<item>中文 (简体)</item>
<item>中文 (繁體)</item>
</string-array>
Notice the code with the simplified Chinese is zh_CN and the last two characters are capitalized.
However,
Locale locale = new Locale("zh_CN");
System.out.println("Locale: " + locale);
prints
Locale: zh_cn
Notice the lower case. So there is no way specialLocaleCodes[i].equals(code) will return true. So then I poked around Locale.java and, long story short, we can bypass that case-changing jumble by doing this (and you MUST keep the 3rd parameter as an empty string for this to work):
Locale locale = new Locale("zh", "CN", "");
System.out.println("Locale: " + locale);
Prints
Locale: zh_CN
With this you should be able to do this:
Locale locale = new Locale("zh", "CN", "");
System.out.println("Name:" + locale.getDisplayName(locale));
Upon further inspection on Kitkat using this (thank you Andrew!)
int specialLocaleNamesId = Resources.getSystem().getIdentifier("special_locale_names", "array", "android");
String[] specialLocaleNames = Resources.getSystem().getStringArray(specialLocaleNamesId);
it was possible to print out
العربية,中文 (简体),中文 (繁體)
as expected. However, something in Kitkat is still preventing the correct string to display. Frustrating.
However, in Lollipop 5.0+ and Java 1.7 this works using forLanguageTag() in Locale.
Locale locale = Locale.forLanguageTag("zh-Hans");
System.out.println("getDisplayName:" + locale.getDisplayName(locale));
System.out.println("getDisplayLanguage:" + locale.getDisplayLanguage(locale));
which prints
getDisplayName:中文 (简体中文)
getDisplayLanguage:中文
You could probably access the android internal resource: com.android.internal.R.array.special_locale_names the same way it's done in LocalePicker:
final Resources resources = context.getResources();
final String[] specialLocaleNames = resources.getStringArray(com.android.internal.R.array.special_locale_names);
But it's probably safer to use your own resource here (avoiding
the use of internals)

Java (Android) - can't detect first character of string?

Not sure if I've missed something really obvious. I know for sure that my String is as follows:
1This is a test message
I'm trying to detect whether the first character is '1', so here's some of my code:
//This outputs '1'
Toast noCmd = Toast.makeText(Play.this, decodedMessage.substring(0,1), Toast.LENGTH_SHORT);
noCmd.show();
if (decodedMessage.charAt(0) == 1) {
noCmd = Toast.makeText(Play.this, "This should show up", Toast.LENGTH_SHORT);
noCmd.show();
noCmd = Toast.makeText(Play.this, finalMessage + " from " + sender, Toast.LENGTH_SHORT);
noCmd.show();
}
if (decodedMessage.substring(0,1) == "1") {
noCmd = Toast.makeText(Play.this, "This should show up", Toast.LENGTH_SHORT);
noCmd.show();
noCmd = Toast.makeText(Play.this, finalMessage + " from " + sender, Toast.LENGTH_SHORT);
noCmd.show();
}
As you can see, I'm trying two methods to get the toasts inside the if statement to show up. Weirdly, when the code is run, only the top (unconditional) toast displays.
Any ideas?
For the first one, the char is '1'. What's currently happening in your code is that because you're comparing a char with an integer, the char is being converted to an int using its character code. For a 1, that comes out as 49, which is not equal to the integer 1. You need to compare the char you're retrieving from the String with the char representing a digit "1", and that means you need to write it as '1'.
For the second one, you need to use .equals() to test for String equality, rather than ==. If you take two String objects s and t that have the same content, then you still will find that s==t will come out as false, unless they happen to be pointing at the same bit of memory (i.e., they're the same instance). To check whether they have the same content, you check
s.equals(t)
rather than
s==t
So, in summary, make the first one
if (decodedMessage.charAt(0) == '1') {
//toast stuff
}
and the second one
if ("1".equals(decodedMessage.substring(0,1))) {
//toast stuff
}
The reason, by the way, for not writing
if (decodedMessage.substring(0,1).equals("1")) {
//toast stuff
}
instead is that if the String on which you call .equals() is null then you'll end up with a NullPointerException, which usually you want to avoid. Actually in this case it would be fine, because the substring() call won't return null, but in the general case if you want to test whether s and "something" are equal then you use
"something".equals(s)
rather than
s.equals("something")
just in case s is null.
1 is an integer with value 1. If you want the ASCII 1, use '1' in single quotes which has the integer value of 49.
For comparing strings, use equals() and not ==. See How do I compare strings in Java?
To compare strings you need to use equals method:
if("1".equals(decodedMessage.charAt(0))){
}

Only else part is executed [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I compare strings in Java?
even whel length is 0 and flag9 is null only else part is executed.can someone help me
Log.d(TAG, "flag8 "+ getIntent().getExtras().getString("flag").length());
Log.d(TAG, "flag9 "+ getIntent().getExtras().getString("flag"));
if( getIntent().getExtras().getString("flag")=="0" ||getIntent().getExtras().getString("flag").length()==0)
{
Log.d(TAG, "hidebeta "+ getIntent().getExtras().getString("flag"));
beta.putExtra("beta", "hidebeta");
flag=1;
beta.putExtra("flag", "1");
}
else {
beta.putExtra("beta","showbeta");
Log.d(TAG, "showbeta "+ getIntent().getExtras().getString("flag"));
flag=0;
beta.putExtra("flag","0");
}
In Java you cannot use == to compare Strings, you must use:
if(string.equals("example"))
So let's use equals() in your conditional and optimize it:
String flag = getIntent().getStringExtra("flag");
if(flag.equals("0") || flag.length()==0)
(Also you ought to be safe and check if getIntent() and flag are not null before trying to access them.)
Read How do I compare strings in Java? or the documentation on Comparing Strings for more information.
use equals to compare strings, not == (which compares references to objects)
You should never use == operator for comparing two Strings, as it compares the actual references, not their values. Use equals() method instead. Hope this helps.

Compare two things doesn't work

I have a strange problem in my android app. I must compare two string which are equals. I tried this :
if (raspunsdata.equals(rok)) {
System.out.println("changed ");
} else
System.out.println("no change");
}
but I get always "no change". Before this I have System.out.println for both strings, and both of them have the same value.
I tried also (raspunsdata==rok) and raspunsdata.contentEquals(rok) but I have the same problem. Why? I cant understand this.,...please help...
You might have unwanted white spaces. Might need to use the trim function just to make sure.
if (raspunsdata.trim.equals(rok.trim())) {
System.out.println("changed ");
} else
System.out.println("no change");
}
Btw equals is the correct way to check whether the values are the same.
.equals - compares the values of both objects. If you have 2 Strings with the same characters sets .equals will return true;
== - compares if two objects references are equal.
For example:
String a = "lol";
String b = a;
a == b - will be true.
Try reading: http://www.devdaily.com/java/edu/qanda/pjqa00001.shtml

Categories

Resources