Nexus 4 not showing files via MTP
Asked Answered
J

12

80

I'm trying to simply write a simple XML file to the SD card and I noticed that my Nexus 4 does write the file, but it is not viewable via the MTP protocol using Windows 7.

code:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    CustomerQueryRqType customerQueryRequest = new CustomerQueryRqType();
    Serializer serializer = new Persister();
    File myFile = new File(Environment.getExternalStorageDirectory() + "/customerQueryRequest.xml");

    try {
        boolean created = myFile.createNewFile();
        serializer.write(customerQueryRequest, myFile);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

I can see the file on the phone itself with Astro File Manager:

Screenshot

but Windows doesn't see it...:

Screenshot

adb shell on the directory shows:

ls -l
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Alarms
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Android
drwxrwxr-x root     sdcard_rw          2012-11-21 19:30 DCIM
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Download
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Movies
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Music
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Notifications
drwxrwxr-x root     sdcard_rw          2012-11-19 12:06 Pictures
drwxrwxr-x root     sdcard_rw          1970-01-16 20:51 Podcasts
drwxrwxr-x root     sdcard_rw          2012-11-19 13:22 Ringtones
drwxrwxr-x root     sdcard_rw          2012-11-19 14:33 bluetooth
-rw-rw-r-- root     sdcard_rw       79 2012-12-05 22:26 customerQueryRequest.xml
drwxrwxr-x root     sdcard_rw          2012-11-20 02:50 data
-rw-rw-r-- root     sdcard_rw    11394 2012-11-19 13:54 eightpen_custom_gestures
drwxrwxr-x root     sdcard_rw          2012-11-19 13:17 media

What's going on with my Nexus 4? Why is it hiding my things from Windows?

Jeane answered 6/12, 2012 at 5:2 Comment(0)
M
72

Seems to be a known issue affecting Android USB file access over MTP. The MTP cache gets out of date until a reboot of the phone.

A workaround is:

  • Clear the "Media Storage" app's data
  • Use the SDrescan or the SD Scanner (also works on Android 4.4/5, available on F-Droid) app to force an update

Or just avoid using USB at all. The issue does not affect other methods of accessing the files. For example, try AirDroid to transfer files.


Note: This doesn't work for Android 5.0.2: After clearing "Media Storage" and using an SD Rescanner, the folders appears in Windows 7 as unopenable 4K files. The only solution at that point is to clear once again Media Storage and restart the device

Methodize answered 28/12, 2012 at 19:2 Comment(6)
Install SDrescan, run it: fixed! Thanks a lotBenford
This wasn't happening before but today did. BTW i reboot should work IDK why it's not working.Lewis
Its strange after rebooting the phone for 3 times it did appeared up.Lewis
This doesn't work for Android 5.0.2: After clearing "Media Storage" and using an SD Rescanner, the folders appears in Windows 7 as unopenable 4K files. The only solution at that point is to clear once again Media Storage and restart the device.Bosomy
This also did not work on Nexus 7 Android 4.4.2. My Mac is reporting that my custom directory is a 4k file.Sandstrom
But it does work when I put my files in a standard directory.Sandstrom
S
44

You can use the following code after file close

MediaScannerConnection.scanFile(this, new String[] { file.getAbsolutePath() }, null, null);

Source: https://code.google.com/p/android/issues/detail?id=38282

Smear answered 6/12, 2013 at 0:47 Comment(4)
This solution is not working for me on a Nexus 7, Android 4.4.2, connecting to a Mac. I am creating a new folder in external storage and storing files in that folder. If I only run this on the files in the folder, the Mac shows nothing. If I also run it on my new directory, the Mac shows that my directory is a 4k file (and not a directory). I have also tried calling context.sendBroadcast() to no effect.Sandstrom
I just played around with doing media scans and broadcasting files created in the standard Downloads directory, and they never showed up when connecting to the Mac.Sandstrom
Ah. This can't be done from onDestroy(). It works if I do it elsewhere. I can do it at the time I create the file, but then the desktop file browser shows a size of zero bites. Even so, when I copy the file over, it copies over the whole file.Sandstrom
Works with 8.1. Deleted files disappearing only after reboot. With this, atleast written files appear immediately on File Browser of the Mounted System.Gillies
T
5

After spending hours on this issue I solved like this:

private void rescanFolder(String dest) {
    // Scan files only (not folders);
    File[] files = new File(dest).listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isFile();
        }
    });

    String[] paths = new String[files.length];
    for (int co=0; co< files.length; co++)
        paths[co] = files[co].getAbsolutePath();

    MediaScannerConnection.scanFile(activity, paths, null, null);

    // and now recursively scan subfolders
    files = new File(dest).listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isDirectory();
        }
    });

    for (int co=0; co<files.length; co++)
        rescanFolder(files[co].getAbsolutePath());
} 

