36

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
eje211
  • 2,385
  • 3
  • 28
  • 44
  • 2
    I've also seen this behavior in samsung devices. There is no problem in your code. It is the behavior of Samsung USB drivers. Plugout and Plugin the USB again, the directory will start showing up. – PC. Nov 22 '12 at 07:41
  • 1
    Thanks for the advice, PC. I thought of that too. This is an ASUS Transformer, though. I tried plugging out and back in and that didn't work. – eje211 Nov 22 '12 at 07:44
  • 1
    if the folders are visible in Android File Manager, then according to me its USB's problem and not your code's issue. – PC. Nov 22 '12 at 07:46
  • 1
    You have to use getExternalStoragePublicDirectory else it wont be available outside the device. – kittu88 Nov 22 '12 at 07:55
  • @eje211 did you find a solution to this? I'm facing the same issue. – Hades Apr 03 '13 at 03:51
  • 3
    the issue was with the mtp protocol...just restart the phone and it shows up – Hades Apr 03 '13 at 12:28
  • @Hades restart works? having same problem... but my app is used on someone else tablet, so I can't check it myself. – Flash Thunder Mar 31 '14 at 20:11
  • @FlashThunder yes it worked...it was on a nexus 7 though.. – Hades Mar 31 '14 at 20:32
  • Everyone answering seems to know, but where is this code you're all talking about, and what language is it in? It's syntax is mostly C-like (unlike Python or Bash), but I don't think it's C and a lot of languages have C-like syntax. – H. H. Mar 14 '23 at 01:16
  • Also, for readers' reference, restarting the cell phone (after unmounting it and followed by remounting it of course) did fixed the problem for me using Thunar on Ubuntu 20.04.5 LTS to access an Android 8.1.0 phone's "Internal Storage" (which I think is /sdcard, but anyway is the only thing that shows up via USB). – H. H. Mar 14 '23 at 01:31

8 Answers8

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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Baschi
  • 1,128
  • 11
  • 14
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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
raziEiL
  • 77
  • 2
  • 6
  • 1
    Just a little comment: instead of saying _This way don't work sometimes for me_ you could say _[Baschi's proposed solution ](http://stackoverflow.com/a/19934089/4453460) doesn't work sometimes for me_ instead (just to be more clear). – lfurini Jun 07 '15 at 18:58
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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Luigi04
  • 437
  • 5
  • 14
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);
}
Daniil Andashev
  • 154
  • 1
  • 9
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ehabth
  • 1
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)
                }

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131