File saved to Download folder doesn't show up in "Downloads" app
Asked Answered
K

2

4

I'm trying to save a file to the Download folder. I get the directory and save the file using something like this:

File exportDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "");
if (!exportDir.exists()) {
    exportDir.mkdirs();
}
File file = new File(exportDir, "filename.csv");
try {
    if (file.exists()) {
        // if the file exists create new file will do nothing. We want to
        // overwrite contents every time
        file.delete();
    }
    boolean created = file.createNewFile();
    if (!created) {
        Log.d("", "Failed to create file");
    }

    // .. write to file

    MediaScannerConnection.scanFile(activity, new String[]{exportDir.getPath()}, null, null);
} catch (Exception sqlEx) {
    Log.e("MainActivity", sqlEx.getMessage(), sqlEx);
}

I've tested this on three devices:

  • OnePlus 3 (Android 8.0.0)
  • Blu Advance 5.0 (Android 5.1)
  • Samsung Galaxy S3 (Android 4.4.4)

On all devices if I navigate to /storage/sdcard0/Download or something of the like I can see my file there. HOWEVER if I try to open the native "Downloads" app I cannot see the file on the Blu or the Galaxy but I can see it on my OnePlus 3.

I have tried restarting the phones to trigger a media scan and have tried using MediaScannerConnection.scanFile to scan both the file and the folder with no luck. According to FileManager the file is -rw-rw---- just like most of the other files in that folder so what is going on here?

My goal is to save the file to a logical place where the user can easily find it and pull it off of their phone. Does the Downloads folder have special rules?

Any suggestions would be appreciated.

Kipp answered 2/2, 2018 at 23:33 Comment(1)
You code is ok but you are creating the file and deleting, check my answer.Fire
K
6

Does the Downloads folder have special rules?

The Downloads/ folder on external storage does not. The Downloads app does. The classic Downloads app is for files downloaded via DownloadManager, though that can be modified by device manufacturers as they see fit.

My goal is to save the file to a logical place where the user can easily find it and pull it off of their phone.

Downloads/ may or may not be the best place — it is not my first choice for something that the user is not explicitly downloading from an app.

UPDATE 2023-07-29: the storage rules are frightfully complicated now. I strongly recommend that you let the user choose where to save the content, via ACTION_CREATE_DOCUMENT / ActivityResultContracts.CreatedDocument or ACTION_OPEN_DOCUMENT_TREE / ActivityResultContracts.OpenDocumentTree.

Kopeisk answered 3/2, 2018 at 0:2 Comment(4)
Ok that makes sense & explains the behaviour. Since it is a file that the user will want to do retrieve I'm probably just going to use an ACTION_SEND intent to allow them to share it immediately rather than make them dig for it through the file system. Thank you!Kipp
@alexgophermix: Or, use the Storage Access Framework (ACTION_CREATE_DOCUMENT) and let them decide where to put it. That's the classic "save-as" sort of flow that people may be used to from desktop operating systems. Your use of ACTION_SEND as an option is fine, but do not assume that all users will have an ACTION_SEND activity that allows them to save the file on their device somewhere.Kopeisk
I've never tried ACTION_CREATE_DOCUMENT before - thanks for the heads upKipp
I am checking Download default app behaviour across API versions on emulators and it is odd. On Android 7 it doesn't show recently created file, on Android 9 file is shown, but could not be picked up, on Android 13 file is not shown at the first time, but become visible and available for pick up after emulator restart. It is possible to pick up this file over 3rd party file explorer, but at least on Android 13 it is not shown as choice for my action.Invent
F
-1

Be sure tu define the permission:

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

if you are using android 6.0+ you have to set the permission manually:

private void checkExternalStoragePermission() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        Log.i("Message", "OK.");
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 225);
    } else {
        Log.i("Message", "PERMISSION NOT SET!");
    }
}

You are checking if the file exists, but you are deleting the file!!!, this line is not neccesary :

file.delete();

  if (file.exists()) {
        // if the file exists create new file will do nothing. We want to
        // overwrite contents every time

       //***This is the problem: file.delete();
       Log.i("MainActivity", "File created and exists!");
    }
Fire answered 2/2, 2018 at 23:48 Comment(3)
I'm deleting it before I call this boolean created = file.createNewFile();. It's just to make sure the file is truly created from scratchKipp
@Kipp have you defined the permission WRITE_EXTERNAL_STORAGE?Fire
Yes. As mentioned the file is does manage to show up on the file system after the code runs. The issue is that it isn't always listed in the Downloads app depending on the OS.Kipp

© 2022 - 2024 — McMap. All rights reserved.