Create/Copy File in Android Q using MediaStore

NOTE: If you reinstall the app, MediaStore will not recognize the previous-created file any more: Android 11 cannot retrieve files create with MediaStore after the app re-installs, using Intent to let user pick file is the only solution.


1. Create and Write File

createAndWriteButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        try {
            ContentValues values = new ContentValues();

            values.put(MediaStore.MediaColumns.DISPLAY_NAME, "menuCategory");       //file name                     
            values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain");        //file extension, will automatically add to file
            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS + "/Kamen Rider Decade/");     //end "/" is not mandatory

            Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);      //important!

            OutputStream outputStream = getContentResolver().openOutputStream(uri);

            outputStream.write("This is menu category data.".getBytes());

            outputStream.close();

            Toast.makeText(view.getContext(), "File created successfully", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            Toast.makeText(view.getContext(), "Fail to create file", Toast.LENGTH_SHORT).show();
        }
    }
});

2. Find and Read File

findAndReadButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Uri contentUri = MediaStore.Files.getContentUri("external");

        String selection = MediaStore.MediaColumns.RELATIVE_PATH + "=?";

        String[] selectionArgs = new String[]{Environment.DIRECTORY_DOCUMENTS + "/Kamen Rider Decade/"};

        Cursor cursor = getContentResolver().query(contentUri, null, selection, selectionArgs, null);

        Uri uri = null;

        if (cursor.getCount() == 0) {
            Toast.makeText(view.getContext(), "No file found in \"" + Environment.DIRECTORY_DOCUMENTS + "/Kamen Rider Decade/\"", Toast.LENGTH_LONG).show();
        } else {
            while (cursor.moveToNext()) {
                String fileName = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME));

                if (fileName.equals("menuCategory.txt")) {
                    long id = cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns._ID));

                    uri = ContentUris.withAppendedId(contentUri, id);

                    break;
                }
            }

            if (uri == null) {
                Toast.makeText(view.getContext(), "\"menuCategory.txt\" not found", Toast.LENGTH_SHORT).show();
            } else {
                try {
                    InputStream inputStream = getContentResolver().openInputStream(uri);

                    int size = inputStream.available();

                    byte[] bytes = new byte[size];

                    inputStream.read(bytes);

                    inputStream.close();

                    String jsonString = new String(bytes, StandardCharsets.UTF_8);

                    AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());

                    builder.setTitle("File Content");
                    builder.setMessage(jsonString);
                    builder.setPositiveButton("OK", null);

                    builder.create().show();
                } catch (IOException e) {
                    Toast.makeText(view.getContext(), "Fail to read file", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
});

3. Find and Overwrite File

findAndWriteButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Uri contentUri = MediaStore.Files.getContentUri("external");

        String selection = MediaStore.MediaColumns.RELATIVE_PATH + "=?";

        String[] selectionArgs = new String[]{Environment.DIRECTORY_DOCUMENTS + "/Kamen Rider Decade/"};    //must include "/" in front and end

        Cursor cursor = getContentResolver().query(contentUri, null, selection, selectionArgs, null);

        Uri uri = null;

        if (cursor.getCount() == 0) {
            Toast.makeText(view.getContext(), "No file found in \"" + Environment.DIRECTORY_DOCUMENTS + "/Kamen Rider Decade/\"", Toast.LENGTH_LONG).show();
        } else {
            while (cursor.moveToNext()) {
                String fileName = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME));

                if (fileName.equals("menuCategory.txt")) {                          //must include extension
                    long id = cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns._ID));

                    uri = ContentUris.withAppendedId(contentUri, id);

                    break;
                }
            }

            if (uri == null) {
                Toast.makeText(view.getContext(), "\"menuCategory.txt\" not found", Toast.LENGTH_SHORT).show();
            } else {
                try {
                    OutputStream outputStream = getContentResolver().openOutputStream(uri, "rwt");      //overwrite mode, see below

                    outputStream.write("This is overwritten data。\n你就不要想起我。".getBytes());

                    outputStream.close();

                    Toast.makeText(view.getContext(), "File written successfully", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    Toast.makeText(view.getContext(), "Fail to write file", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
});

Demo: https://www.youtube.com/watch?v=idsUMiWjfnM

Hope this may help you.

Leave a Comment