The thing is that you have to scan files only (not folders) and then repeat recursively for each fubfolder

EDIT In addition, if you don't want pictures to be added to your photo album (but just your contents to appear over mtp protocol), remember to place an empty .nomedia file in your folder before rescanning it, like this:

new File(myFolder + File.separator + ".nomedia").createNewFile();
rescanFolder(myFolder);
Trotman answered 5/12, 2014 at 17:32 Comment(1)
Very useful answer, I was able to use it recursively and now I see all the newly created files over MTP. Anyway, how to deal with the unbind of the service? I get a ServiceConnectionLeaked error: "Activity has leaked ServiceConnection android.media.MediaScannerConnection@42164d98 that was originally bound here". Any idea about how to solve it since using MediaScannerConnection.scanFolder() statically there's no chance to disconnect() the bound service...Smutchy
T
4

The best workaround I found to the bug mentioned in the accepted answer is to copy data from Android OS to a another machine/server (Linux, MacOS, windows) using SSH.

  • Make sure that the device (Android) and the machine (where you want to copy the data) are reachable per IP or host name, for example by connecting them to the same wifi network.

Optional and recommended

  • Connect the android device using USB tethering. This ensures fast speed because of the wired connection and guarantees that both IP addresses are visible to each other because both are in the same network.

In the Android device

  • Install an SSH server. SSHelper worked like a charm
  • Run the SSHelper and go to the configuration tab to get the IP address, port, and password. In the example below, they are 192.168.1.5, 2222 and 'admin'.
  • The default password is admin but if you decide to change it hit the button "Restart server with new values" after changing it

In the machine

  • Install rsync. If happen to use Ubuntu it is already installed by default.
  • Open a shell and type the following command. Change the IP address and port to your values

rsync -avzhP --inplace --info=progress2 -e 'ssh -p 2222' 192.168.1.5:/storage/emulated/0/DCIM/Camera/ /home/username/path/to/pics/

  • you will get the following prompt, enter your password

SSHelper Version 8.5 Copyright 2014, P. Lutus Default password is "admin" (recommend: change it) [email protected]'s password: admin receiving incremental file list

The other suggestions did not work for me:

  • Using USB storage mode instead of MTP is not supported by the device (as many other newer devices).
  • There was no option in my OS (Android 6.0.1) to clear the "Media Storage" app data.
  • Other methods of sharing files over the network had their draw backs. FTP does not ensure the files integrity. If the connection is dropped it either overwrites or skips all files, so one of the files might be incomplete. Other protocols might be hard to install and other apps might use proprietary protocols.
Trousers answered 25/12, 2016 at 12:35 Comment(0)
S
3

On Xperia Z below code worked just fine:

  String screenShotFile = "....";
  activity.sendBroadcast(new Intent(
        Intent.ACTION_MEDIA_MOUNTED, Uri
                .fromFile(screenShotFile)));

for 4.4+ use:

activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                                Uri.fromFile(screenShotFile)));

(unfortunalelly I dont remember if I have tested it well enough)

http://commonsware.com/blog/2013/11/06/android-4p4-permission-regressions.html

