How do you access the values in the res/values/string.xml resource file from the Android Activity class?
Well you can get String using,
getString(R.string.app_name);
And, you can get string-array using
String arr[] = getResources().getStringArray(R.array.planet);
for (int i = 0; i < arr.length; i++) {
Toast.makeText(getBaseContext(),arr[i], Toast.LENGTH_LONG).show();
}
strings.xml:
<string name="some_text">Some Text</string>
Activity:
getString(R.string.some_text);
Put this code in res/values/string.xml
<string-array name="planet">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
<item>Mars</item>
</string-array>
This code to be placed in res/layout/main.xml and remove default widgets present in main.xml.
<ListView android:id="#+id/planet"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:entries="#array/planet"/>
</LinearLayout>
If getString(R.string.app_name); isn't working for you, you can pass context like this:
context.getString(R.string.app_name);
If you have the context of Activity, go with:
getString(R.string.app_name);
If you don't have the context, try below, you can get the context from activity using Constructor.
mContext.getString(R.string.app_name);
Related
I would like to check programmatically whether an sd card is installed, and if yes, give the user the choice to switch between external and internal storage.
I have my other static settings organized inside a preferences.xml.
It seems that I have to rewrite all the settings of the xml file in code if I start to work with preferences more dynamically.
Or is there an option to enhance the preferences from the xml with preferences from code which get used just once needed?
Thanks
Add this to manifest for install app on sd card if is possible:
android:installLocation="preferExternal">
To verify is sd card writable and readable use this method:
private boolean isExternalStorageWritable() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);}
To get folder of appfiles on sdCard (externalStorageVolumes[0] is primary folder):
File[] externalStorageVolumes =
ContextCompat.getExternalFilesDirs(getApplicationContext(), null);
Oficial documentation
I found out myself, it looks a bit clumsy, but it works.
Once again: My problem is that I have certain setting options pre configured in an xml file as described here:
Preferences with XML
Here is my preferences.xml:
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory app:title="#string/download_header">
<SwitchPreferenceCompat
app:key="dl_background"
app:title="#string/background_behaviour"
app:defaultValue="false"/>
<ListPreference
app:title="#string/dl_qual"
app:defaultValue="#string/low_qual"
app:key="dl_qual"
app:entries="#array/dl_qual_arry"
app:entryValues="#array/dl_qual_arry"/>
</PreferenceCategory>
<PreferenceCategory app:title="#string/tc_header">
<SwitchPreferenceCompat
app:key="tc_installed"
app:title="#string/tc_behaviour"
app:defaultValue="false"/>
<ListPreference
app:title="#string/dl_dir_root"
app:key="dl_dir_root"/>
</PreferenceCategory>
</PreferenceScreen>
Here you can define arrays which map to ListPrefrence objects.
Each option list is then populated from a resource xml file holding the actual list entries.
I used this approach for the first ListPreference "dl_qual" above.
This is the resource.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="dl_qual_arry">
<item>Higher quality (128kbps)</item>
<item>Lower quality (64kbps)</item>
</string-array>
</resources>
But then I had the idea to insert a ListPreference where the values of the options list are only known at runtime.
This is my second ListPreference above "dl_dir_root".
I was too lazy to rewrite (and read how to do it in advance) the complete settings activity from code.
So I ended up with this SettingsFragment inside my SettingsActivity:
public static class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
//First, lets check whether we have initialized preferences already
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
String selectedDir = prefs.getString("dl_dir_root", "INIT");
setPreferencesFromResource(R.xml.root_preferences, rootKey);
PreferenceScreen root = getPreferenceScreen();
ListPreference dlDirRoot = root.findPreference("dl_dir_root");
CharSequence[] arryValues = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
CharSequence[] arryEntrys = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
dlDirRoot.setEntries(arryEntrys);
dlDirRoot.setEntryValues(arryValues);
if(selectedDir.equals("INIT")) {
//Initialize value/index
dlDirRoot.setDefaultValue(arryValues[0]);
dlDirRoot.setValueIndex(0);
}
else{
//Position at already selected value/index
dlDirRoot.setDefaultValue(selectedDir);
dlDirRoot.setValue(selectedDir);
dlDirRoot.setValueIndex(dlDirRoot.findIndexOfValue(selectedDir));
}
}
}
The pre defined xml is applied first, then the ListPreference object for "dl_dir_root" is acessed and the options are added:
ListPreference dlDirRoot = root.findPreference("dl_dir_root");
CharSequence[] arryValues = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
CharSequence[] arryEntrys = BBCWorldServiceDownloaderUtils.getStoragePaths(getContext());
dlDirRoot.setEntries(arryEntrys);
dlDirRoot.setEntryValues(arryValues);
The rest is checking/keeping state between the calls to the activity.
If anyone knows of a more elegant way, I would be curious.
Best
Matthias
I'm working on a project where I've defined several strings to use on my project.
I want to use a string to be displayed as my subtitle of the page on the toolbar. The reason I'm using strings is because I want my app to be translation supported.
Here is how I use subtitles on the toolbar of my activity:
android.support.v7.app.ActionBar ab = getSupportActionBar();
ab.setTitle("Title");
ab.setSubtitle("Subtitle");
I want to use a string on java (like #string/helloworld in xml) but I don't know how can I do that.
Can anyone help me?
In your "res" directory, there might be "strings.xml" file. (If you didn't remove it). Add string tags like bellow code snippets.
<string name="title">Title Message</string>
<string name="sub_title">Sub Title Message</string>
And in your java file.
String mStringTitle = getString(R.string.title);
String mStringSubTitle = getString(R.string.sub_title);
You can also use these string resources in your layout XML like follows.
<TextView
android:text="#string/title" />
For more information, please refer to the bellow URLs.
What is the string resource in Android? android_string_resources
How to support multiple locales?
support_different_language //
different-locales
In this case, use R.string.helloworld, because these methods require a resource ID.
This is the code -
R.string.message_failure
Implementation of the above code -
snackbar = Snackbar.make(constraintLayout,R.string.message_failure, Snackbar.LENGTH_SHORT)
//String_file.xml code -
<string name="message_failure">Failure</string>
Im using 2 different xml Files to store data i need. When starting the App i want to read those 2 resources and generate Objects from it.
Let me explain, what it is i'm doing:
The first resource stores event-names like this: /res/values/event_names.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="event_a">AAAA</string>
<string name="event_b">BBBB</string>
<string name="event_c">CCCC</string>
<string name="event_d">DDDD</string>
</resources>
The seconds resource stores the times, that given events kick off: /res/values/event_times.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="event_a">
<item>02:00</item>
<item>11:30</item>
<item>17:00</item>
</string-array>
<string-array name="event_b">
<item>03:00</item>
<item>12:30</item>
<item>18:00</item>
</string-array>
<string-array name="event_c">
<item>04:00</item>
<item>13:30</item>
<item>19:00</item>
</string-array>
<string-array name="event_d">
<item>04:30</item>
<item>10:00</item>
<item>15:00</item>
<item>20:00</item>
</string-array>
</resources>
Note, that event names and times have their name in commom. On startup the App will read the event-names first and then find out their correspondent timestamps.
Can i do it the way i planned this out? I'd have to read all the identifiers from the name-resource and then by that identifier get the times.
Why don't you add all the event names as the first element in your <string-array>. This way your event names will be tightly coupled to their respective times.
Quick idea:
You can probably save all your information on a file with JSON format in the asset folder as #amalBit suggested in a comment.
Then you don't have to make the parsing since Android comes with a JSON library, and you won't be needing to parse any txt with a custom format.
Or in an uglier way (and I am not writing this hehe), you can just put a JSON directly in your strings.xml in one entry alone. That would save you from reading the asset manually. But I wouldn't do this, because strings.xml has another meaning (which is to store strings you want to translate hehe)
If you want I can post you some code of the first case later.
<!-- ================= -->
<!-- Event Mappings -->
<!-- ================= -->
<eat-comment />
<array name="event_lists">
<item>#array/event_a</item>
<item>#array/event_b</item>
<item>#array/event_c</item>
</array>
<!-- =========== -->
<!-- Event Lists -->
<!-- =========== -->
<eat-comment />
<string-array name="event_a">
<item>Event A</item>
<item>02:00</item>
<item>11:30</item>
<item>17:00</item>
</string-array>
<string-array name="event_b">
<item>Event B</item>
<item>03:00</item>
<item>12:30</item>
<item>18:00</item>
</string-array>
<string-array name="event_c">
<item>Event C</item>
<item>04:00</item>
<item>13:30</item>
<item>19:00</item>
</string-array>
Code:
List<Event> events = new ArrayList<Event>(); // putting all events into a list
TypedArray eventMappings = getResources().obtainTypedArray(R.array.event_lists);
for (int mappingVar = 0; mappingVar < eventMappings.length(); mappingVar++) {
int eventId = eventMappings.getResourceId(mappingVar, 0);
String[] eventInfos = getResources().getStringArray(eventId);
Event event = new Event(); // your event domain class or whatever info holding class
for (int infosVar = 0; infosVar < eventInfos.length; infosVar++) {
switch (j) {
case 0:
event.setName(eventInfos[infosVar]);
break;
default:
event.addTime(eventInfos[infosVar]);
break;
}
events.add(event);
}
}
eventMappings.recycle(); // important
Hope that helps :-)
Could someone maybe tell me what i'm doing wrong? I'm betting im missing one small thing. I've looked on the developer site and i've read some tutorials and i'm just not seeing what i did wrong.
I'm trying to use a ListPreference to decide which sound to play on a button click.
I have this at the top:
public String greensound;
Here's my OnClick code:
case R.id.green:
SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(this);
greensound = prefs.getString("greensound", "gsone");
if (greensound == "gsone") {
mSoundManager.playSound(1);
} else if (greensound == "gstwo") {
mSoundManager.playSound(2);
} else if (greensound == "gsthree") {
mSoundManager.playSound(3);
}
break;
Here's my xml:
<ListPreference
android:title="Geen Button"
android:key="greensound"
android:summary="Select sound for the Green Button"
android:entries="#array/green_list"
android:entryValues="#array/green_list_values"
android:defaultValue="gsone">
</ListPreference>
here's my Settings.java:
package com.my.app;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Settings extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
and here's my array's if that will help at all:
//This is the one I want to display to the user
<string-array name="green_list">
<item>Sound One</item>
<item>Sound Two</item>
<item>Sound Three</item>
<item>Sound Four</item>
<item>Sound Five</item>
</string-array>
<string-array name="green_list_values">
<item>gsone</item>
<item>gstwo</item>
<item>gsthree</item>
<item>gsfour</item>
<item>gsfive</item>
</string-array>
edit: added a logcat that kinda looked possibly related.
08-27 01:52:07.738: WARN/Resources(6846): Converting to string: TypedValue{t=0x12/d=0x0 a=2 r=0x7f090000}
08-27 01:52:07.748: WARN/Resources(6846): Converting to string: TypedValue{t=0x12/d=0x0 a=2 r=0x7f090000}
08-27 01:52:07.758: WARN/Resources(6846): Converting to string: TypedValue{t=0x12/d=0x0 a=2 r=0x7f090000}
DDMS > File Explorer > Data > Data > packageName > SharedPreferences
This is what was in there:
com.my.app_preferences.xml:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="redsound">rsone</string>
<string name="greensound">gsone</string>
</map>
_has_set_default_values.xml:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="_has_set_default_values" value="true" />
</map>
This all really confuses me more because...It looks like greedsound does infact = gsone
so.... I don't understand whats wrong its not even playing the default sound. and yes i've tested
mSoundManager.playSound(1);
mSoundManager.playSound(2);
mSoundManager.playSound(3);
all without the other code and they work great. I'm not sure what's work
greensound.equals("gsone")
I had a similar problem. I changed my '==' comparisons to string.contentsEquals() and things started working. I eventually ended up putting the keys and values into HashMaps.
The only issue I can think of is that your preferences are not getting set before you are running your playSound code. To ensure the settings are loaded include the following code in your onCreate():
/* Loading default preferences the first time application is run */
PreferenceManager.setDefaultValues(getApplicationContext(),
R.xml.filename, false);
Also, check through the DDMS > File Explorer > Data > Data > packageName > SharedPreferences that your preferences are getting set.
When you are using Preference Activity and creating it from xml resource. It automatically creates a SharedPreference file: packageName_preferences (eg. com.my_company.my_app_preferences). Thus to access this you need to use the following code:
SharedPreferences prefs = getSharedPreferences("com.my.app_preferences", MODE_PRIVATE);
And finally remove the following line in the xml:
android:defaultValue="gsone"
Hope this helps.
Just a quickie,
i have an xml resource in res/values/integers.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer-array name="UserBases">
<item>2</item>
<item>8</item>
<item>10</item>
<item>16</item>
</integer-array>
</resources>
and ive tried several things to access it:
int[] bases = R.array.UserBases;
this just returns and int reference to UserBases not the array itself
int[] bases = Resources.getSystem().getIntArray(R.array.UserBases);
and this throws an exception back at me telling me the int reference R.array.UserBases points to nothing
what is the best way to access this array, push it into a nice base-type int[] and then possibly push any modifications back into the xml resource.
I've checked the android documentation but I haven't found anything terribly fruitful.
You need to use Resources to get the int array; however you're using the system resources, which only includes the standard Android resources (e.g., those accessible via android.R.array.*). To get your own resources, you need to access the Resources via one of your Contexts.
For example, all Activities are Contexts, so in an Activity you can do this:
Resources r = getResources();
int[] bases = r.getIntArray(R.array.UserBases);
This is why it's often useful to pass around Context; you'll need it to get a hold of your application's Resources.
get an array from xml resources of android project can be accessed.
from array.xml
<string-array name="weather_values">
<item>sunny</item>
<item>cloudy</item>
<item>rainy</item>
</string-array>
in Activity
String[] stringsArray = getApplicationContext().getResources().getStringArray(R.array.weather_values);
in Fragment
String[] stringsArray = getContext().getResources().getStringArray(R.array.weather_values);
for output in log
System.out.println("Array Values " + Arrays.toString(stringsArray));
output is
I/System.out: Array Values [sunny, cloudy, rainy]