文件保存到下载文件夹后在“下载”应用程序中不显示。

4

我正在尝试将文件保存到下载文件夹。我获取了目录并使用以下方式保存文件:

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);
}

我已经在三台设备上测试过了:
  • OnePlus 3(Android 8.0.0)
  • Blu Advance 5.0(Android 5.1)
  • Samsung Galaxy S3(Android 4.4.4)
在所有设备上,如果我导航到 /storage/sdcard0/Download 或类似的地方,我可以看到我的文件。但是,如果我尝试打开原生的“下载”应用程序,则在 Blu 或 Galaxy 上无法看到该文件,但我可以在 OnePlus 3 上看到它。
我已经尝试重新启动手机来触发媒体扫描,并尝试使用 MediaScannerConnection.scanFile 扫描文件和文件夹,但没有成功。根据 FileManager,该文件与该文件夹中的大多数其他文件一样为 -rw-rw----,那么这里到底发生了什么?
我的目标是将文件保存到一个逻辑位置,用户可以轻松找到并从其手机中取出。下载文件夹有特殊规则吗?
欢迎提出任何建议。

你的代码没问题,但是你正在创建文件并删除它,请检查我的答案。 - Jorgesys
2个回答

6
下载文件夹有特殊规定吗?
外部存储的Downloads/文件夹没有特殊规定。但是Downloads应用程序有。经典的Downloads应用程序用于通过DownloadManager下载的文件,尽管设备制造商可以根据需要进行修改。
我的目标是将文件保存在用户可以轻松找到并从手机上取出的逻辑位置。
Downloads/可能不是最佳选择,对于用户不是通过应用程序明确下载的内容,这不是我的首选。
2023-07-29更新:存储规则现在非常复杂。我强烈建议您让用户通过ACTION_CREATE_DOCUMENT / ActivityResultContracts.CreatedDocument或ACTION_OPEN_DOCUMENT_TREE / ActivityResultContracts.OpenDocumentTree选择保存内容的位置。

好的,这解释得通,并且能够解释行为。由于这是用户希望检索的文件,我可能会使用 ACTION_SEND 意图,让他们立即分享它,而不是让他们在文件系统中搜索。谢谢! - alexgophermix
1
@alexgophermix:或者使用存储访问框架(ACTION_CREATE_DOCUMENT),让用户决定将文件放在哪里。这是人们可能从桌面操作系统中习惯的经典“另存为”流程。您提供 ACTION_SEND 作为选项是可以的,但不要假设所有用户都有一个 ACTION_SEND 活动,可以让他们将文件保存在设备上的某个地方。 - CommonsWare
我以前从未尝试过ACTION_CREATE_DOCUMENT - 感谢您的提醒。 - alexgophermix
我正在检查模拟器上不同API版本中的默认应用下载行为,结果很奇怪。在Android 7上,它不显示最近创建的文件;在Android 9上,文件显示出来,但无法选取;在Android 13上,文件一开始没有显示,但在重新启动模拟器后变得可见且可供选择。可以通过第三方文件管理器选择此文件,但至少在Android 13上,它不作为我的操作选择显示。 - Gleichmut

-1

请确保定义权限:

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

如果您使用的是Android 6.0+,则必须手动设置权限:

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!");
    }
}

你正在检查文件是否存在,但是你却删除了这个文件!!!这行代码是不必要的:

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!");
    }

在调用 boolean created = file.createNewFile(); 之前,我将其删除。这只是为了确保文件是从头创建的。 - alexgophermix
@alexgophermix,你定义了WRITE_EXTERNAL_STORAGE权限吗? - Jorgesys
是的。如上所述,代码运行后文件确实能够在文件系统中显示出来。问题在于,根据操作系统的不同,它并不总是会在“下载”应用程序中列出。 - alexgophermix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接