Assets Filepath

There have been various issues re Assets, but not on these lines as far as I can find. I am testing some html/Javascript code in WebViewer. The test html, js and css files are loaded into Media in Designer. My program then selects the html filenames from Assets and puts these into a ListView. I can then pick the html file which I wish to test. All that works fine in Companion (development) mode, but fails when compiled.

I’m using TaifunFile1.FileList with TaifunTool1.PathToAssets to pull in the files. See screenshot. In Companion the Assets Filepath is reported as file:///storage/emulated/0/Android/data/edu.mit.appinventor.aicompanion3/files/assets/ In the compiled code it is reported as file:///android_asset/

Thus in Companion mode the Asset filepath ends in the word ‘assets/’ and when compiled it is ‘asset/ - No ‘s’ on the end! Clearly my splittext call will fail for that reason alone. I could put code in to handle that, but it gets worse.

(1) As far as the compiled code is concerned there are no Media loaded files in file:///android_asset/. It is totally empty even with a wildcard filetype.

(2) Using Cx File Explorer to investigate I cannot find any folders or files in the ASD, unless they are all hidden. So where did TaifunTool1.PathToAssets find something called file:///android_asset/?

(3) Using the wildcard filetype in the Companion mode returns hundreds of files. Not just the five I’ve loaded in via Media for this specific program – but apparently every file that I’ve ever loaded for all of my apps in the last several years. It looks as if deleting a Media loaded file eg. jpg, png, mp3 or whatever during development does not really remove it. It disapears from the development screen but is still lurking around somewhere.... That strikes me as a serious problem.

Can anybody explain what is going on? How do I get a file listing from Assets in a compiled program?

you might want to use the FileListFromAssets method
filelistFromAssets

Taifun

Thanks, I've used the .FileListFromAssets to grab all Asset files and then filter for the '.html' filetype.
Due to the inconsistant filepaths between development mode and compiled mode that still leaves a problem as to how to reference the *.css and *.js files within HTML so that it runs under both modes. See screenshot for *.css files.
Under development mode I found that href="../assets/filename" worked - but not when compiled. After, much faffing around it turns out that href="filename" on its own worked for both development and compiled. Same for the *.js files external to the HTML. Can't think why a 'no filepath' works - but hayho!

For files in assets you can use the path:
http://localhost/filename with both development(companion) and compiled mode

If all the files (html/js/css) are in the assets then it is, as you have found, just the case of using the filename without any path to call associated files in the html

2 Likes

Thanks for the previous help. This is similar to the issue I raise on 7 May – but not quite. I have encountered a different problem with the TaifunFile1.FileList block which only happens when running the compiled program. I have put in a debug statement immediately after that call so I know that is where the problem arises.

I am developing an App to play music to pracice the Bodhran. The practice music is in two formats and stored in /Music/Bodhran/MP3 for the mp3 tunes and /Music/Bodhran/ABC for the tunes in abcNotation. I have a function which uses TaifunFile1.FileList that lets me select from either /MP3 or /ABC. Folders. The selected file then gets passed to the appropriate routine to play the music.

All this woks well in development mode, but ‘selectively’ fails when compiled. The function call (see screenshot) to get a directory listing from /MP3 continues to work, but not from /ABC which returns with an empty list. I find this very strange. Why work when the function is directed to /MP3 folder but not for /ABC folder?

The file types and extension names between /MP3 and /ABC differ (*.mp3 and *.abc, where the latter are small text files), so that requires different processes to play the music. But all that is downstream of getting a directory listing, which is what I first need to get working in compiled mode. Any explanations? Is an *abc file extension name something toxic that TaiFunFile1.FileList ignores?– But only when compiled?!

create a test project and try it manually like this to display the list in a label

directoryName: /Music/Bodhran/ABC
extension: abc
includeSubdirectories: false

what do you get a) in the companion app and b) after building the app?

Taifun

Thanks Taifun, I'll put a test together, but kind of busy tomorrow so may be the day after. For tidy 'house-keeping' I kept the *.mp3 and *.abc files in separate directories, but I'll also do a test where both *.mp3 and *.abc files are in the same directory and see what happens.

