Nexus 4无法通过MTP显示文件


80

我试图将一个简单的XML文件简单地写入SD卡,但我发现Nexus 4确实写入了该文件,但是使用Windows 7不能通过MTP协议查看该文件。

码:

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

我可以使用Astro File Manager在手机上看到文件:

屏幕截图

但是Windows看不到...:

屏幕截图

adb shell 在目录上显示:

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

Nexus 4怎么了?为什么要在Windows中隐藏我的东西?


1
我以为我做错了什么。现在我知道我并不孤单。
neverMind9 '19

Answers:


72

似乎是一个已知问题,会影响通过MTP的Android USB文件访问。MTP缓存会过期,直到手机重新启动。

一个解决办法是:

  • 清除“媒体存储”应用程序的数据
  • 使用SDrescanSD扫描仪(也适用于Android 4.4 / 5,在F-Droid上可用)应用程序强制进行更新

或者只是完全避免使用USB。该问题不会影响访问文件的其他方法。例如,尝试使用AirDroid传输文件。


注意:这不适用于Android 5.0.2:清除“媒体存储”并使用SD重新扫描器后,文件夹在Windows 7中显示为无法打开的4K文件。唯一的解决方案是再次清除媒体存储并重新启动设备


2
安装SDrescan,运行它:已修复!非常感谢
PiTheNumber

这以前没有发生过,但今天发生了。顺便说一句,我重新启动应该可以工作IDK为什么它不工作。
穆罕默德·巴巴尔

重新启动手机3次后,它确实出现了。
穆罕默德·巴巴尔

这不适用于Android 5.0.2:清除“媒体存储”并使用SD重新扫描器后,文件夹在Windows 7中显示为无法打开的4K文件。此时唯一的解决方案是再次清除媒体存储并重新启动设备。
安东尼奥

这在Nexus 7 Android 4.4.2上也不起作用。我的Mac报告我的自定义目录是4k文件。
乔·拉普

44

文件关闭后,您可以使用以下代码

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

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


11
完善。这应该是这个问题的解决方案。
Sorcerer 2014年

在连接到Mac的Nexus 7,Android 4.4.2上,该解决方案不适用于我。我正在外部存储中创建一个新文件夹,并将文件存储在该文件夹中。如果仅在文件夹中的文件上运行此程序,则Mac不会显示任何内容。如果我也在新目录上运行它,则Mac显示我的目录是4k文件(而不是目录)。我也曾尝试致电context.sendBroadcast()无效。
Joe Lapp 2015年

我只是在进行媒体扫描和广播在标准Downloads目录中创建的文件,而在连接到Mac时它们从未出现过。
Joe Lapp

啊。无法通过onDestroy()完成此操作。如果我在其他地方这样做,它会起作用。创建文件时可以执行此操作,但是桌面文件浏览器显示的大小为零。即使这样,当我复制文件时,它也会复制整个文件。
Joe Lapp

适用于8.1。仅在重新启动后,已删除的文件才会消失。这样,至少写入的文件会立即显示在已安装系统的文件浏览器中。
Midson

5

在这个问题上花了几个小时后,我这样解决了:

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

问题是您只需要扫描文件(而不是文件夹),然后对每个文件夹进行递归重复

编辑 此外,如果您不希望将图片添加到相册中(而是仅将内容通过mtp协议显示),请记住.nomedia在重新扫描之前将一个空文件放在文件夹中,如下所示:

new File(myFolder + File.separator + ".nomedia").createNewFile();
rescanFolder(myFolder);

非常有用的答案,我能够递归使用它,现在我可以通过MTP看到所有新创建的文件。无论如何,如何处理服务的取消绑定?我收到ServiceConnectionLeaked错误:“活动泄漏了最初绑定在此处的ServiceConnection android.media.MediaScannerConnection@42164d98”。自从静态使用MediaScannerConnection.scanFolder()以来,关于如何解决它的任何想法都没有机会断开()绑定的服务...
Andre

3

在Xperia Z上,以下代码可以正常工作:

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

适用于4.4+:

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

(不幸的是,我不记得我是否对它进行了足够的测试)

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


3

对于所接受的答案中提到的错误,我发现的最佳解决方法是使用SSH将数据从Android OS复制到另一台计算机/服务器(Linux,MacOS,Windows)。

  • 确保按IP或主机名可访问设备(Android)和计算机(要在其中复制数据),例如,通过将它们连接到相同的wifi网络。

