How to check for a device language in android? - java

I want my application to check which language the phone is using. This if statement is supposed to do that:
if (Locale.getDefault().getLanguage().equals("en")) {
yourYesResponse = "That is great " + usersName + "!";
}
else if (Locale.getDefault().getLanguage().equals("fr")) {
yourYesResponse = "C\'est bon " + usersName + "!";
}
But even if my device is set to French it still displays the English. Is there anything wrong with this if statement and if yes, then what?
EDIT: Thanks for the help. I appreciate it.

In order to get the device language, you can use this:
Locale.getDefault().getDisplayLanguage();
or,
Locale.getDefault().getLanguage(); //to get usual language code

Use :
Locale.getDefault().getLanguage().contentEquals("en")
The String#equals() not only compares the String's contents, but also checks if the other object is also an instance of a String. The String#contentEquals() methods only compares the contents (the character sequence) and does not check if the other object is also an instance of String. It can be anything as long as it is an implementation of CharSequence or an instance of StringBuffer.

For have the system language:
Locale.getDefault().getDisplayLanguage();

As everyone already explain that i18N (String XMLs in different languages) have to be used to achieve this simple thing but if you are looking for user language for some other purpose then please use one of this.
Locale.getDefault().getLanguage();
This will give language iso code i.e. "de", "ru".
OR
Resources.getSystem().getConfiguration().locale;
This returns global shared Resources object that provides access to only system resources.

You could solve this by declaring a string resource file for each language.
Create resource folders named values-fr and values-en and add a file called strings.xml to both folders.
The string.xml file in values-en:
<resources>
<string name="good">That is great </string>
</resources>
And you load the resource like this:
yourYesResponse = getResources().getText(R.string.good) + usersName + "!";
Niek was faster...

Usually locale is provided with followig format fr_FR where first fr is language code and second one is country code, thats why you should use
Locale.getDefault().getLanguage().startsWith("fr")
but Android way is to use resources
getString(R.string.hello, userName);
Edited: Ok, shame on me, I didn't notice that you call getLanguage(), but second part is correct.

The Android way of doing this, is using xml resources, as explained in Localizing with Resources.
values/strings.xml:
<resources>
<string name="yes_response">That is great, %s!</string>
</resources>
values-fr/strings.xml:
<resources>
<string name="yes_response">C\'est bon, %s!</string>
</resources>
Code:
yourYesResponse = context.getString(R.string.yes_response, usersName);
Motivation:
It is good practice to use the Android resource framework to separate
the localized aspects of your application as much as possible from the
core Java functionality:
You can put most or all of the contents of your application's user
interface into resource files, as described in this document and in
Providing Resources.
The behavior of the user interface, on the other
hand, is driven by your Java code. For example, if users input data
that needs to be formatted or sorted differently depending on locale,
then you would use Java to handle the data programmatically. This
document does not cover how to localize your Java code.

Related

How can I include a unicode country flag in a TextView in Android

