Nexus 4没有通过MTP显示文件

问题描述 投票:75回答:12

我正在尝试简单地将一个简单的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文件管理器在手机上看到该文件:

Screenshot

但Windows没有看到它......:

Screenshot

目录中的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隐藏我的东西?

android usb-drive nexus-4 mtp
12个回答
69
投票

似乎是一个known issue affecting Android USB file access over MTP。 MTP缓存已过期,直到重新启动手机。

一个workaround是:

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

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


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


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
投票

最近我面临同样的问题,但一些额外的研究帮助找到隐藏的文件。谷歌似乎已经对存储结构做了一些改变。所有这些文件都被移动到另一个文件夹This Computer\HTC One\Internal Storage\storage\emulated\0。但奇怪的是并非所有文件都被移动了。

Android 4.4.2


0
投票

从文档here,您需要调用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);
    }
});

43
投票

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

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

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


4
投票

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

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

问题是你必须只扫描文件(而不是文件夹),然后为每个fubfolder递归重复

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

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

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


2
投票

通知/存储/模拟。 Android 4.2有一些时髦的模拟每个应用程序/用户访问的东西,例如每个用户单独的/ SD卡/。尝试将文件移动到/ sdcard /而不是显示的模拟SD卡。


2
投票

提问How can I refresh MediaStore on Android?的简单代码会对MediaStore进行必要的更新,如果我将文件放在外部存储器上后调用的话。我的Nexus 4上的内容会立即在Window 7文件资源管理器中刷新。


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

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


1
投票

与我的Oneplus One有类似的问题:

软件更新(至6.0.1)后,我无法在连接到计算机(PTP和MTP)时看到我的相机图片。应用程序的SDRescan和SDscanner都没有效果。

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


1
投票

我发现accepted answer中提到的bug的最佳解决方法是使用SSH将数据从Android OS复制到另一台机器/服务器(Linux,MacOS,windows)。

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

可选和推荐

  • 使用USB网络共享连接Android设备。由于有线连接,这可确保快速,并确保两个IP地址彼此可见,因为两者都在同一网络中。

在Android设备中

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

在机器上

  • 安装rsync。如果碰巧使用Ubuntu,它已经默认安装。
  • 打开shell并键入以下命令。将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) [email protected]'s password: admin receiving incremental file list

其他建议对我不起作用:

  • 设备不支持使用USB存储模式而不是MTP(与许多其他更新的设备一样)。
  • 我的操作系统(Android 6.0.1)中没有选项可以清除“媒体存储”应用数据。
  • 通过网络共享文件的其他方法有其缺点。 FTP无法确保文件的完整性。如果连接被删除,它将覆盖或跳过所有文件,因此其中一个文件可能不完整。其他协议可能难以安装,其他应用程序可能使用专有协议。
© www.soinside.com 2019 - 2024. All rights reserved.