Assets Filepath

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

1 Like

After some experimentation I decided that SAF1.OpenSingleDocument which opens at the required directory was better than trying to construct my own file selection list with AI2 ListView etc. The only difficulty with SAF1.OpenSingleDocument was with the Mime Types relating to a particular type of text file. An *.abc (which is abcNotation for music) is not a recognised mime type despite the format having been around since about 1997 and hunderds of thousands of files in existance. I used Mime Type ‘application/octet-stream’ as a wildcard which gets round the problem – but probably not good practise.

To help others with similar issues, the following app demonstrates

  • using SAF1.OpenSingleDocument to make a file selection
  • incorpoorating JavaScript and HTML and CSS files into a user app (placed in Assets)
  • using AI2 WebViewer to display the JavaScript output
  • using window.AppInventor.getWebViewString() to pass data into JavaScript
  • plus odds and ends eg: CSS font-size vw/vh, button management

SAF1OpenSingleD o cument is used to select a music file of either *.mp3 or *.abc from Music/Bodhran/MP3 or Music/Bodhran/ABC directories. If you wish to run the app you can either (a) set up the above directories and copy a few tunes into them or (b) edit the Uri reference to a directory of your choice. Some sample *.mp3 and *.abc files are appended.

Depending on the music format selected (determined by filename extension) the file is passed to the AI2 Player 1 if *.mp3 or if *.abc passed to JavaScript. Playing an *.mp3 is trivial, but the *.abc process is somewhat more interesting.

In essence the JavaScript parses the *.abc textfile and produces (a) the sheet music score and (b) a sound file. WebViewer displays the music score (may need to scroll down to see it), with the notes animated when playing. The nice thing about the *.abc player is that the tempo can be changed which is great if you are trying two learn to play a new piece of music.

The JavaScript is in part embedded within the HTML and in part called from an ABCJS library, (see https://www.abcjs.net/) which has an extensive range of procedures, of which only a few are used in this demo.

Enough said, better just to have a look if interested. Best viewed on a tablet, but music score will squeeze onto a phone screen. An internet connection is required to pull in a piano soundfont to generate the JavaScript sound file.
SAF_ForBod2.aia (766.4 KB)

Having said I'd include a couple of sample music files I don't think they were uploaded???

3 Likes