In my app i want to be able to store resource id of some icons in database. I suppose it is not save to do, cause in the later stages (application upgrades) i may want to add new icons to the app, so all id's may change? What is the best practice to store resource in case i do not want to store icons as blobs?
As an example, let's say i have a game 1.0, where i let user to choose an avatar for his character from a list of avatars. I want to store this avatars id in DB and be sure that if i add more avatars in game 1.1 - user will still see his choice.
The best way (in my opinion) is to store the resource entry name.
String iconName = getResources().getResourceEntryName(R.drawable.your_icon);
So your SQLite database column where you want to store the icon will have type TEXT. You're right that storing resource IDs is a bad practice because they're recreated when you compile the app, so you can't rely on them not changing (I learned this the hard way, all my app's icons got messed up).
To get the resource ID from the String when you need it, call
int resID = getResources().getIdentifier(iconName, "drawable", getPackageName());
Note that both getResources() and getPackageName() are methods from Context, so you need to have reference to your application/activity Context to be able to call these methods.
Related
I have a question. I know I can store an image as byte array in SQLite database. But this needs some extra CPU work, so I tried to store only the id (R.drawable.myImage).
I stored it as an integer and I can retrieve it back. I am setting my image into imageview like this:
ivSportIcon.setImageResource(getItem(i).getIcon());
But I get an error:
Resources$NotFoundException: Resource ID #0x8
Is this a wrong way? Should I store my image as a byte array? Thank you in advance!
I do not know how you are storing the resource ID, but 0x8 is not a resource ID.
Beyond that, bear in mind that resource IDs change with each build, and so the resource ID that you save today will be different tomorrow.
Instead, store some other identifier in the database, that you can use to decide which of your drawables to use.
The only reason to store the actual image data in the database would be if you plan to change the images in the future and you want the user to be able to use the old images that happen to be associated with database entries.
You could store the name of the Drawable as a String instead, and use this method to retrieve its id:
public static int getResourceIdForName(Context context, String drawableName) {
final Resources res = context.getResources();
final String packageName = context.getPackageName();
return res.getIdentifier(drawableName , "drawable", packageName);
}
This is a little inflexible however, as if you decide to change the name of your drawable in future, then you will also need to change the name in the database.
I have number of drawables to select in a View. When the user selects one of the drawable and on next time when the app is launch , I have to show only the selected drawable.
Is it good to store the Resource ID in shared preference and retrieve the selected drawable using Resource ID next time when the app is launched.?
All the R class related ids are generated at compile time so they won't change at runtime. There's nothing stopping you from storing this IDs in SharedPreferences, however, there's no gain whatsoever. It's almost always faster just to reference the R.drawable.x related id.
I know this is an older question, but I'd advise AGAINST storing the values in SharedPreferences.
When you release a newer version of the app, it's re-compiled. There is no guarantee, that the old value of let's say R.drawable.ic_example has the same value when drawables have been added/removed to the updated application. Therefore the stored value could no longer match with the Drawable asset you expect.
I have 100 images in my application of different cities and I want to divide these pictures in different groups, lets say in evening, morning, sunny, raining etc…
We know that when we call an image from layout folder by calling R.layout.image_1, android generates integer number for each image
For example:
R.layout.image_1 (223344), R.layout.image_2 (556677),
R.layout.image_3 (778899),
I can create one table having evening, morning fields and I can assign group of pictures to each of them with integer IDs which are (223344,556677) and I can call evening or morning group and i can display all images related to these group.
My question is: Does Android generate same number every time. Are these numbers are fixed? When ever the application runs.
If its true then upper idea will work for me. If this idea is incorrect then kindly guide me what is the decent approach to handle hundreds of PNGs in application.
Those numbers are not fixed. R will be regenerated and can have completely different numbers if you change something. That is why when comparing ids, you compare by the name instead.
Eg instead of
if (i == 223344)
do
if (i == R.layout.image_1)
Since R.layout.image_1 references the integer id, the name won't change (unless you change the layout xml name.
If you want to get a resource id dynamically (by a string representing the name), you should have a look at this method - Resources#getIdentifier().
First of all we generally put images in the drawable folder.
Does Android generate same number every time?
No.
Are these numbers fixed whenever the application runs?
Yes.
In fact, once your project is built, the ids will remain the same for that same build.
In other words for a certain generated APK file, the ids won't change.
So how can you take advantage of that to group your resources?
You could have a static int array that holds the ids:
public static final int[] IMAGES_MORNING = {R.drawable.morning0, R.drawable.morning1, etc};
public static final int[] IMAGES_EVENING = {R.drawable.evening0, R.drawable.evening1, etc};
Although a more structured method would be to store them in a database on your app's first launch.
Or you could use what A--C suggests:
For example to get all the ids of morning images
for(int i = 0; i < numberOfMorningImages ; i++){
int id = getResources().getIdentifier("morning" + i, "drawable", getPackageName());
// do something with the id
}
No, there's no guarantee that integers will be the same every time, so the solution you've described won't work. Unfortunately, there's no proper way to group drawables inside the res/drawable folder. As a workaround, you can store them inside the assets folder, where you can group them as you like. However, Android won't be able to handle different resolutions this way. The choice is up to you. Hope this helps.
This is the problem:
I have a form for inputting names, then saves it, then displays it in another activity. But once I try to enter another name, the previous name is overwritten by the new name.
Is there a way to set these names up to list themselves one after another without overwriting each other in SharedPreferences?
You can as long as they have distinct names. Ig you need multiple values for same name, you can store JSON array or use some form of prefix / suffix solution to provide unique names
Either do it like Konstantin Pribluda suggested, or you might think of using the SQLite, if you have a lot of names you want to store (e.g. if creating a history of typed in names). That way you can store unlimited values for the same key and retrieve them as a list/cursor.
But of course that's overkill if you only have 2-3 names…
you can also save a Set of Strings in the SharedPreferences.
i am currently trying change a imageView in my program, it needs to changed based what the user picks from the screen before, so i was wondering how i can access an image in my drawable folder through a string path?
all the examples i have seen have been either hard coded (R.drawable.XXX) or asking for the integer id value
Cheers
Make a HashMap using your string as a key and ID as a value.