可选和推荐

  • 使用USB共享网络连接android设备。由于采用了有线连接,因此可以确保速度较快,并且由于两个IP地址都在同一网络中,因此可以确保两个IP地址彼此可见。

在Android设备中

  • 安装SSH服务器。SSHelper就像魅力一样
  • 运行SSHelper并转到“配置”选项卡以获取IP地址,端口和密码。在下面的示例中,它们是192.168.1.5、2222和'admin'。
  • 默认密码是admin,但是如果您决定更改密码,请在更改密码后点击“使用新值重新启动服务器”按钮。

在机器上

  • 安装rsync。如果碰巧使用Ubuntu,则默认情况下已安装它。
  • 打开一个外壳,然后键入以下命令。将IP地址和端口更改为您的值

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

  • 您将收到以下提示,输入密码

SSHelper Version 8.5 Copyright 2014, P. Lutus Default password is "admin" (recommend: change it) username@192.168.1.5's password: admin receiving incremental file list

其他建议对我不起作用:

  • 该设备(与许多其他较新的设备一样)不支持使用USB存储模式代替MTP。
  • 我的操作系统(Android 6.0.1)中没有选项来清除“媒体存储”应用程序数据。
  • 通过网络共享文件的其他方法也有缺点。FTP无法确保文件的完整性。如果断开连接,它会覆盖或跳过所有文件,因此其中一个文件可能不完整。其他协议可能很难安装,其他应用程序可能使用专有协议。

2

通知/存储/模拟。Android 4.2正在进行一些时髦的,按应用程序/用户访问的模拟操作,例如,针对每个用户的单独的/ sdcard /。尝试将文件移动到/ sdcard /而不是显示的模拟sdcard。


11
一切都是到/storage/emulated/legacy任何地方的链接,本身就是/mnt/shell/emulated/0包含文件的链接。
moonlightcheese


1

我需要创建一个目录并为我的应用程序复制一些示例文件。经过大量的实验和研究,以下过程对我而言是完美的:

1)使用File.mkdir()创建目录。

2)复制目录中的文件,并在每个文件上运行MediaScanner。

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

3)在目录上运行MediaScanner。

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

结果:文件和目录通过MTP即时显示在PC上。


扫描目录创建的特定文件都对我有用。您还可以通过准备包含两个元素(同时列出文件和父对象)的String []数组来组合两个调用。另请参阅stackoverflow.com/a/25086535/911550
parvus

1

我的OneplusOne也有类似的问题:

在软件更新(至6.0.1)之后,连接到计算机(PTP和MTP)时,我看不到相机的照片。应用程序的SDRescan和SDscanner均无效。

我的解决方案是使用终端或手机上的任何文件资源管理器应用程序将所有图片从DCIM复制到另一个文件夹。连接到计算机时,我能够看到复制的文件。.我将它们移至计算机,并清除了我的相机文件夹。没有永久性的解决方案,但它至少在我进行下一次备份之前为我解决了该问题。= D


0

上面的答案对于创建文件是很好的。如果以后删除该文件并希望也能反映出该更改,则可以执行以下操作之一;让我们首先介绍看似可行的两个解决方案,但它们会在某些设备上引起问题。第一个是扫描已删除的文件:

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

这在许多用于删除文件的设备上都有效,但是在某些设备上,它实际上会导致创建一个新的0字节文件,这可能不是您想要的。在这种情况下,如果您在<4.4 KitKat上运行,则可以执行以下操作:

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

其中folder等于file.getParentFile()。不幸的是,在KitKat 4.4及更高版本上,这将引发SecurityException,因此对于这些设备,您可以尝试直接从Media Store中删除:

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

我已经测试了这一解决方法,以解决ACTION_MEDIA_MOUNTED无法在KitKat上运行的问题,并且可以在Nexus 5上进行测试。


0

最近,我遇到了同样的问题,但是一些其他研究帮助找到了隐藏文件。Google似乎对存储结构进行了一些更改。所有这些文件都移到了另一个文件夹This Computer\HTC One\Internal Storage\storage\emulated\0。但是奇怪的是,并不是所有文件都被移动了。

Android 4.4.2


0

此处的文档中,您需要调用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);
    }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.