How to call resources with string name in android? - android

I'm now trying to call the resources( in my application they are mp3 files and images).
For the mp3 file part, my code goes like this ( not working obviously!)
if(i==1)
{
hoho= MediaPlayer.create(getApplicationContext(), R.raw.univ_day1);
hoho.start();
}
else if (i==2)
{
hoho= MediaPlayer.create(getApplicationContext(), R.raw.univ_day2);
hoho.start();
}
...
In my application, there are hundreds of mp3 file inside the application. So what I want to do is briefly summarize code into something like this.
hoho=MediaPlayer.crate(getApplicationContet(), R.raw.univ_day+"i"); //This also looks really awkward.
If I knew how to write down code just like above one. How can I handle the name of raw files and the form like "R.raw...."? If I can do, then I also can apply similar approach to the image resources.

You can get resource id by its name using public int getIdentifier (String name, String defType, String defPackage) method.
For example:
int id = getResources().getIdentifier("univ_day"+i, "raw", getPackageName());
hoho = MediaPlayer.create(getApplicationContext(), id);

We can list all the names of raw assets, which are basically the filenames without the extensions, we can do this as -
public void listRaw(){
Field[] fields=R.raw.class.getFields();
for(int count=0; count < fields.length; count++){
Log.i("Raw Asset: ", fields[count].getName());
}
}
Next you'll need to refer to them by the integer assigned to that resource name. You can get this integer as:
int resourceID=fields[count].getInt(fields[count]);
This is the same int which you'd get by referring to R.raw.yourRawFileName.
In your code you can use this like -
hoho= MediaPlayer.create(getApplicationContext(), resourceID);
hoho.start();
Next you can apply JAVA logic to play previous current and next media files. Please let know if you need help here also.

Related

How to sort image names with digits like 1,2,3,4..., not 10,11,12,13 in "drawable" folder?

There are some images in my "drawable" folder and I want to know how to sort like cat__1_, cat__2_..., but don't start from cat__10_, cat__11_.... Any ideas?
You can't have it as of now, as natural sorting is simply not supported in AS' view - it just sorts alphabetically. The only workaround is to rename your assets and use fixed number of digits to achieve desired order. Something like this:
cat_01_
cat_02_
...
cat_11_
...
If you got more than 99 elements of given "sequence" then use three digits instead of two etc.
This would also help you :
for(int i=1; i<=99;i++){
int drawableImageId = context.getResources().getIdentifier("cat__"+i+"_", "drawable", context.getPackageName());
imageView.setImageResource(drawableImageId);
}
or
public int getCatImage(int pos) {
int drawableImageId = context.getResources().getIdentifier("cat__" + pos + "_", "drawable", context.getPackageName());
return drawableImageId;
}
You can easily sort your list with a custom sort.
Have a look at Collections.sort().

Creating resource reference ints programmatically

I am building a quiz app with questions in a string resource, as well as an answer. They are formatted by numbers like so:
<string name="ques1">What color is the sky?</string>
<string name="ques2">What sound does a cow make?</string>
The answers are also strings corresponding to the same number as the questions:
<string name="ans1">Blue</string>
<string name="ans2">Moo</string>
I have created a QA class for holding both a question and the answer, as well as the user's response from an EditText. At the "loading" of my app these classes are created and filled by reading from the strings resource.
I can programmatically enter these no problem, it is a lot of copy pasting but it will get the job done:
QA.setQuestion(getString(R.string.ques1));
QA.setAnswer(getString(R.string.ans1));
quizList.add(QA);
QA.setQuestion(getString(R.string.ques2));
QA.setAnswer(getString(R.string.ans2));
quizList.add(QA);
etc...
The problem is that I want to be able to add questions and answers to the xml at any time without having to add yet another repetition of the above method. What I want to do is essentially this:
String refBase = "R.string."
String ans = "ans";
String ques = "ques";
int numOfQues = 25; //only change when questions are added or removed
for (int i = 0; i < numOfQues; i++)
{
String referenceQ = refBase + ques + i;
String referenceA = refBase + ans + i;
QA.setQuestion(getString(referenceQ));
QA.setAnswer(getString(referenceA));
quizList.add(QA);
}
I cannot cast a string to an int like this obviously, but I am wondering if there is a way to implement a reference "builder", where I don't have to repeat many lines of code just to read another string with the same name but incremented number.
I understand that I can also just create an array.xml with one for questions and one for answers, making sure their position in each array corresponds. This would be easiest I think, but I guess I am wondering if it is possible to create references to string values through the code like my example?
You can use this method to get the question or answer String by its resource name:
String getQAString(boolean isQuestion, int index) {
String prefix = isQuestion? "ques" : "ans";
int resId = getResources().getIdentifier(prefix + index, "string", getPackageName());
return resId != 0? getString(resId) : "";
}
The loop to add questions and answers (assume they start from 1 and end at 25):
int numOfQues = 25;
for (int i = 1; i <= numOfQues; i++) {
String referenceQ = getQAString(true, i);
String referenceA = getQAString(false, i);
QA.setQuestion(referenceQ);
QA.setAnswer(referenceA);
quizList.add(QA);
}

Drawable Reference

