[expo-media-library] createAssetAsync() crashes on Android 11

  1. SDK Version: 40
  2. Platforms(Android/iOS/web/all): Android

I’ve been using the following code in my app for a while. It downloads a PDF file and saves it using the Media Library API.

FileSystem.downloadAsync(
    // example file
    'http://www.africau.edu/images/default/sample.pdf',
    FileSystem.documentDirectory + 'testFile.pdf'
)
    .then(({ status, uri }) => {
        if (200 === status) {
            saveFileAndroid(uri);
        }
    })
    .catch(e => {
        console.log(e);
    });

const saveFileAndroid = async uri => {
      const { status: existingStatus } = await MediaLibrary.getPermissionsAsync();

      if (existingStatus !== 'granted') {
        return;
      }

      try {
        const asset = await MediaLibrary.createAssetAsync(uri),
          album = await MediaLibrary.getAlbumAsync(appName);

        if (!album) {
          await MediaLibrary.createAlbumAsync(appName, asset, false);
        } else {
          await MediaLibrary.migrateAlbumIfNeededAsync(album);

          await MediaLibrary.addAssetsToAlbumAsync([asset], album, false);
        }
      } catch (e) {
        console.log(e);
      }
    };

This works fine on all Android devices except the ones with Android 11, where it breaks on createAssetAsync(). The error is: “Unable to copy file into external storage”.

I’m aware that Android 11 introduced changes to its scoped storage, but I haven’t found any documentation on this error. Any suggestion on what to do?

Thanks.