Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to copy files from internal storage into scoped storage in an external SD card in the Podcasts directory? #52

Closed
mitchdowney opened this issue Jul 22, 2022 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@mitchdowney
Copy link

mitchdowney commented Jul 22, 2022

react-native: 0.66.1
react-native-file-access: 2.4.3
Platform: Android 11

Bug
I can't seem to copy files from the local device storage into permission-based scoped storage on an SD card.

I'm trying to save to the Podcasts directory, but I've tried many directories on the SD card and get the same failing result.

Details

@alpha0010 sorry as this question involves an additional library (react-native-scoped-storage), and I'm not sure if the problem is some incompatibility between the two. I'm wondering if you could see some obvious mistake I'm making with my process...

I'm trying to copy to the scoped storage "Podcasts" directory on an SD card, but I get an error like follows:

Error: /tree/01F6-AC3F:Podcasts/document/01F6-AC3F:Podcasts/7kJmAzNQ3.mp3: open failed: ENOENT (No such file or directory)

Here's the sequence of steps I'm doing to get there...

First, I requested permission to the SD card Podcasts directory using:

import * as ScopedStorage from 'react-native-scoped-storage'
...
  _setExtDownloadFileLocationAndroid10 = async () => {
    const dir = await ScopedStorage.openDocumentTree(true)

    if (dir?.uri?.endsWith('%3APodcasts')) {
      const sdCardDownloadLocation = dir.uri
      await AsyncStorage.setItem(PV.Keys.EXT_STORAGE_DLOAD_LOCATION, sdCardDownloadLocation)  
      ...
    }
  ...
}

Then, on file download using react-native-background-downloader, I download to origDestination (RNFS.TemporaryDirectoryPath), then try to move it into scoped storage:

  const folderPath = RNFS.TemporaryDirectoryPath
  const origDestination = `${folderPath}/${episode.id}${ext}`
  // download the episode from origDestination using react-native-background-downloader
  ...
  // then in the `done` callback, I try to move the file into scoped storage:
  const sdDestination = `${sdCardDownloadLocation}/${episode.id}.mp3`
  await FileSystem.cp(origDestination, sdDestination)
...

However...when I do that I get:

Error: /tree/01F6-AC3F:Podcasts/document/01F6-AC3F:Podcasts/7kJmAzNQ3.mp3: open failed: ENOENT (No such file or directory)

When I use RNFS.TemporaryDirectoryPath or RNFS.DocumentDirectoryPath, I have not been able to find where the file is initially stored by react-native-background-downloader (I might just not know where to look). I have used the Files explorer on the device, and I have used Android File Transfer on my Mac to try to find the files...I also have "show hidden files" enabled and still can't find them.

However, when I use RNFS.DownloadDirectoryPath, I can find the files are successfully downloaded to Internal Storage > Download directory.

In any case, wherever the files are initially downloaded...it seems like according to the error message that react-native-file-access just can't find or write to the SD Card > Podcasts directory.

There must be something fundamental I'm missing about this process...does that make sense, and do you have any advice on how to accomplish this?

@mitchdowney mitchdowney added the bug Something isn't working label Jul 22, 2022
@mitchdowney
Copy link
Author

mitchdowney commented Jul 22, 2022

Another thing related to this...it seemed like cpExternal() might be intended for this purpose (copying a file from internal to scoped SD card storage), but cpExternal() doesn't have the "Podcasts" directory as an option.

Beyond that though, cpExternal() isn't working for me, even with the "downloads" param, I think because the openDocumentTree method will not let me select the Download folder to give it scoped storage permission.

Any insights on what I'm doing wrong would be greatly appreciated.

@alpha0010
Copy link
Owner

From what I can tell, it is an incompatibility. I will see what I can do.

@alpha0010 alpha0010 self-assigned this Jul 22, 2022
@mitchdowney
Copy link
Author

@alpha0010 do you think the incompatibility is with react-native-scoped-storage? Or something else is incompatible?

@mitchdowney
Copy link
Author

mitchdowney commented Jul 24, 2022

@alpha0010 follow-up question...the only reason we are using react-native-scoped-storage AND react-native-file-access (assuming react-native-file-access does in fact support scoped storage) is because react-native-scoped-storage has an openDocumentTree method so that the user can select which directory to use for scoped storage. Is there a method similar to openDocumentTree in react-native-file-access? Or is the expectation for us to use a separate library to enable scoped storage?

@alpha0010
Copy link
Owner

Should be fixed in v2.4.4.

I would like to add features from libraries such as react-native-scoped-storage and react-native-document-picker to this library, so that only one library is really needed for file handling. However, I just do not have the time for that currently. (PRs always welcome.)

@mitchdowney
Copy link
Author

@alpha0010 it works! I was able to download audio files to the SD card for the first time 🥳 thanks so much for the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants