An Expo module for directly downloading files to the native Downloads folder on Android and iOS.
npx expo install expo-downloads
Below is a sample code which saves a text file named example.txt
to the native Downloads folder.
For Android versions 9 and below, the WRITE_EXTERNAL_STORAGE
permission is checked.
import { saveFile, openFile, getPermissionsAsync, requestPermissionsAsync } from "expo-downloads";
const options = {
name: "example.txt",
type: "text/plain",
data: "Hello, World!",
};
// For Android 9 and below, request WRITE_EXTERNAL_STORAGE permission.
const permissions = await getPermissionsAsync();
if (!permissions.granted) {
const newPermissions = await requestPermissionsAsync();
if (!newPermissions.granted) {
console.error("Could not obtain permissions");
return;
}
}
try {
const result = await saveFile(options);
if (result.cancelled) {
console.log("Download was cancelled");
} else {
console.log(`File saved successfully: ${result.uri}`);
// Example of opening the file immediately after saving
await openFile({ uri: result.uri, type: options.type });
}
} catch (error) {
console.error("Error saving or opening file:", error);
}
android-text.mp4
android-image.mp4
ios-text.mp4
ios-image.mp4
-
Description: Saves the Base64 encoded file data using the provided options.
-
Parameters (
SaveFileOptions
object):name
: The name under which the file will be saved.type
: The MIME type of the file.data
: The file data to be saved.encoding
: (Optional) The encoding of the data, either "base64" or "utf8". Defaults to "utf8".
-
Returns (
SaveFileResponse
object):uri
: The URI of the saved file (upon success).cancelled
:true
if the operation was cancelled by the user (iOS only).
-
Description: Opens the downloaded file using the native file viewer on the device.
-
Parameters (
OpenFileOptions
object):uri
: The URI of the file to be opened. (Use theuri
field of theSaveFileResponse
object returned bysaveFile
.)type
: The MIME type of the file.
-
requestPermissionsAsync
:
Requests theWRITE_EXTERNAL_STORAGE
permission for Android versions 9 and below. (This permission is not required on Android 10+ and iOS.) -
getPermissionsAsync
:
Retrieves the current status of the storage write permission.
-
ERR_INVALID_ARGUMENT (iOS / Android)
- Thrown if the
name
is empty, if thetype
format is invalid, or if thedata
is improperly formatted.
- Thrown if the
-
ERR_FILE_OPEN
- Thrown when an error occurs while attempting to open a file. This exception is raised if the specified file does not exist or if a compatible application cannot be found to open it.
-
ERR_DOWNLOAD_IN_PROGRESS
- Thrown if a download is already in progress, preventing simultaneous operations.
-
ERR_MISSING_VIEW_CONTROLLER
- Thrown if the current view controller cannot be obtained, which prevents the file-saving dialog from being displayed.
-
ERR_CONTENT_URI_CREATION (Android 10 and above)
- Thrown if creating the content URI using the MediaStore API fails.
-
ERR_OUTPUT_STREAM_CREATION (Android 10 and above)
- Thrown if an OutputStream for writing to the file cannot be created.
-
ERR_DIRECTORY_CREATION (Android 9 and below)
- Thrown if the Downloads folder does not exist or if attempting to create it fails.
-
ERR_OUT_OF_MEMORY
- Thrown when the file is too large and an OutOfMemoryError occurs during saving due to insufficient memory.
- Implementation:
UsesUIDocumentPickerViewController
to allow the user to select a save location.
- Implementation:
Uses the MediaStore API to save files to the system-managed Downloads folder. - Permissions:
No special storage permissions are required on API level 29 and above.
- Implementation:
Writes directly to the device's Downloads folder using legacy methods. - Permissions:
TheWRITE_EXTERNAL_STORAGE
permission is required. UserequestPermissionsAsync
andgetPermissionsAsync
to handle permissions.
- Implementation:
Utilizes HTML'sBlob
and<a>
tag to download the file.