Path to Assets?

Could someone be kind enough to advise on the code needed in order to return the path to a file in Assets (all android versions, but will be targeting Android 11+)

I have seen getAssets() and getAssetsPath() in my research, but all examples are for android studio...

The File component, using the scope Asset and fullPath, doesn't work when compiled (A10 or A12)

Need something that works when the app is compiled

Many thanks

If for companion, this is what I did last year:

2 Likes

Need for a compiled app.... :upside_down_face: that last line ?

Why do you want that for :sweat_smile:

They can be used here too:

public String PathAsset(String name) {  return form.getAssetPath(name);  }

Try this, im not sure if it would return the result you expect.

Thank you will try it

1 Like

Works OK in companion.
file:///storage/emulated/0/Android/data/edu.mit.appinventor.aicompanion3/files/assets/example.pdf
(I then strip off the file://)

But when compiled returns the path /android_asset/example.pdf

full path of file:///android_asset/example.pdf also fails to load the file

with Runtime Error
open failed:ENOENT (no such file or directory)

Unless I need to construct my path differently

Assets on AI2 with Companion on Android < 10 (≀ API 28):

/storage/emulated/0/Android/data/edu.mit.appinventor.aicompanion3/files/AppInventor/assets/

See also here:

Btw, on Kodular with Companion for Android < 10 it is no longer Makeroid, but Kodular.

1 Like

If you want to just access the file why not directly:

        InputStream stream = form.openAsset("asset.txt");

Ah, perhaps we are getting somewhere...?

Where are you using the path at? If you want to access the asset file you can do it directly...?

Need more help with what to do with this ^^^ :frowning:

If we start from here, what next:

  public void GetAsset(String filename) {
     InputStream stream = form.openAsset(filename);

     }

I am not sure what you want to do? :sweat_smile: Do you want to read an asset file?

Hang on, real world getting in the way...:slight_smile:

1 Like

My ViewPDF extension requires an absolute path to display a pdf. This works just fine for files in, for example, the ASD, but if i have files in the assets, I have to copy them over in order to display them. I would like to be able to provide a path to display directly from assets. (Image is using companion, but you should get the idea)

1 Like

It might be better to internally use an InputStream to read the PDF rather than rely on a path in the file system. Assets are not stored in the file system in the traditional way--they're read from the AssetManager and come from inside of the APK file. Likewise, in some cases you might have a content:// URI which internally might map to a file on the file system but may not be accessible by your app unless you use the content URI. In both situations, Android provides an API to get an InputStream to read the content.

1 Like

Thank you Evan

What else do I need then to create a block I can plug in to my pathToPdf socket?

public void GetAsset(String filename) throws IOException {
     InputStream stream = form.openAsset(filename);

     }

I have tried a return but that throws an error in the above.

I guess it depends on what you're trying to do? Based on your blocks, it seems like you might be trying to render the PDF using a webviewer. In this case, I'd do something like:

import android.util.Base64;
import com.google.appinventor.components.runtime.util.IOUtils;

// ...

InputStream in;
try {
  in = form.openAsset(filename);
  byte[] contents = IOUtils.readStream(in);
  String content64 = Base64.encodeToString(contents, Base64.NO_WRAP | Base64.URL_SAFE);
  content64 = "data:application/pdf;base64," + content64;
  // Set web viewer URL to content64
} catch (IOException e) {
  // Report error via form.dispatchErrorOccurred(...)
} finally {
  IOUtils.closeQuietly(in);
}

The extension needs the pdf.... (which it converts to a series of images, which are built in to an html file to then display in the webviewer)

Without knowing what the PDF API that you are using looks like, it is hard to guess. Hopefully, it would take an InputStream as an input in some form and would just read the contents from the stream.