Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-14991] Android: Javascript can't get path of assets folder of module

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionWon't Fix
Resolution Date2015-11-11T07:55:23.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsAndroid
Labelslook1, parity, supportTeam
ReporterEduardo Gomez
AssigneeAshraf Abu
Created2013-08-28T22:20:39.000+0000
Updated2018-08-02T22:20:06.000+0000

Description

Problem

Client is trying to get images from Android Titanium Module and refer to them via Javascript. So instead of return a TiBlob they would like to get path access resolved so they just have to link image in their image proxy on a similar way like:
var image = Ti.UI.ImageView({
    image: '/modules/com.mod-id.org/images/image.png'
});
"image.png" would be contained at "/RootModuleFolder/assets/image.png" As the assets/README suggests, if you put the image.png in an "images/" subdirectory under assets. Then try to refer to it from a Javascript file.

assets/README

Place your assets like PNG files in this directory and they will be packaged with your module.

If you create a file named org.appcelerator.wifissid.js in this directory, it will be compiled and used as your module.  This allows you to run pure Javascript modules that are pre-compiled.

Steps to reproduce

Create the scenario as follows: 1) Create android module 2) Create directory in assets call 'images' 3) Put an image.png in assets/images 4) Create a test app 5) Replace app.js with snippet below. 6) Public the android module into the Test app 7) Launch the test app in an Android Device 8) Notice how nothing shows up If you create an iOS module in the same way as the android module and you publish it, when running the test app on an iOS device, you'll see the image.

A Snippet

var win = Ti.UI.createWindow({
    backgroundColor: 'yellow'
});
var view1 = Ti.UI.createImageView({
    top: 0,
    left: 0,
    height: Ti.UI.SIZE,
    width: Ti.UI.SIZE,
    // works for iOS, doesn't work for android
    image: '/modules/com.mod-id.org/images/image.png'
})
win.add(view1);
win.open();

Additional details

If you try any of these paths and attempt to use a TiUIImageView warning below is thrown as a drawable reference:
//None of these paths worked
//var imagePNG = '/modules/org.appcelerator.org/yes.png';
//var imagePNG = '/modules/org.appcelerator.org/assets/yes.png';
//var imagePNG = 'modules/org.appcelerator.org/assets/yes.png';
//var imagePNG = '/org.appcelerator.org/assets/yes.png';

var win = Ti.UI.createWindow({
    backgroundColor: 'yellow'
});
var image = Ti.UI.createImageView({
	top: 150,
	image: imagePNG
});
win.add(image);
win.open();
- 08-27 09:56:56.778: W/TiDrawableReference(3030): (pool-3-thread-2) [632,632] Could not open stream to get bitmap Other than parity, this can be just a TIDOC issue. But from javascript how does one refer to an image that's included as part of an android module?

