Accessing a file on Android SD card

Discussions specifically related to the Android and iOS editions of BBCSDL
atom058
Posts: 25
Joined: Tue 05 Nov 2019, 18:07

Accessing a file on Android SD card

Post by atom058 »

Hello - I am writing an Android app that needs to be able to access the Android's on-board SD card to read in a data file. My app, as it is, will read in the data file if it is located in the same folder as the program, so that part works. Ultimately, I need to be able to read the file from a folder on the SD card as that is where it will be "deposited". So, I need to be able to navigate to the file on the SD card, find the file, and return the filename to the program so that I can then read in the data. Very similar to the "File / Load" function of the SDLIDE program. I have opened that program up, but can't determine what I need to strip out to get just that functionality. I have looked at all the file-related functions and can't tell which part I need or if they will run on an Android. Can someone please point me in the right direction? Thanks!
RichardRussell

Re: Accessing a file on Android SD card

Post by RichardRussell »

atom058 wrote: Mon 06 Apr 2020, 15:25Can someone please point me in the right direction?
The only thing that's different about the Android file system, compared with the other supported platforms, is that there is no concept of 'current directory'. What this means in practice is that 'relative' paths, i.e. directories specified relative to the current directory, cannot be used; instead all file paths must be 'absolute', i.e. start with a / character.

With that proviso there should be no particular difficulty accessing files on the SD card or elsewhere (assuming of course that they can be accessed at all from a user-mode program), it's just a case of knowing the full path to that file. Unfortunately that is not standardised between manufacturers so I can't tell you specifically where it wil be on your device; commonly it will be a subdirectory of /storage but even that isn't guaranteed.

If you can see the file from your PC, when connected via a USB cable, that should help you locate it in Android's file system (dir /s will do a recursive search from a command prompt). Alternatively you can try to find it from the touchide file selector, but there will inevitably be an element of trial-and-error in that approach. You could even write your own BASIC program to recursively search the file system!
atom058
Posts: 25
Joined: Tue 05 Nov 2019, 18:07

Re: Accessing a file on Android SD card

Post by atom058 »

Richard - Thank you for your reply. I am able to see the file on the SD card in the Android via my PC file explorer. The path is:

"This PC\RCT6A03W13E\SD card\Export\LibsData.csv"

How would I reference to that file from where the program is running? Would it be "\SD card\Export\LibsData.csv"?

I tried this:
file$ = "\SD card\Export\LibsData.csv"
file% = OPENIN(file$)
IF file% = 0 ERROR 0, "Could not open file " + file$

and got the error. Am I using the right format for the filename?
RichardRussell

Re: Accessing a file on Android SD card

Post by RichardRussell »

atom058 wrote: Mon 06 Apr 2020, 20:31How would I reference to that file from where the program is running?
If you can see, from the PC, both the directory which corresponds to @usr$ and the file you are interested in, it should be a simple matter of noting how to get from one to the other on the PC (for example 'up four levels, then down through these directories') and then applying the same traverse to what @usr$ contains. If that still doesn't work it may mean that the file's location isn't visible from BBC BASIC, in which case you will need to move it somewhere else.
I tried this: file$ = "\SD card\Export\LibsData.csv"
Using backslashes on Android (or indeed any OS other than Windows) is never going to work! The differences document says the following: "To ensure cross-platform compatibility, a forward-slash (/) should always be used as the directory delimiter, not a backslash (\)". It's best to get into the habit of never using backslashes as directory delimiters at all, because Windows accepts forward slashes (at the API level) and all other common OSes require them.
atom058
Posts: 25
Joined: Tue 05 Nov 2019, 18:07

Re: Accessing a file on Android SD card

Post by atom058 »

Richard - Thank you for the reply - The "/" was a typo on my part - sorry. It should be "\". Good news - I am now able to read the data file in the Export directory of the SD card(!). What I did was write a little program that would give me the full path of where it (the program) was residing. I put this program in the Export directory and it gave me this: "/storage/7B8A-B22A/Export/". I took that path info and appended my data file name to it and now my program finds it with no problem! I realize this path info may be different from one device to another, so I put that path in a .dat file in the same directory as the program that will be read when the program runs. That way it's not hard-coded in the program and can be changed easily. OK, that problem solved - now on to the next one - listing the files in the Export directory so I can select which one I want to use...

