5

I would like to know - are there ways to access android resources and/or assets files (or files from any other folder) outside of an Activity (without passing context)?

Can't access without context:

getResources().getIdentifier("resource_name", "drawable", getPackageName());
getAssets().open("file_in_assets_folder_name");

Throws Exception if not in Activity:

try {
    Class class = R.drawable.class;
    Field field = class.getField("resource_name");
    Integer i = new Integer(field.getInt(null));
} catch (Exception e) {}

Also tried the below, but it complains file doesn't exist (doing something wrong here?):

URL url = new URL("file:///android_asset/file_name.ext");
InputSource source = new InputSource(url.openStream());
//exception looks like so 04-10 00:40:43.382: W/System.err(5547): java.io.FileNotFoundException: /android_asset/InfoItems.xml (No such file or directory)
Marc
  • 145
  • 1
  • 3
  • 11
  • I can't really understand. You want to access android resources outside of an activity? Where are you if not in an activity? And what exactly are the android resources? Do you mean like the pre-installed icons? – nuala Apr 09 '12 at 23:56
  • are you in an extended class or in some library class that you don't have access to the context? – Yevgeny Simkin Apr 10 '12 at 00:23
  • @Marc: Why don't you want to pass a Context? – Squonk Apr 10 '12 at 00:24
  • yoshi - as I understand, Activities are for stuff user interacts with. My RSS and XML parsing classes are thus not activities. MisterSquonk - because I'd prefer to simply have a constant variable pointing to location of an xml file. I can do this for a remote xml file (rss feed), why not for one I include with my app? – Marc Apr 10 '12 at 00:26

2 Answers2

5

If the folders are included in the Project Build Path, you can use ClassLoader access files under them outside the android.content.Context, for instance, from a POJO (in case if you don't want to pass a reference of android.content.Context):

String file = "res/raw/test.txt";
InputStream in = this.getClass().getClassLoader().getResourceAsStream(file);
  • The res folder is included into Project Build Path by default by all Android SDK version so far.
  • The assets folder was included into Project Build Path by default before Android SDK r14.

To add folders into Project Build Path, right click your project -- Build Path -- Configure Build Path, add your folder (for example, assets if using later SDK version) as a Source folder in build path.

Check out the similar question I answered before at here.

Community
  • 1
  • 1
yorkw
  • 40,926
  • 10
  • 117
  • 130
  • Thank you, this works well for accessing a file. Could you also tell me if there is a way (without context) to access R.java contents? (my above question wasn't clear, by "android resources" I meant R.java). – Marc Apr 10 '12 at 21:37
  • What do you mean by "access R.java contents"? if you mean import/use public variable generated in R.java. Simply import com.example.R in you POJO class. Note that R.java is auto-generated from app resources and literately changed by SDK. I don't know what you want to achieve here but I don't see any point to use R.java outside android.content.Context. – yorkw Apr 10 '12 at 21:52
  • By access I meant being able to obtain various information about the resources. For example, get int id value from name (similar to 1st line of code in question). I merely didn't want to pass in context if I didn't have to. – Marc Apr 10 '12 at 22:25
  • Try adding statement `import com.example.R` in POJO class. – yorkw Apr 10 '12 at 22:30
  • For some reason (probably since it's generated and has fancy methods for access) I was treating it in my mind as some mysterious object rather than just a class that has some public variables... – Marc Apr 11 '12 at 00:36
  • So basically there's no way to sensibly make use of the android Resources system to store an array of values that will never be changed inside code in xml? For example, an array of types. – G_V Dec 01 '14 at 12:24
1

Android framework when compile your app create static class call:

your.namespace.project.R

you can statically call this class like:

your.namespace.project.R.string.my_prop

this.context.findViewById(your.namespace.project.R.id.my_id_prop);

Maybe you can access dynamic resources this way:

Resources res = this.context.getResources();
int id = res.getIdentifier("bar"+Integer.toString(i+1), "id", this.context.getPackageName());
Steven Koch
  • 629
  • 7
  • 9