I want to include country flags in some TextViews in my Android app.
These are being set via setText as follows:
viewBinding.lAe.setText(getString(R.string.flag_ae).concat(" ").concat("UAE"));
flag_ae is defined in my strings.xml currently as follows:
<string name="flag_ae" translatable="false">\u1F1E6\u1F1EA</string>
but my app displays "6 A UAE". What I want is "🇦🇪 UAE".
I have also tried with the string defined as:
<string name="flag_ae" translatable="false">🇦🇪</string>
and also pasting the unicode character from a web page (as pasted into this question) into the string definition as below, but in this case all I get displayed in my app is " UAE".
<string name="flag_ae" translatable="false">🇦🇪</string>
Note that in Android Studio the above displays as the special joined AE character rather than the flag as shown in this question.
Android obviously supports these flag characters somewheer as they display in SMS etc, so why not in my app... am I defining the string incorrectly? Can this be done directly in the Java rather than using a string resource?
I have tried the following directly in the Java (which is a copy and paste of the flag character used in this question, but again I get " UAE" displayed in the app.
viewBinding.lAe.setText("\uD83C\uDDE6\uD83C\uDDEA".concat(" ").concat("UAE"));

How to change this text to string to pass it to strings translation

I asked someone to developp an android app for me, but forgot to tell him to make the translation for me. I found how on google, by creating multiple string file in the values folder and translate almost all the app.
My problem is some text is written in the java folder. I made string for some but for others I can't. I tried using R.string.txt or #string/txt but it's not working.
If you could help with those codes I would apreciate it.
1- in the first code the text I want to add as string is [débit à passer] & [gouttes/min]
final TextView txt = (TextView) dialogView.findViewById(R.id.text_result);
String dose_qunt="Débit à passer " + "="+dose+" "+"gouttes/min";
2- for the second text: [please enter volume] & [please enter time]
public void onClick(View view) {
hideKeyboard(this);
if(view==btn_min){
if(edt_vol.getText().toString().isEmpty() ){
edt_vol.setError("please enter volume");
}
else if(edt_time.getText().toString().isEmpty()){
edt_time.setError("please enter time");
}
Cordialy
What you have here is a bad practice called "hardcoded strings".
Any strings that are shown to the user really should not be written in the Java source code.
That said, to properly correct such a problem, you need some understanding of Java and Android programming.
I can fix your specific examples with some guesswork, but if there are other such strings in your app, they may need a different solution.
It would really be better for you to ask the person who wrote the app to fix this.
That said, here how it should look:
1. Loading a string with parameters:
<string name="dose">"Débit à passer = %d gouttes/min"</string>
Notice %d is a placeholder for a value supplied when the app runs.
In this example the value can only be an integer. If you need different kind of parameter, like a decimal number, there is a list of placeholders here.
And this is how you load it:
int dose = 10; //just an example
final TextView txt = (TextView) dialogView.findViewById(R.id.text_result);
txt.setText(getString(R.string.dose, dose));
The second case is almost identical, except you do not need a parameter:
please enter volume
And the code will look like this:
if(edt_vol.getText().toString().isEmpty() ){
edt_vol.setError(getString(R.string.volume_error));
}
R.string.nameOfString gives the id of the string.
What you need is to call getString and pass the id:
getString(R.string.some_text);
You have to write this strings in values/string.xml in each language string file:
<string name="debit">Débit à passer </string>
<string name="gouttes">gouttes/min</string>
And later you can use them as:
String dose_qunt=getString(R.string.debit) + "="+dose+" "+getString(R.string.gouttes);
(for example)
If it dosen't works, write:
String dose_qunt= getApplicationContext().getString(R.string.debit) + "="+dose+" "+getApplicationContext().(R.string.gouttes);
And simillar for the second texts.

How to change slf4j log into html link

I have java code as:
final URI myUri = new URIBuilder()
.setScheme(azkabanHostProtocol)
.setHost(azkabanHost + ":" + azkabanPort)
.setPath("/executor")
.setParameter("execid", executionID).build();
logger.info(myUri.toString());
I want to display myURI in form of an url/html link into Azkaban's logs so that by clicking on the url it is opened. I am using log4j for logging.
You may create your own Layout class extending HTMLLayout .
Then override the format method to suit your needs.
The actual implementation has the following lines, that you may want to replace :
sbuf.append(Transform.escapeTags(event.getRenderedMessage()));
See that all tags in the message String, will be escaped by default.
Your version could be based on a kind of marker, say String mark = "[LINK]"; for instance
if(event.getRenderedMessage().startsWith(mark)){
String uri = event.getRenderedMessage().substring(mark.length());
String link = "" + uri + "";
sbuf.append(link);
}
else
sbuf.append(Transform.escapeTags(event.getRenderedMessage()));
And you would call the logger this way :
logger.info(mark + myUri.toString());
The following topic will help you use a custom HTMLLayout : how to change htmllayout in log4j2
Here is the source code for the default HTMLLayout, as a starter.
How do you view the Azkaban log files? If they are just raw text files being viewed with a vanilla text editor then there is no way to accomplish what you want. If you are viewing them in a smarter UI then you need to format them according to what that UI requires.
In short, the answer to your question is completely driven by whatever tool you are using to view the logs.

is there a fast way to aplly function to set of variables?

Assume i have lots of variables
String not_id, not_section, not_steet, not_sqTotal, not_sqLiving, not_sqKitchen, not_flat, not_floor, not_floors, not_text, user_phone1, user_phone2, user_contact, not_region, not_district, not_settle, not_price, not_photo, not_date, not_date_till, not_up, not_premium, not_status;
not_id= not_section= not_steet= not_sqTotal= not_sqLiving=
not_sqKitchen= not_flat= not_floor= not_floors= not_text=
user_phone1= user_phone2= user_contact= not_region= not_district=
not_settle= not_price= not_photo= not_date= not_date_till= not_up=
not_premium= not_status=region_title=district_title=settle_title=section_title="";
i need to change their values using someFunction
not_id = someFunction(not_id);
How can i do such action for all variables?
Please, dont propose to use arrays, lists and other sort of collections if it assumes changing variable names to some uniform name.
I van to know if there is such possibility within java itself, eclipse ide or eclipse plugins.
This is going to lead to somewhat unmaintainable code, but you could do it pretty easily with a regular expression search & replace on that second statement, replacing "var_name=" with "var_name = someFunction(var_name);".
Find: ([^=])+=
Replace with: \1 = someFunction(\1);
is someFunction a java method? or it is some simple transformer that is changing from not_([a-z])(\w*) to not[A-Z]\2? If you are only changing variable names use eclipse's excellent refactoring rename bound to Ctrl+Shift+R that can change all occurrences taking to account scope rules

Do resource bundles in Java support runtime string substitution?

Can you do the following with a Java ResourceBundle?
In the properties file...
example.dynamicresource=You currently have {0} accounts.
At runtime...
int accountAcount = 3;
bundle.get("example.dynamicresource",accountCount,param2,...);
To give a result of
"You currently have 3 accounts."
Not without using the MessageFormat class, such as:
String pattern = bundle.getString("example.dynamicresource");
String message = MessageFormat.format(pattern, accountCount);
On their own, ResourceBundle does not support property placeholders. The usual idea is to take the String you get from the bundle, and stick it into a MessageFormat, and then use that to get your parameterized message.
If you're using JSP/JSTL, then you can combine <fmt:message> and <fmt:param> to do this, which uses ResourceBundle and MessageFormat under the covers.
If you happen to be using Spring, then it has the ResourceBundleMessageSource which does something similar, and can be used anywhere in your program. This MessageSource abstraction (combined with MessageSourceAccessor) is much nicer to use than ResourceBundle.
There are various ways, depending on the view technology you're using. If you're using "plain vanilla" Java (e.g. Swing), then use MessageFormat API as answered before. If you're using a webapplication framework (which is true, if I judge your question history here correctly), then the way depends on the view technology and/or MVC framework you're using. If it is for example "plain vanilla" JSP, then you can use JSTL fmt:message for this.
<fmt:message key="example.dynamicresource">
<fmt:param value="${bean.accountCount}">
</fmt:message>
If it is for example JSF, you can use h:outputFormat for this.
<h:outputFormat value="#{bundle['example.dynamicresource']}">
<f:param value="#{bean.accountCount}">
</h:outputFormat>
Best place is to just consult the documentation of the technology/framework you're using (or to tell it here so that we can give better suited and more detailed answers).
Struts have a nice util called MessageResources which does exactly what you ask for....
e.g.
MessageResources resources = getResources(request, "my_resource_bundle"); // Call your bundle exactly like ResourceBundle.getBundle() method
resources.getMessage("example.dynamicresource",accountCount,param2,...);
Limitation
It only allows maximum of 3 parameters (i.e. resource attribute, param1, ..., param3).
I suggest using MessageFormat (if you want to use more than 3 parameter values) as suggested by David Sykes.
PS the getResources method is available only in the Struts Action class.
I don't think you can make this work for Non-English properties file.
My message.properties file has the following line:
info.fomat.log.message.start=Starting to parse log message in {0} format.
And my message_fr_FR.properties file has the following line:
info.fomat.log.message.start=A partir d'analyser le message connecter {0} format.
This code works only for the English one
String.format((String) messages .getString(GlobalConstants.MESSAGE_FORMAT_START), GlobalConstants.STR_JSON));
It does NOT replace the placeholder with the value when my language / locale is French :-(
Even MessageFormat.fomat() is no good
I don't believe ResourceBundle can do that itself, but String can:
String.format(bundle.getString("example.dynamicresource"), accountCount);
Remember that when using MessageFormat.format() you need to use a double quote ('') in your resource bundle if you want to express single quote (').
MessageFormoat#format will work for the case like:
greetingTo=Have Param, saying hello {0}
You can declare two methods like this where RB is a instance of ResourceBundle:
/**This is a method that takes the param to substitute the placeholder**/
public String getString(String key, Object... params ) {
try {
return MessageFormat.format(this.RB.getString(key), params);
} catch (MissingResourceException e) {
return "[" + key + "]";
}
}
/**Without a param, this will derectly delegate to ResourceBundle#getString**/
public String getString(String key) {
try {
return this.RB.getString(key);
} catch (MissingResourceException e) {
return "[" + key + "]";
}
}

Categories

Resources