Thanks!
RichardRussell

Re: Accessing a file on Android SD card

Post by RichardRussell »

atom058 wrote: Tue 07 Apr 2020, 19:36that problem solved - now on to the next one - listing the files in the Export directory so I can select which one I want to use...
There are of course off-the-shelf library routines for this (e.g. FN_filedlg in filedlg.bbc) but you might prefer to write your own to give you more control over formatting etc. You could compromise and use a library routine (e.g. FN_dirscan) to read the file list into an array, but handle the display and selection yourself. Some members here will advise you not to use library routines at all! The choice is yours.
RichardRussell

Re: Accessing a file on Android SD card

Post by RichardRussell »

Something to be aware of. BBC BASIC for Android requests permission to access file storage, but on recent Android versions permissions are not automatically granted on installation. Instead, you must go to Settings... Apps & notifications... BBC Basic... Permissions and enable the permissions explicitly (e.g. Storage if you want to access files other than in BASIC's local directories, and Microphone if you want to enable audio recording). Enabling storage permission will make a difference to what you can see by navigating 'upwards' from @usr$ in the file selector.
atom058
Posts: 25
Joined: Tue 05 Nov 2019, 18:07

Re: Accessing a file on Android SD card

Post by atom058 »

Thanks - I checked the permissions for storage and it was on. Good to know, though, for the future...
atom058
Posts: 25
Joined: Tue 05 Nov 2019, 18:07

Re: Accessing a file on Android SD card

Post by atom058 »

Hello - I am currently able to open and read data from files that are stored on my Android SD card. Now I am wanting to create and output data to a new file on the SD card. I am using the same path information that is used for accessing the data files, so I know it is correct. I have checked my permissions and it says that I "can modify or delete the contents of my SD card". When I run the program, it just crashes and gives me "Invalid Channel". If I change the path to @dir$, it works just fine - I can create the file and add data to it. No problem. Here is the routine:

Code: Select all

     
      DEFPROCSaveResults
      T$ = TIME$
      Out$ = T$ + ", " + FileName$ + ", " + STR$(HURatio) + ", " + STR$(OURatio) + ", " + ResMsg$
      DataFile$ = DataPath$ + "LIBSResults.dat"
      file% = OPENUP(DataFile$)
      IF file% = 0 THEN
        REM Create the file, write the header and dump the first line of data
        file% = OPENOUT(DataFile$)
        PRINT#file%, "Date/Time, FileName, H/U Ratio, O/U Ratio, U/U Ratio, Result"
        PRINT#file%, Out$
        CLOSE #file%
      ELSE
        REM Jump to the end of the file and spit out next line of data
        PTR#file% = EXT#file%
        PRINT#file%, Out$
        CLOSE #file%
      ENDIF
      ENDPROC
What I have been able to determine is that OPENUP and OPENOUT both are returning file%=0 and that is why I am getting the Invalid Channel error. Again, everything works fine if I use @dir$ as DataPath$. I even tried putting the file there (on the SD card) in advance, so that it would see it and just append to it, and same results. It is acting as if I don't have permission to create or modify a file on the SD card even though my permissions say otherwise. Any thoughts? Thanks!
RichardRussell

Re: Accessing a file on Android SD card

Post by RichardRussell »

atom058 wrote: Sat 11 Apr 2020, 21:52It is acting as if I don't have permission to create or modify a file on the SD card even though my permissions say otherwise.
I expect your conclusion is exactly right. Why it is denying you 'create' access there I cannot say, but that's what OPENOUT returning zero is telling you. A Google search suggests that you are not the only one to have experienced this issue.
If I change the path to @dir$, it works just fine
Don't rely on that; it's probably only writable because, in this specific instance, @dir$ is the same as @usr$. Of the built-in paths only @tmp$ and @usr$ should always be writable, @dir$ and @lib$ are likely to be read-only (and you should assume they are).