I have few images in my app ( they are all copied into res/drawable and have appropriate R.drawable reference) that I want to assign them to my ImageViews using contents of an string type variable. To illustrated, I have an image file named "c4.png" in my drawable folder and an string variable (card) that contains "c4". I want to see if there is any way I can use a code like this (ImageView1.setImageResource(R.drawable.card)) to assign image c4 to my ImageView1 instead of using ImageView1.setImageResource(R.drawable.c4). Basically, I am wondering if it is possible to replace a variable with the specific image name in the R.drawable.resourceName. I know that R.drawable.resourceName is an integer and I am not trying to change its type. I want to replace the resourceName with a variable. I appreciate any help
Use this to draw a random number in particular range-
int min = 0;
int max = 9;
Random r = new Random();
int i1 = r.nextInt(max - min + 1) + min;
Then using this number pick image from image array-
public Integer[] nImages = {
R.drawable.c1, R.drawable.c2,
R.drawable.c3, R.drawable.c4,
R.drawable.c5, R.drawable.c6,
R.drawable.c7, R.drawable.c8,
R.drawable.c9, R.drawable.c10
};
ImageView1.setBackgroundResource(nImages [i1]);
Hope this works.
Try this
Resources res = getResources();
int id = res.getIdentifier(card, "drawable", getPackageName());
img.setImageResource(id);
this may solve your problem.
Or you can put the images in the asset folder. Assets are referenced by their filename, as in
getAssets().open(<filename>);
This returns an InputStream. Afterwhich it is trivial to convert them to a Bitmap resource
BitmapFactory.decodeStream(inputStream);
And then use that bitmap for your ImageView. That should be straightforward with
imageView.setImageBitmap(bitmap);
I want to replace the resourceName with a variable.
Instead of declaring the variable card as a string declare it as an Integer. So that you can use it like the following.
int card=R.drawable.c4;
ImageView1.setImageResource(card);
You probably can not do something like R.drawable.card because the R file is generated according to the resources in the drawable folder.
hope this helps

Play a random sound on a button click

I wonder if you could help. Im trying to play a random sound (from a set of 7 available sounds) when a user clicks on a button. So far I have:
Random rand = new Random();
int rndm = rand.nextInt(6) + 1; // I have 7 random sounds to play sequentially named 'my sound' + n.
String sndName = "mysound" + rndm; // Assign a random # to the end of the sound file.
mp1 = MediaPlayer.create(getApplicationContext(), R.raw.sndName); // ERROR HERE: Expects an Int
mp1.start();
My hope was that one of my sound files (mysound1, mysound2, mysound3,...) would play randomly but eclipse complains that the mp1 assignment is expecting an int. Any ideas?
Thanks much.
Use
int[] sounds={R.raw.mysound1, R.raw.mysound2, R.raw.mysound3,R.raw.mysound4,R.raw.mysound5,R.raw.mysound6,R.raw.mysound7};
Then
Random r = new Random();
int Low = 0;
int High = 7;
int rndm = r.nextInt(High-Low) + Low;
mp1 = MediaPlayer.create(getApplicationContext(),sounds[rndm]);
mp1.start();
The issue is that you need to get the resource id to pass in. You'll need to use something like this.
int id = getResources().getIdentifier("mysound" + rndm, "raw", getApplicationInfo().packageName);
mp1 = MediaPlayer.create(getApplicationContext(), id);
Two things. First I recommend you look at the line above where you create the string. If I remember correctly you may need to use a function such as to String to get the integer to be a string to concatenate on your string.
Next, I don't believe the r.raw is going to work like that.
My recommendation is if you have only 7 items, make an array holding the resources.
int [] resources = {R.raw.mysound1, R.raw.mysound2} etc
Then use the index from before to select the right R file.
So in the media create line, replace R.raw.sndName with resources[rndm]
your program using variable error. see below code:
// 1. R.raw.sndName is Constant
mp1 = MediaPlayer.create(getApplicationContext(), R.raw.sndName);
// 2. android resource must integer, Starting from this idea

Using a Random Number in a Drawable Path

I am using a random number to set my imageButton to a random image. I am wondering if there is a way to use the random int in the file path for the drawable. This code gives a run time error for invalid integer but will compile.
Random generator = new Random();
int chooseFirstPicture = generator.nextInt(2);
int imagePath1 = Integer.parseInt("R.drawable.image" + chooseFirstPicture);
btn1.setBackgroundResource(imagePath1);
You are parsing a String to a Integer, so your code is going to throw a NumberFormatException every time you run it.
The correct way to get a resource id from a String key is using the function getIdentifier():
Random generator = new Random();
int chooseFirstPicture = generator.nextInt(2);
int resourceId = getResources().getIdentifier("image" + chooseFirstPicture, "drawable", getPackageName());
if (resourceId != 0) {
//Provided resource id exists in "drawable" folder
btn1.setBackgroundResource(imagePath1);
} else {
//Provided resource id is not in "drawable" folder.
//You can set a default image or keep the previous one.
}
You can find more information in the Android Resources class documentation.
Hm.. You trying to convert "R.drawable.image1" string to an integer that is impossible. During compilation nothing checks what's in the string, but when you run the app, it fails immediately.
Better to use the getResources().getIdentifier() with proper parameters (link)
I hope it helps :)

Categories

Resources