How to save file to storage (android 13 – API33) – Android

by
Ali Hasan
android android-13 cucumber-java gradle-kotlin-dsl

The Problem:

I’m trying to save a screen recording as an MP4 file to external storage on Android 13 (API level 33). My code works on API 29 and below, but it doesn’t work on API 32 and above. I’m using Environment.getExternalStoragePublicDirectory to get the external storage directory, but it doesn’t seem to be working correctly. I’m getting a java.io.FileNotFoundException error when I try to save the file. What changes do I need to make to my code to support saving files to external storage on Android 13 and above?

The Solutions:

Solution 1:

To save a file to storage on Android 13 (API 33), use the following steps:

1. Declare storage permissions in your AndroidManifest.xml file:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2. Request storage permissions programmatically using ActivityCompat.requestPermissions(). Here’s an example:

ActivityCompat.requestPermissions(
    this,
    arrayOf(
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    ),
    REQUEST_CODE
)

3. Create a file using File() and write data to it using OutputStreamWriter(). Here’s an example:

val file = File("/storage/emulated/0/MyFile.txt")
val writer = OutputStreamWriter(file.outputStream())
writer.write("Hello world!")
writer.close()

4. To save the file to a specific directory, use the Environment.getExternalStorageDirectory() method. Here’s an example:

val file = File(Environment.getExternalStorageDirectory(), "MyFile.txt")
val writer = OutputStreamWriter(file.outputStream())
writer.write("Hello world!")
writer.close()

5. Save the file to a specific directory using the FileProvider class. Here’s an example:

val file = File(
    this.filesDir,
    "MyFile.txt"
)
val writer = OutputStreamWriter(file.outputStream())
writer.write("Hello world!")
writer.close()

val uri = FileProvider.getUriForFile(
    this,
    "com.example.myprovider",
    file
)

Solution:

On Android SDK 33 you will not ask for the WRITE_EXTERNAL_STORAGE permission to begin with, as you have write permission by default to all public directories on external storage.

Solution 3: Use ACTION_CREATE_DOCUMENT Intent

This updated solution addresses the changes introduced in Android API level 29 regarding external storage access. Instead of directly saving the file to a specific location, it uses the ACTION_CREATE_DOCUMENT intent to have the user choose a storage location.

Here’s a breakdown of the key steps:

  • Create an intent with the action ACTION_CREATE_DOCUMENT.
  • Specify the category CATEGORY_OPENABLE to allow the user to choose a location.
  • Set the type to "video/mp4" to indicate the file type.
  • Use putExtra to specify a default file name.
  • Start the intent to open the document creation interface.

When the user selects a storage location and confirms the creation of the document, the result is returned in the onActivityResult method. If the result is successful, the app can use the returned Uri to save the video data using the contentResolver.openOutputStream method.

Q&A

How can I save a file to storage in Android 13 (API33) and above?

Start by requesting the necessary permissions (READ_MEDIA_VIDEO and READ_MEDIA_IMAGES) in the manifest and programmatically. Use the createAppDirectoryInDownloads and createFileInAppDirectory methods to create a directory and file, respectively, in the Downloads folder.

How should I approach file saving in Android 13 (API33) and above?

You no longer need to request the WRITE_EXTERNAL_STORAGE permission since you have default write access to public directories. Consider using the ACTION_CREATE_DOCUMENT intent to let users choose the save location.

How can I save a video file to a specific location in Android 13 (API33) and above?

Use the ACTION_CREATE_DOCUMENT intent to prompt the user to choose a save location. Once they select a location, you can use a ContentResolver to open an OutputStream and write the video data to the chosen location.

Video Explanation:

The following video, titled "How to create and save an image file in Download folder from your ...", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

The App is developed in Android Studio for Android 13 - API 33 ... Write Text File to Internal Storage - Android Studio Tutorial. Coding in Flow ...