I'm currently using shared prefs in android to save some of my settings. This works well, but I came across a little problem with R.
In my shared prefs I'm also saving some image resource IDs so I can acces them later (after the app was destroyed) on a new app start.
Now apparently once I add new resources to my resource tree and build the app again (aka update) the IDs change and I'm accessing a different resource with the ID that I saved before.
Do you have an idea/approach how to save the image resource IDs (or any other identifier) without loosing the link to them?
Thank you very much in advance.
R values will change frequently and are not meant to be stable.
The best solution is for you to be saving something in SharedPreferences that has actual business meaning in your app, then map those values to drawables and other items that you might use for rendering that information. That way, if you decide that you need to refactor and rename those drawables, you don't break your data storage.
If you wish to be lazy or otherwise are willing to stipulate that you can never change the drawable names, you could use something like getResourceEntryName() on a Resources object (you can get one of these via getResources(), called on any Context), to find the name of a resource given its ID, and persist the name. You can then use getIdentifier() on a Resources object to look up the corresponding R.drawable value later on.
You can save your resource name in shared prefs and retrieve the Drawable by :
Drawable drawable = getResources().getDrawable(getResources().getIdentifier(yourDrawableName, "drawable", getPackageName()));
Related
Some information about the app:
The app contains a lots of images in drawable folder.
The size of every image is between 1kb and 3kb.
And I need to draw them into a ListView.
What I need to get:
I need store the identifier of the image (R.drawable.my_image) into database with some aditional user information.
The problem:
When I update the app (adding new image resources), the identifier may change. So, in database I will have an outdated identifier, which is linking to a non-existing resource.
I've thought to store the resource name in database instead of the resource identifier and them I will retrieve it by getResources().getIdentifier(String, String, String) method. But I don't know if this method is efficient enough to use it in a ListView.
The documentation says Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.
Do you know any other solution?
Finally Im using getResources().getIdentifier() method to load images into list (with recyclerview). My list has about 20 images. The average size is also less than 3kb. I've tried the app in older devices (wich behavior can be affected by his CPU) and it worked fine. I know this method is not recomended, but can be a solution.
Not efficient to use it in a list view.
Official documentation of Resources.getIdentifier method:
Return a resource identifier for the given resource name. A fully qualified resource name is of the form "package:type/entry". The first two components (package and type) are optional if defType and defPackage, respectively, are specified here.
NOTE in documentation
Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.
Does anyone know if it is possible to make Android not generate new ID's for resources that is added to raw, drawable and other resource-folders?
The problem is that if I for example add an image with the name 3.jpg, and later on adds another image called 2.jpg the ID for image 3.jpg gets changed.
I need to keep the ID's static as the ID's are defined in XML files and used in the app to get the resources based on the ID.
I may have done something wrong when I tested it so it may be that the ID does not get changed, but as far as I can remember ID got changed when adding new resources.
Thanks for any help.
As far as i know, R.java is autogenerated and all resource ID's are internally allocated by eclipse. Technically your code should not depend on the ID's generated. So even if ID's keep changing, it is absolutely fine. If you are depending on the generated ID's in your code, you will keep running into problems.
I need to store the link to the image, which user has chosen. The sources of the images are files, contact icons and resources' drawables (I need drawables since I provide different images for different resolutions/densities).
For the purpose of unification I store it in URI, and consequently this URI may be pointing to a file (file://), to content provider or to resource (android.resource://...). Here is how the URI pointing to drawable with id=2130837534 looks like:
android.resource://my.packagename/2130837534
It works fine unless the ids in R.java are regenerated. So, is there any way to prevent SDK from changing some of the R.java ids values?
No you can't, and shouldn't. If you can describe your problem clearly, there might be some other solution.
Save your resource names in a file, in this way.
icon_profile_1
icon_profile_2
And then when you need the resource ID, do this.
int resID = getResources().getIdentifier("icon_profile_1", "drawable","your_package_name");
Check here(java.lang.String, java.lang.String, java.lang.String)
As R.java is auto-generated it can't be restricted from it's operation, because it will agin be auto-generated when your project is cleaned or compiled.
This is impossible In android because R.java is Autogenrated and you cant do anything for that.
I just curious. There are 3 method:
1. getPreferenceManager().setSharedPreferencesName(String PrefName);
2. PreferenceManager.getDefaultSharedPreferences(Context context)
3. Context.getSharedPreferences (String name, int mode)
As I know, the third method is only used when the first method is used, right?
But with 3 method we also use addPreferencesFromResource(int resID);
so, what is the difference? When can we use one of these method?
Thanks!
Let's go one step at a time:
setSharedPreferencesName() is method that allows to set the name of the preference group for later use. This is helpful for example when using the helper class of
PreferencesActivity before loading a preferences from XML resource file by calling addPreferencesFromResource(). It is therefore not as common as the other 2 methods you mentioned above.
getDefaultSharedPreferences() uses a default name, usually stored as /data/data/com.package.name/shared_prefs/com.package.name_preferences.xml.
It is commonly used. Note that this default is set per application.
The alternative method - getSharedPreferences() requires to indicate a specific preference (file) name and an operation mode.
As appears also in another answer about shared preferences,
getDefaultSharedPreferences() in fact uses Context.getSharedPreferences, so the result is the same, but without the flexbility to split to multiple preference files, that is offered by getSharedPreferences(). Sharing the preferences between apps using
a MODE_WORLD_READABLE operation indicator is also something possible using getSharedPreferences(), but is rarely used.
IMHO, getDefaultSharedPreferences() can be safely used without going into the confusion of multiple preference file names that are prone to typos and confusion.
If someone knows of a good reason to use getSharedPreferences() and not getDefaultSharedPreferences(), please let me know by commenting here.
getDefaultSharedPreferences() uses a default preference-file name like "com.example.something_preferences". This default is set per application, so all activities in the same app context can access it easily as in the following example:
SharedPreferences spref = PreferenceManager.getDefaultSharedPreferences(this);
if (spref.contains("email")) {
String sEmailAddr = spref.getString("email", "");
}
The preferences are usually stored at /data/data/com.package.name/shared_prefs/com.package.name_preferences.xml
getSharedPreference is the best way because using getDefaultSharedPreferences has some flaws
Actualy getDefaultSharedPreferences doesn't work correct on some
devices when build with targer api 13
Starting app from shortcut and from menu gives me different
DefaultSharedPreferences. After removing DefaultSharedPreferences
from my code - it works perfect. I can't just say: people dont make
shrotcuts, so I had to change code
This link may also help
I have recently started developing a game in android, never used it before and was wondering if there is a simple way of getting a set of images loaded into the application. As my current implementation involves basically
Creating an int[] array,
Storing the values of each drawable into this array, (now this has to be hand coded, so if I add any more images it has to be added programmitically)
Then itterating through each item in the array and calling BitmapFactory to get the resource.
(Unfortunately I don't have the code with me as it is at home and I am at work, but that is the jist)
So 2 questions, is there a way of getting the drawables without having to put in each item manually to the int[] - ie looking for perhaps a file name prefix and then only loading the resource with the prefix?
Which leads me to my second question because I more than just these images in my drawable resource directory, is there a way to add extra organisation (folders) to manage the files better. As currently I have loads of images within the drawable file and how would I reference these sub folders/images.
You cannot have sub folders within the resources structure. Android depends on the folder layout to determine which resource to use in what condition (localization, different screen resolutions, etc).
I'm not sure why exactly you are trying to load up a whole bunch of images, but there are a couple of (slower) methods that allow you to look up a resource by string name. If you used a naming convention for your images you could look them up that way via [Resources.getIdentifier()][1]. However, in a game performance likely matters, so you are probably better off with a more manual approach using the int IDs directly since it is much more efficient.
[1]: http://developer.android.com/reference/android/content/res/Resources.html#getIdentifier(java.lang.String, java.lang.String, java.lang.String)
I am uploading a load of images as they will be shown to user for different items. Its not a system where responsiveness is critical so its okay in terms of what I want. Though...
public int getIdentifier (String name, String defType, String defPackage)
Since: API Level 1
Return a resource identifier for the given resource name. A fully qualified resource name is of the form "package:type/entry". The first two components (package and type) are optional if defType and defPackage, respectively, are specified here.
Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.
They suggest using the resource id but if I want to add a file later on then I have to re-compile the app to include the extra file, this is where it bugs me, as the pic gets associated to an item that I have in a string array. So I can add items to the array but not the images without a change of the code.
Surely there is a function to fix this?