Comments

  1. Jeff English 2013-08-29

    A couple of possible workarounds for now: **Module provides access to assets** Provide an API in the module to return the requested module resource. See the loadImageFromModule method provided in the moddevguide reference module found here: https://github.com/appcelerator/titanium_modules/blob/master/moddevguide/mobile/android/src/ti/moddevguide/ModdevguideModule.java and here: https://github.com/appcelerator/titanium_modules/blob/master/moddevguide/mobile/ios/Classes/TiModdevguideModule.m. The application can call such a method whenever it needs to get the assets from the module. This option provides parity across platforms. **Module makes assets available as drawable assets** 1. Place the module's assets in the 'platform/android/res/drawable' folder of the module project (you may have to create this folder). These assets will be packaged with the module when it is built. 2. The application can reference these assets as Ti.App.Android.R.drawable.<asset name>. For example, "image: Ti.App.Android.R.drawable.flower" This option requires platform-specific logic in the application.
  2. Hieu Pham 2013-08-29

    When we build the app APK file, we merge the the module's assets folder into the apk's assets folder. With this, a quick workaround would be: 1. Inside the module's assets folder, create Resources/ folder. 2. Put image into assets/Resources/ 3. Then you can treat the path as if the image is actually in your app's Resources/ folder. For instance, if my module name is emodule and I put image.png in emodule/assets/Resources/image.png, I would simply use the path 'image.png'. One drawback of this method is name duplication (i.e: if I have two same name images, one in my module's assets/Resources, and one in my app's Resources folder, one would overwrite the other). To prevent this, you can simply create unique sub-directories inside your module's assets/Resources.
  3. Jeff English 2013-08-29

    The use of the assets/Resources folder does not currently work. TIMOB-4233 mentions this issue for iOS, but the same issue exists for Android. IIRC, the build scripts explicitly ignores the Resources folder, but I could be wrong there. Correction: putting the assets in the 'assets/Resources' folder does work. The assets are bundled into the module's jar file, so you won't see them in the module's zip file. You can verify that the assets are bundled by running 'jar -xf ' and then looking in the 'assets/Resources' folder that is created. The module assets are then included in the application's apk
  4. Hieu Pham 2013-08-29

    I tested the above workaround on Android and it worked for me. I can see the image in Resources/ folder inside the APK file. Though that workaround doesn't work with density images. In that case, you'd need to use the 'assets as drawables' workaround.
  5. Eduardo Gomez 2013-08-29

    'Assets as drawables' can work for them. Just they will need to deal with density-specific image logic. Furthermore, I tried using density specific folders but can't get it to work. They are definitely bundled with module.jar. But can't seem to find them in the APK. Is it possible at all? e.g.
       wifissid//platform/android/res/drawable/drawable-hdpi
       wifissid//platform/android/res/drawable/drawable-hdpi/yes.png
       wifissid//platform/android/res/drawable/drawable-ldpi
       wifissid//platform/android/res/drawable/drawable-ldpi/yes.png
       wifissid//platform/android/res/drawable/drawable-mdpi
       wifissid//platform/android/res/drawable/drawable-mdpi/yes.png 
       
  6. Chris Barber 2013-11-09

    After discussing with [~jenglish] and [~ayeung], I am going to be fixing this by adding support for two new directories within modules: "app" and "resources". The current behavior with how the "assets" directory will be preserved. Currently the "assets" folder copies to the following folder: Android: build/android/res/assets iOS: build/iphone/build/Debug-iphoneos/testapp.app/modules/com.mymodule To normalize how assets are copied, files in the "app" and "resources" directories will be copied as such: "app" directory will be copied to: Android: build/android/res/assets iOS: build/iphone/build/Debug-iphoneos/testapp.app "resources" directory will be copied to: Android: build/android/res/assets/Resources/modules/com.mymodule iOS: build/iphone/build/Debug-iphoneos/testapp.app/modules/com.mymodule
  7. Ashraf Abu 2015-03-25

    Proposed solution for parity:- Perhaps a simple solution for parity to work when using: '/modules/com.mod-id.org/images/image.png' in Android is internally in the Android code, when it sees it is referring to the modules directory, it will map that to '/images/image.png'. Basically stripping the '/modules/com.mod-id.org/'. Would this be an acceptable solution for this?
  8. Ashraf Abu 2015-03-26

    [~jalter] [~penrique] Any thoughts on this?
  9. Jon Alter 2015-03-26

    [~msamah] - Could I get another example? The solution is not totally clear to me.
  10. Carlos Henrique Zinato 2015-11-09

    Guys, I've tried a lot of paths and I'm still not able to "embed" an image with my Android module =/ For iOS "modules/com.mymodule/image.png" works fine!
  11. Ingo Muschenetz 2015-11-09

    [~chmiiller] Did you try one of the workarounds earlier in the ticket?
  12. Carlos Henrique Zinato 2015-11-09

    Ok guys, I was kind of lost in the comments but figured out how to do it. You need to create a Resources folder inside "assets" like Hieu Pham said. So, you want to call "logo.png": 1. Create "Resources" folder inside the "assets" folder. 2. Use your image name as path: Ti.UI.createImageView({ image:'logo.png' }); 3. Done! Thank you all!
  13. Ingo Muschenetz 2015-11-09

    [~chmiiller] That's great!
  14. Eric Merriman 2018-08-02

    Closing old "Won't fix" tickets. If you disagree, please reopen.

JSON Source