14

My application depends on a library project.

The menu.xml file is within the application project.
All the java code is within the library project, including the menu handler code onOptionsItemSelected().

Is there a way to access the application resources from library project ? I'd like to write something like this, which is currently impossible, since menu items are not visible from the library:

if ( item.getItemId()==R.id.settings ) {
...
}
tos
  • 996
  • 1
  • 10
  • 20
  • 4
    You probably want to re-think your design if your library needs to make assumptions about what is in your application project. If the menu is something you wish to share with other projects, then move the menu into the library project. – Justin Breitfeller Feb 23 '12 at 21:05
  • I forgot to mention that the library project contains all menus, apart from one. The project menu has an additional "get the pro version" menu item. – tos Feb 23 '12 at 21:09
  • Maybe you want to sub-class from your library activity and add the menu option to "Go Pro" manually. – Justin Breitfeller Feb 23 '12 at 21:22
  • Yes, I think this would certainly be the most elegant way to do it. Triad's solution has the benefit of being fast. – tos Feb 23 '12 at 21:40

3 Answers3

23

Yes you can if you know the package name of your library. See: Resources#getIdentifier

You can do:

getResources().getIdentifier("res_name", "res_type", "com.library.package");

ex:

R.id.settings would be:

getResources().getIdentifier("settings", "id", "com.library.package");
hata
  • 11,633
  • 6
  • 46
  • 69
triad
  • 20,407
  • 13
  • 45
  • 50
13

You should really just include a version of the menu.xml resource in your library project. If you want to have a different menu.xml in your application, you can do that and it will override the copy from the library project.

From the Library Projects docs:

In cases where a resource ID is defined in both the application and the library, the tools ensure that the resource declared in the application gets priority and that the resource in the library project is not compiled into the application .apk. This gives your application the flexibility to either use or redefine any resource behaviors or values that are defined in any library.

Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
kabuko
  • 36,028
  • 10
  • 80
  • 93
  • This is probably the best all-around solution to the problem - removing the need altogether. I tried it, works fine. Thank you. – tos Feb 23 '12 at 22:12
  • Note that this [does not work well](https://stackoverflow.com/questions/37213375/is-it-possible-to-redefine-a-librarys-databinding-resource) with [Data Binding](https://developer.android.com/tools/data-binding/guide.html). – PLNech May 24 '16 at 14:33
1

I found @triad's solution with Resources.getIdentifier(String, String, String) to be somewhat error-prone:

  • the String-literal resource identifiers aren't checked by the IDE
  • multiple sequential String arguments to a single method are easy to use incorrectly.

I found this approach to work better for me:

String libString = context.getString(example.library.pkg.R.string.library_string)

Where the library's package is example.library.pkg.

  • The library's R class is resolved at compile-time, so your IDE will tell you if you referenced it correctly
  • Not importing the library's R class allows you to still use your own local R later, and explicitly marking the external resource usages makes them easier to spot.
medavox
  • 175
  • 2
  • 11
  • This doesn' work for me. @medavox do you think you can help me here https://stackoverflow.com/questions/64446897/translations-android-library-error-cannot-find-symbol – trixo Oct 21 '20 at 09:27
  • I found a solution @trixo. Check if your manifest has package declared. ` ` – Divya Gupta Jan 12 '23 at 05:30