Friday, March 25, 2011

Accessing com.android.internal.R resources from APK

Sometimes you would like to get to resources that are used by the OS but there is no access to the com.android.internal.R resources class. It is possible to get to them by name. Here is an example for looking for a string value.


// this will look for an id of string (located in strings.xml)
// that has key name "web_user_agent", "android" is the reference
// to Android OS resources
int id = Resources.getSystem().getIdentifier("web_user_agent", "string", "android");
// now user agent can be found in system resources using the id
String webUserAgent = Resources.getSystem().getString(id);


This has also a good use case when an application is built not with SDK but with Android OS source tree. When application is built in this tree then access to com.android.internal.R is granted, but this may bring many complications when application will be executed on some vendor specific device. This problem comes from the fact that any given vendor can edit for example the strings.xml file, and then com.android.internal.R will be regenerated with some new values. Our application on compilation time will have an inlined int value reference to some string resource from the original Android OS, for example:


int web_user_agent = 0x00000001;


But on device X with some custom fancy UI and changed resources values 0x00000001 will be assigned to


int fancy_very_important_string = 0x00000001;


When application will launch on such device, it will look up for a string with id 0x00000001 and instead of getting string located under the key web_user_agent it will receive fancy_very_important_string.

This is of course a scenario that wont happen to most developers because most of them use official Android SDK that protects developers from hanging themselves along with their application. However if you will play with the Android source tree, problems like that are coming.

3 comments:

ABhi said...

How can i access id class of com.android.internal.R???

I'm planning to HIDE day Picker from DateView.

Any help would help,
thanks.

Maciej Pigulski said...

You cant access com.android.internal.R class directly from code using SDK. You can get to the Resources from this class by calling: Resources.getSystem(). Then if you want int value of a particular resource you have to know its name and then use the code above to find the value.

I have looked after DateView in the Android source but I don't understand what you want to do. Can you write something more about it?

Vlad said...

Thanks, this helped me a lot to find the localized 'More' string that appears when you have more than 6 menu items.