Sappy answered 29/7, 2013 at 17:24 Comment(0)
H
2

notice /storage/emulated. Android 4.2 has some funky emulated per-app/user access stuff going on, for example a separate /sdcard/ for each user. Try moving the file to /sdcard/ instead of the emulated sdcard that is shown.

Hurleigh answered 7/12, 2012 at 2:43 Comment(1)
everything is a link to /storage/emulated/legacy anyway, which itself is a link to /mnt/shell/emulated/0 which contains the file.Jeane
W
2

The simple code proposed to question How can I refresh MediaStore on Android? does the necessary update of MediaStore, if called after I put a file on external storage. Content on my Nexus 4 is refreshed instantly in Window 7 file explorer.

Woodford answered 3/7, 2013 at 12:13 Comment(1)
Just experienced, that it might stop updating eventually.Woodford
M
1

I needed to create a directory and copy some sample files for my app. After a lot of experiments and research the following procedure worked flawlessly for me:

1) Created directory using File.mkdir().

2) Copied files in directory and run MediaScanner on each file.

MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, null, null);

3) Run MediaScanner on directory.

MediaScannerConnection.scanFile(context, new String[]{directory.getAbsolutePath()}, null, null);

Result: The files and directory appear instantaneously on PC over MTP.

Madel answered 19/7, 2015 at 4:22 Comment(1)
Scanning both the directory and the specific file created worked for me. You can also combine the two calls by preparing a String[] array of two elements where both the file and the parent are listed. See also https://mcmap.net/q/145553/-trigger-mediascanner-on-specific-path-folder-how-toCaeoma
V
1

Had a similar issue with my OneplusOne:

After software update (to 6.0.1) i was not able to see my camera pictures when connecting to the computer (PTP and MTP). Both app's SDRescan and SDscanner had no effect.

My solution was to copy all pictures from DCIM to another folder using terminal or any file Explorer app on the Phone. When connecting to computer i was able to see the copied files.. i moved them to my computer and cleared my camera folder. No permanent solution but it fixed the problem for me at least until i do the next backup. =D

Voyeurism answered 16/8, 2016 at 12:5 Comment(0)
R
0

The above answers are fine for creating the file. If you later delete the file and want that change to be reflected as well, you can do one of the following; let's first cover two solutions that seem like they work, but will cause problems on some devices. The first one is to scan the deleted file:

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));

This works on many devices for deleted files, but on some devices it'll actually cause a new 0-byte file to be created, which probably isn't what you want. In that case, if you're running on < 4.4 KitKat, you can do this:

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(folder)));

Where folder is equal to file.getParentFile(). Unfortunately, on KitKat 4.4 and above, this will cause a SecurityException to get thrown, so for those devices, you can try deleting directly from the Media Store:

final Uri externalFilesUri = Files.getContentUri("external");
context.getContentResolver().delete(externalFilesUri, Files.FileColumns.DATA + "=?", new String[] {file.getAbsolutePath()});

I've tested this one as a workaround for ACTION_MEDIA_MOUNTED not working on KitKat, and it works in my testing on the Nexus 5.

Reorganization answered 20/2, 2014 at 19:52 Comment(0)
E
0

Recently I faced with the same problem but some additional research helped find hidden files. It seems that Google has made some changes in storage structure. All these files were moved to another folder This Computer\HTC One\Internal Storage\storage\emulated\0. But it's strange that not all files were moved.

Android 4.4.2

Erickson answered 30/5, 2014 at 5:23 Comment(0)
C
0

From the documentation here, you need to call MediaScannerConnection.scanFile :

// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this,
        new String[] { file.toString() }, null,
        new MediaScannerConnection.OnScanCompletedListener() {
    public void onScanCompleted(String path, Uri uri) {
        Log.i("ExternalStorage", "Scanned " + path + ":");
        Log.i("ExternalStorage", "-> uri=" + uri);
    }
});
Chromyl answered 29/12, 2017 at 22:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.