I am trying to search for drawable (pictures) in a resource file in android from my library project Is it possible without the context of the of the actual android project or do I need to add that in? Also how would I be able to find an ID through my library project by using a string as the name of the ID and then convert it to the appropriate integer to set the background resource.
This is what I have tried so far: This works but only looks at the rescources in the library project, I need to look at the resources in the current application project
try
{
Class res = R.drawable.class;
Field field =
res.getField("string_ID_I_want");
drawableId = field.getInt(null);
}
The actual drawable resources are compiled into your app, so accessing them is no different than accessing normal app resources.
Supposing the ID of the drawable in the library is big_picture. Then R.drawable.big_picture is the ID of the drawable you want to load. You don't have to use introspection. If R.drawable.big_picture is not available, there's something wrong with your project setup (or a compile error).
Context context = getApplicationContext();
Resources r = context.getResources();
r.getDrawable(id); //pass your drawable id in it, could be R.id.whatever
Related
I'm working on a Android application and using this nice class to load a resource file, located in the applications res/raw folder, as a Java String:
public class ResourceReader {
public static String resourceToString(Context context, int id) {
try {
Resources res = context.getResources();
InputStream in_s = res.openRawResource(id);
byte[] b = new byte[in_s.available()];
in_s.read(b);
return new String(b);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
The context is the Activity based application class, the id is found using R.raw.mytext. The resource is a file, created in the mentioned folder.
When used in the app, it is no problem to get the file's content as a string with this line:
String content = ResourceReader.resourceToString(this, R.raw.mytext);
As the resources I read are likely to be used in other applications, I would like to put not only the classes, but also the resources into an external JAR file.
In eclipse I can create an android jar file, complete with resources and associated R class. The integer values associated with the names are accessible as expected, but how do I read the content?
I need to get the resources of the library, not those of the application.
The resourceToString method needs a context:
Resources res = context.getResources();
The Question is: is there a library context? And how do I get this context? - Or any other method to access the content of a library resource?
You can create an Android library. The output shall be an arr file which includes the classes and resources.
You may check Create an Android library for details.
The following is an excerpt from that page:
An Android library is structurally the same as an Android app module. It can include everything needed to build an app, including source code, resource files, and an Android manifest. However, instead of compiling into an APK that runs on a device, an Android library compiles into an Android Archive (AAR) file that you can use as a dependency for an Android app module. Unlike JAR files, AAR files can contain Android resources and a manifest file, which allows you to bundle in shared resources like layouts and drawables in addition to Java classes and methods.
A library module is useful in the following situations:
When you're building multiple apps that use some of the same components, such as activities, services, or UI layouts.
When you're building an app that exists in multiple APK variations, such as a free and paid version and you need the same core components in both.
In either case, simply move the files you want to reuse into a library module then add the library as a dependency for each app module.
Assume I've got 2 Application A and B.
I want to access resources (drawables, images, strings) of an B application from A application. How would I do that?
Edit:
You can also designate an Android project as a library project, which allows it to be shared with other projects that depend on it. Once an Android project is designated as a library project, it cannot be installed onto a device.
Does it mean That I can not use my library on android market?
My aim is to use default resources of Application A, but also if someone what he can download Application B and use it resources.
If you are the developer of both applications then the right approach would be, as othes noted, to create an Android library project and share it between apps.
Nevertheles, you can still access resources from another app, even if this is not your app:
Resources res = context.getPackageManager().getResourcesForApplication("com.example.foo")
If both apps are your own and you want to bundle these resources at build-time:
Create an Android Library Project, put all the needed resources into it and reference it from both your apps.
Edit to your edit:
You can use the library in the android market. You just can not use it alone (compile it). You have to build an app that uses the library. When you build that app, all the needed content gets basically grabbed from the library and copied to your apk. Which you can put on the market as usual.
This does not work when you want to access resources from an app that gets downloaded onto the device at runtime. A library project bundles all resources when you build the app that uses it. Peter Knego's response is the correct one when accessing at runtime.
It is possible if those both application are yours. Or you can used any Android Library for both these application. If you want you also create your own Android Library for this kind of work. Thnx.
Peter's answer above is great, but I'd like to elaborate a little more...
When you control appA and appB and want to get a drawable from appB, while in appA, then do the following:
Get the identifier of the drawable when in appB (for example, R.drawable.iconInAppB)
Then, in appA
Resources res = context.getPackageManager().getResourcesForApplication("com.example.appB");
Drawable d = res.getDrawable(integer);
//integer was what appB assigned to R.drawable.iconInAppB
*Note: The integer id assigned to R.drawable.iconInAppB will change over time so don't rely on hardcoding. I save the key-value pairs (String resourceName, int resourceId) in a database in appB and access them using a content provider.
For example, let's get the string-array with the ID of entryvalues_font_size from the package com.android.settings
String[] enries = null;
try {
// You can get PackageManager from the Context
Resources res = getPackageManager().getResourcesForApplication("com.android.settings");
int resId = res.getIdentifier("entryvalues_font_size", "array", "com.android.settings");
if (resId != 0) {
enries = res.getStringArray(resId);
}
}
catch (NameNotFoundException e) {
e.printStackTrace();
}
I have a question about inheriting resources from android libraries.
Assume you have an android library project and in that library you put some resources (let's say strings for the moment) under the package name com.libexample
Now in an android project under the package name com.example, I reference the library I created earlier.
If I want to use one of the strings of the library I can get it by using
getString(com.libexample.R.string.test_string);
My question is, is it possible for a string resource in my main project to get assigned the same integer ID as a string in my library? Cause if it is, then the above code statement would in fact be equal to :
getString(R.string.new_string);
assuming that the new_string recourse was assigned the same ID as the test_string resource.
Apparently the compiler adds the resources under the same generated R.java file automatically which prevents any conflicts.
I am trying to separate an application into an app project and a library project (besides moving it from Netbeans to Eclipse). The app will contain resources that are used by the library - for this, I had read on Stackoverflow that we can bundle the resources in the library project and then override them in the app project.
But when I did this, I am getting the error:
...\res\values\attrs.xml:5: error: Attribute "pageBackground" has already been defined
Am I doing something wrong here? Any of my assumptions is faulty?
Thanks,
Rajath
I think I had similar problem when I tried to create a kind of 'configuration file' which was placed in application's resources and was meant to alter behavior of library it used. What I found working was using getIdentifier method from Resources instead of refering directly to R class:
final int resId = getResources().getIdentifier("my_resource", "raw", getPackageName());
You can then use the identifier as normal resource ID, e.g.:
if (resId > 0) {
final InputStream is = getResources().openRawResource(resId);
// ...
}
The idea was to handle both situations: when the file was present in app's resources or when it was not. But I think it should also work in your case of "overriding" the resources from library in application, thanks to getPackageName providing appropriate package name for resources' identifiers' resolving.
Is there a way that i can see the resources from my app within my library?
I tried
Class res = Class.forName( extras.getString( R.string.getClass() ) ); <- apps' R class
final Field[] fields = res.getFields(); <- returns nothing
for(final Field field:fields){
....
}
Thanks
Update
The app could see the whole list by just getting R of the library, but now i cant get string value from the app
Is it possible that you really want to be using a raw resource, rather than the strings resource? If you want random access to strings, reading a file into memory would make things much easier.
The nature of the strings resource is more of a compile-time linking, not a database to search at run-time.