how to reference an asset in a library project

41,717

Solution 1

This answer is out of date, the gradle build system and AAR files support assets.


From the Android Docs:

Library projects cannot include raw assets

The tools do not support the use of raw asset files (saved in the assets/ directory) in a library project. Any asset resources used by an application must be stored in the assets/ directory of the application project itself. However, resource files saved in the res/ directory are supported.

If you want to include files from a Library project, you'll need to put it in the resources instead of the assets. If you're trying to load HTML files from your library project into a WebView, this means that you'll have to go a more roundabout method than the usual asset URL. Instead you'll have to read the resource data and use something like loadData.

Solution 2

This is now possible using the Gradle build system.

Testing with Android Studio 0.5.0 and v0.9 of the Android Gradle plugin, I've found that files such as

MyLibProject/src/main/assets/test.html

are correctly packaged in the final application and can be accessed at runtime via the expected URL:

file:///android_asset/test.html

Solution 3

You can achieve this by creating a symbolic link in the project's asset folder that points to the directory in the library project.

Then you can access as below:

webview.loadUrl("file:///android_asset/folder_in_a_libary_project/info.html", null);

Solution 4

Okay. Ive been stressing out and losing sleep about this for a while. Im the type of person that loves API creation, and HATES complicated integration.

There arent many solutions around on the internet, so im quite proud of what Ive discovered with a bit of Eclipse Hackery.

It turns out that when you put a file in the Android Lib's /assets folder. The target apk will capture this and place it on the root of the APK archive. Thus, making general access fail. This can be resolved by simply creating a Raw Java Library, and placing all assets in there, ie (JAVALIB)/assets/fileX.txt.

You can in turn then include this as a Java Build Path Folder Source in Project > Properties > Java Build Path > Source > Link Source.

  1. Link Source
  2. Click on Variables. and Add New Variable, ie VAR_NAME_X. location : ../../(relative_path_to_assets_project)
  3. Click Ok

Now, when you build and run your app, the assets folder in the APK will contain your (GLOBAL Library) files as you intended.

No need to reconfigure android internals or nothing. Its all capable within a few clicks of Eclipse.

Solution 5

I confirm that Daniel Grant's approach works for at least the following situation: target project does NOT have an asset folder (or the folder is empty, so you can safely delete it). I did not setup any variable. Simply setup a LinkSource as follows (just an example) Linked folder location: /home/matthew/workspace_moonblink/assetsForAdvocacy/assets Folder name : assets

The "assetsForAdvocacy" is a Java project, (created with New- Project - Java Project) with empty src folder, and a new folder named "assets", which now provides the entire assets folder for the target project.

This is a fairly straightforward way within Eclipse to provide assets re-use across many different projects IF they do not already have assets, good enough to get going with. I would probably want to enhance it to become a content provider in the long run, but that is a lot more development.

My project accesses the assets with the following code: String advocacyFolderInAssets = "no_smoking/"; //a folder underneath assets/ String fn =advocacyFolderInAssets+imageFilename; Bitmap pristineBitmapForAdvocacy = getBitmapFromAsset(context, fn);

I use Motodev Studio 3.1.0 on Ubuntu. It would not let me 'merge' a new assets folder in the new assets-only project onto an existing assets folder in the target project.

Share:
41,717
an00b
Author by

an00b

Updated on July 09, 2022

Comments

  • an00b
    an00b almost 2 years

    In a class belonging to a Library project I call:

    webview.loadUrl("file:///android_asset/info.html", null);
    

    Unfortunately, this only works if I duplicate the file info.html into the Application's project asset folder as well.

    Is there a way to tell an Android library code: "look for this file in the library's assets folder, not in the application's assets folder" ?

  • an00b
    an00b about 13 years
    Thanks. Unfortunately, that thread doesn't explain how to reference an asset in a library project.
  • Lukas Knuth
    Lukas Knuth about 13 years
    Yes, it does... even with pictures: Link
  • Marcus Wolschon
    Marcus Wolschon over 12 years
    The problem with loadData is, that images and other page -element referenced in the loaded html can not be loaded without a lot of hacking.
  • an00b
    an00b about 12 years
    +1 for a great workaround, but what do you mean by "a Raw Java Library"? How do you create one on Eclipse? Thanks!
  • Thomas Dignan
    Thomas Dignan about 12 years
    You should write a proof of concept. I am doubtful of whether this actually works in the way someone familiar with assets in an android project would expect it to. For example, can the resultant assets be referenced with the "file:///android_asset" url?
  • pstoppani
    pstoppani over 11 years
    This is the most useful answer here!
  • Jimmar
    Jimmar almost 11 years
    +1 for a real answer :D in eclipse , just drag the assets folder from the explorer/finder/whatever into the project and chose to link it .. fastest way to do it
  • Nizzy
    Nizzy over 10 years
    @kabuko Google explanation is not clear to me. I have a project that has a library dependency. I have a path assets/dir/index.html, js, css files in this library project and this is loading from my application. I am using IntelliJ and there is an option to tell compiler to "Include assets from dependencies into APK". While compiling, it merges both assets. This is a common practice that developers do. Make sure that you have distinct directory and files names that won't conflict with application's files.
  • kabuko
    kabuko over 10 years
    @Nizzy It's entirely possible that this is a feature that is included in IntelliJ. I don't use IntelliJ or Android Studio regularly, so I can't say much on that front. I was purely speaking from experience (2.5 years ago to boot) using Eclipse and Ant as well as noting Google's own documentation. I would imagine IntelliJ is just doing exactly what OP described: copying the files over, albeit only in the build process.
  • Jim Moriarty
    Jim Moriarty over 10 years
    No it doesn't. Only how to reference a library project, not an asset in the library project.
  • Don Kirkby
    Don Kirkby over 9 years
    This worked for me, @TomDignan, so I posted a sample project that uses a linked resource for its assets folder.
  • Stealth Rabbi
    Stealth Rabbi over 9 years
    You're putting a folder called assets in the src directory, which isn't standard. Assets folders go in the root of the eclipse project / intellij module
  • Graham Borland
    Graham Borland about 9 years
    @StealthRabbi Wrong. See stackoverflow.com/questions/18302603/…
  • user1443721
    user1443721 almost 7 years
    This code does not work. Got exception "no such file" from url.openStream. URL url = new URL("file:///android_asset/test.html"); BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
  • Veeresh P
    Veeresh P almost 6 years
    I am building library module. Not getting how to open existing database in library module assets.Its the problem with path.Earlier in MainApplication i used to access it through applicationContext.getAssets().open(dbName) but now i don't know proper way to implement the same in library module
  • Saeed Masoomi
    Saeed Masoomi over 5 years
    @VeereshP, I build a library and want to access to asset files via getAssets() method but it's not working in library are you find any solution for this?
  • Veeresh P
    Veeresh P over 5 years
    @saeedmasoomi , I resolved path issue like this 'DB_PATH = Environment.getDataDirectory() + "/data/" + this.myContext.getPackageName() + "/databases/";'
  • Saeed Masoomi
    Saeed Masoomi over 5 years
    @VeereshP,Thanks :)
  • jiahao
    jiahao over 5 years
    Thanks to update the answer. Now the gradle build system allow us to add assets into Android libraries, is there anyway to access them directly from the Android library or they just get merged into the app module and we access them separately?