I've put some test code together (see screenshots) and have run 'Development' mode and 'Compiled' mode tests for 'App' 'Shared' and 'Legacy' filescope cases. I ran the tests across four different directory paths (3 under /Music and 1 under /Documents). In each of these I had placed a mixture of files with extensions *.mp3, *.abc and *.txt and hence used the wildcard filetype. The tabulated results are attached. In all filescope cases the 'compiled' version only returns with *.mp3 files, wheras in the 'development' mode all the files are listed. This makes no sense to me. I can't see any logic error in the test code. What else can I try?

By the way, I've also attached an abcNotation file. If I was able to select them these get passed to some JavaScript which renders the music score and plays the tune. And, in the app I'm developing all that works when in 'Development' mode. An abcNotation file is just text, so I can't see why that should be a problem.
ABCfile

Non-media files can only be accessed with the app that created them. So if these files are created (saved) with Companion, they can only be accessed (read / listed) with Companion and NOT with the compiled app (which is another app).

See also here:

Non-media files (outside of the ASD or assets) can only be accessed on Android 11+ if they are created by the app itself and they are stored in one of these Shared folders:

  • /Documents
  • /Download

Media files can be accessed from any location on the device (incl. the root dir of internal storage).

Thanks Anke. It looks like I'll have to use the SAF approach as my application is a mix of media (mp3) and non-media (txt) files, none of which were created by the app itself. I've looked at SAF previously, but like several others couldn't get my head round it. However I agree with your comment (Sept 2022)
'As Sunny (the extension developer) has already explained, the possibilities of using this extension are almost unlimited, so it is hardly possible to present all possible scenarios in tutorials/examples.

Therefore, proceed as most users usually do

  • describe your specific goal / problem(s) in detail,
  • show us what you have tried so far (blocks & aia) and
  • where you get stuck.
    Then someone (at least from the power users) will surely be able to help you.

In that context what I need is a coded example of how to display a Directory Filelist > Pick a File > Read the File. In more detail:
(1) Create a file listing for a nominated directory eg /music
(Actually I can get that to half work with SAF1.ListFiles block which displays files in a file manager style, but doesn't seem to provide a selection mechanism, so see 2)
(2) Process (1) to put the file listing into a ListView. This reverts back to familiar territory for most users.
(3) Pass the ListView selected filename to a SAF call / calls to read the file.
(4) Get the result of the read, which I assume is through SAF1.GotReadResult.

Further processing after (4) will then depend on the nature of the file.
I think the get filelist, pick and read sequence would be a fairly frequent requirement for many apps, so I hope some SAF guru can provide an example which would be of great benefit.

If it was me, I would download all these files to my ASD and manage them from there. Suitable procedures in your app would allow for additional downloads / deletes / updates /exports.

The question is where do these non-media files come from. Of course, if these were created by other apps or the user created them manually, there is no way to download them (from anywhere).

Of course there is a way to download them, from a local or online server, Google drive, firebase storage, etc.

once again

They started off as assets, then moved to shared folders....

As long as these non-media files are part of the app package (assets), they can (as I have already explained) be copied in one of the two shared folders

  • /Documents or /Download or the
  • ASD or the
  • PrivateDir (internal storage)

In each of these cases there is full file access (read/write).

Anke and TIMAI2, thanks for your response. I hope my terminology is correct in that I'm calling files like csv and plain ASCII text non-media files as opposed to say mp3 and jpg which I regard as media.
In my apps non-media files have come from third parties. Example (1) a list of all Scottish mountains (Name, Lat/Lon, height etc) as a csv, or (2) abcNotation tunes (text) downloaded from a large library of abcNotation music.
Loading files into ASD (one way or another :slight_smile: ) may be okay in some cases. However, not really a practical solution for what I'm working on as these files are accessed by more than just my app, so would be 'invisible' if in ASD. Hence my desire to get up to speed with SAF.

Thanks Anke for the file listing example. I'll try it out later today. I was thinking that the 'average' MIT AI2 user's file operations come down to three things:
(1) Saving a file
(2) Reading a file
(3) Selecting a file
(1) Has been dealt with by an example called SAF_CreateTextFile and which, with some reworking, addresses (2). I think your example will deal with (3). That's progress!

Anke, a daft question perhaps. I'm coding up your screenshot and have got it more or less working, but for the call you make to SAF1.initialDir. I don't see that function in my SAF1 download. Where did you get that / what version of SAF? Without that the SAF1.OpenDocumentTree seems to default to /Documents. Also, is there a way to supress the filemanager type display and manual 'Use This Folder' prompt? Thanks again for your help, Fossil