35

I'm trying to save pictures in a subfolder on Android. Here's a bit of my code:

File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
path = new File(path, "SubDirName");
path.mkdirs();

(I've tried getExternalStorageDirectory instead of getExternalStoragePublicDirectory and the Pictures folder instead of DCIM.)

Any subfolder I add, including its contents, don't show up in Windows Explorer when the device is connected via USB. It does show in the Android File Manager, though.

I've tried broadcasting the ACTION_MEDIA_MOUNTED intent on the new directory's parent. It didn't work.

If I add a file in Windows, it shows up on Android. If I add a file on Android via the File Manager, it shows up in Windows. If I add the file programmatically, it shows up on the Android File Manager, but not in Windows Explorer. And I need to get it from Windows, and I don't want the final user to have to create the folder manually.

What am I doing wrong?

4

8 回答 8

62

I faced the same issue and rebooting either the Android device or the PC is not a practical solution for users. :)

This issue is through the use of the MTP protocol (I hate this protocol). You have to initiate a rescan of the available files, and you can do this using the MediaScannerConnection class:

// Snippet taken from question
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
path = new File(path, "SubDirName");
path.mkdirs();

// Initiate a media scan and put the new things into the path array to
// make the scanner aware of the location and the files you want to see
MediaScannerConnection.scanFile(this, new String[] {path.toString()}, null, null);
于 2013-11-12T16:06:53.563 回答
5

The way used in Baschi's answer doesn't always work for me. Well, here is a full solution.

// Snippet taken from question
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
path = new File(path, "SubDirName");
path.mkdirs();

// Fix
path.setExecutable(true);
path.setReadable(true);
path.setWritable(true);

// Initiate media scan and put the new things into the path array to
// make the scanner aware of the location and the files you want to see
MediaScannerConnection.scanFile(this, new String[] {path.toString()}, null, null);
于 2015-06-07T18:46:03.277 回答
3

The only thing that worked for me was this:

Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri fileContentUri = Uri.fromFile(path);
mediaScannerIntent.setData(fileContentUri);
this.sendBroadcast(mediaScannerIntent);

Credit to https://stackoverflow.com/a/12821924/1964666

于 2016-09-10T13:38:41.347 回答
1

None of the above helped me, but this worked: The trick being to NOT scan the new folder, but rather create a file in the new folder and then scan the file. Now Windows Explorer sees the new folder as a true folder.

    private static void fixUsbVisibleFolder(Context context, File folder) {
    if (!folder.exists()) {
        folder.mkdir();
        try {
            File file = new File(folder, "service.tmp");//workaround for folder to be visible via USB
            file.createNewFile();
            MediaScannerConnection.scanFile(context,
                    new String[]{file.toString()},
                    null, (path, uri) -> {
                        file.delete();
                        MediaScannerConnection.scanFile(context,
                                new String[]{file.toString()} ,
                                null, null);
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Thanks to https://issuetracker.google.com/issues/37071807#comment90

You also should scan every created file in the directory analogically:

   private static void fixUsbVisibleFile(Context context, File file) {
    MediaScannerConnection.scanFile(context,
            new String[]{file.toString()},
            null, null);
}
于 2020-10-09T11:18:32.990 回答
0

If you add the folder to the SD card from the PC directly to the card through the card reader, it will not show in Windows Explorer when connected with the phone.

The solution is to copy or move the same folder using the Android file manager program and then it will be listed in the SD card index when connected to the PC.

于 2013-06-11T07:11:34.877 回答
0

It's work fine for me.

MediaScannerConnection.scanFile work if there is file in directory (not directory)

private fun checkMTPFolder(f: File, context: Context) {
   if (f.isDirectory) {
      val newFilePath = f.absolutePath + "/tempFIle"
      val newFile = File(newFilePath)
      newFile.mkdir()

      MediaScannerConnection.scanFile(context, arrayOf(newFilePath), null, object : MediaScannerConnection.OnScanCompletedListener {
                override fun onScanCompleted(p0: String?, p1: Uri?) {
                    val removedFile = File(p0)
                    removedFile.delete()
                    MediaScannerConnection.scanFile(context,arrayOf(removedFile.absolutePath), null, null)
                }

            })
   }
}
于 2020-01-17T09:28:01.807 回答
-1

I have solved this problem by toggling the phone setting:

  1. After a directory is created and/or a file saved, change from (MTP) mode to USB (SD card) mode for a moment, wait for the SD card mounting on the PC, so the directory and file will be shown.

  2. Turn back to (MTP) mode again where the last file still shows up.

  3. When re-saving a file, you have to change to USB again to see it.

于 2016-08-05T09:45:32.263 回答
-2

Just create the directory on the PC first, and then copy it over to the SD card/phone storage.

You can either put in the contents into the folder first and copy over or just the folder first. As long as the folder is created from the PC, any content can just be copied directly to internal/external mobile devices. For zipped content, it cannot be directly unzipped and copied over unfortunately; you need to unzip them first.

于 2017-11-02T17:24:45.590 回答