Why this Code for saving text to a file in downloads folder not working (Android Q)?

from the CommonsWare Community archives

At March 28, 2020, 5:49pm, root-ansh asked:

(Hi commonsware!) I tried to follow your Android Q recommended code for saving a file (This one) Since you had written the code to write a video file, i tweaked according to other sources(SO)

  public void downLoad(Context ctx,String filename, String data) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            downloadQ(ctx, filename,data);
        }
        else {
            downLoadCompat(ctx,filename,data);
        }
    }

    @RequiresApi(Build.VERSION_CODES.Q)
    private void downloadQ(Context ctx,String fileName, String data) {
        Log.e(TAG, "downloadQ: Android Q version ran" );
        ContentValues myContentValues = new ContentValues();
        myContentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
        String myFolder =  "Download/downloadQ2";
        myContentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, myFolder);
        myContentValues.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain");
        myContentValues.put(MediaStore.MediaColumns.IS_PENDING,1);

        Uri extVolumeUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);

        ContentResolver contentResolver =  ctx.getContentResolver();
        Uri uri = contentResolver.insert(extVolumeUri,myContentValues);

        if(uri==null){
            Log.e(TAG, "downloadQ: uri is null, quitting operation and returning" );
            return;
        }
        Log.e(TAG, "downloadQ: uri="+uri );

        try {
            FileOutputStream fos = new FileOutputStream(new File(uri.toString()));
//                    ctx.openFileOutput(uri.toString(), Context.MODE_PRIVATE);//try with uri.getPath()
            fos.write(data.getBytes());
            fos.close();
        }
        catch (Exception e) {
            Log.e(TAG, "downloadQ: error occurred"+e.getMessage() );
            e.printStackTrace();
        }
        finally {
            myContentValues.clear();
            myContentValues.put(MediaStore.MediaColumns.IS_PENDING,0);
            contentResolver.update(uri,myContentValues,null,null);
        }

    }

initially it was giving an error “android file contains a path separator” when i was using openFileOutput() but then again changed accordingly based on this answer here, but now it isn’t even giving uri. its simply going into my null uri block and execution stops there.

Can you (or anyone else ) please take a look?


At March 28, 2020, 6:08pm, mmurphy replied:

In this blog post, I demonstrate this sample app, which downloads to MediaStore.Downloads. You are trying to use MediaStore.Files, and that may not work.

Also, a Uri is not a file. You cannot use FileOutputStream to write to a Uri. Please use openOutputStream() on ContentResolver, as shown in the example that you cited, the sample app that I linked to earlier, etc.