Saving Files to Public Storage on Android Q (API 29)

Saving Files to Public Storage on Android Q (API 29)

Android Q (API 29) introduced significant changes to how apps can access external storage, enhancing user privacy and data control. Accessing public storage for writing files now requires specific permissions and adheres to a scoped storage model. This article outlines the steps and considerations for saving files to public storage in Android Q and above.

Understanding Scoped Storage

Scoped storage restricts apps to their designated storage areas (app-specific directories). This model enhances security and prevents data conflicts between apps. Accessing public storage, like the Downloads folder, involves requesting specific permissions and using designated system APIs.

Prerequisites

  • Target API Level 29 or higher
  • Manifest Permissions:
    • android.permission.WRITE_EXTERNAL_STORAGE
    • android.permission.READ_EXTERNAL_STORAGE

Saving Files using MediaStore API

1. Create a ContentResolver

ContentResolver resolver = getContentResolver();

2. Define the File’s Content URI

The content URI for the Downloads folder is: MediaStore.Downloads.EXTERNAL_CONTENT_URI

3. Prepare File Metadata

  • ContentValues values = new ContentValues();
  • values.put(MediaStore.Downloads.DISPLAY_NAME, "your_file_name.ext");
  • values.put(MediaStore.Downloads.MIME_TYPE, "mime/type");
  • values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);

4. Create the File

Uri contentUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);

5. Open an OutputStream

OutputStream outputStream = resolver.openOutputStream(contentUri);

6. Write File Data

// Write your file data to the outputStream
outputStream.write(fileData);
outputStream.close();

7. Handle Result

If successful, contentUri will hold the URI of the newly created file in the Downloads folder.

Example Code

import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;

// ... within your activity or service

public void saveFileToDownloads(byte[] fileData, String fileName, String mimeType) {
    ContentResolver resolver = getContentResolver();
    ContentValues values = new ContentValues();
    values.put(MediaStore.Downloads.DISPLAY_NAME, fileName);
    values.put(MediaStore.Downloads.MIME_TYPE, mimeType);
    values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);
    Uri contentUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
    if (contentUri != null) {
        try (OutputStream outputStream = resolver.openOutputStream(contentUri)) {
            outputStream.write(fileData);
        } catch (Exception e) {
            // Handle error
        }
    } else {
        // Handle failure to create file
    }
}

Permissions

To use these APIs, you must declare the necessary permissions in your app’s manifest:

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

Important Considerations

  • Target API Level: Ensure your app’s target API level is 29 or higher to use the MediaStore API for external storage.
  • Runtime Permissions: Request the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions at runtime using the requestPermissions() method, as per best practices.
  • Data Security: Always consider data security when accessing external storage. Encrypt sensitive information before storing it in external storage.

Conclusion

Saving files to public storage in Android Q (API 29) and above requires specific permissions, utilizing the MediaStore API. By following these steps and adhering to the scoped storage model, you can safely and securely manage your app’s file storage access.


Leave a Reply

Your email address will not be published. Required fields are marked *