Nexus 4 未通过 MTP 显示文件
Posted
技术标签:
【中文标题】Nexus 4 未通过 MTP 显示文件【英文标题】:Nexus 4 not showing files via MTP 【发布时间】:2012-11-24 02:33:59 【问题描述】:我正在尝试简单地将一个简单的 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 文件管理器在手机上查看文件:
但 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】:似乎是known issue affecting Android USB file access over MTP。在手机重启之前,MTP 缓存会过期。
workaround 是:
清除“媒体存储”应用的数据 使用SDrescan 或SD Scanner(也适用于Android 4.4/5,适用于F-Droid)应用强制更新或者干脆避免使用 USB。该问题不会影响访问文件的其他方法。例如,尝试AirDroid 传输文件。
注意:这不适用于 Android 5.0.2:清除“媒体存储”并使用 SD Rescanner 后,这些文件夹在 Windows 7 中显示为无法打开的 4K 文件。此时唯一的解决方案是再次清除媒体存储并重新启动设备
【讨论】:
安装 SDrescan,运行它:修复!非常感谢 这种情况以前没有发生,但今天发生了。顺便说一句,我重新启动应该可以工作 IDK 为什么它不工作。 奇怪的是,重启手机3次后它确实出现了。 这不适用于 Android 5.0.2:清除“媒体存储”并使用 SD Rescanner 后,这些文件夹在 Windows 7 中显示为无法打开的 4K 文件。此时唯一的解决方案是再次清除媒体存储并重新启动设备。 这也不适用于 Nexus 7 Android 4.4.2。我的 Mac 报告我的自定义目录是 4k 文件。【参考方案2】:文件关闭后可以使用以下代码
MediaScannerConnection.scanFile(this, new String[] file.getAbsolutePath() , null, null);
来源: https://code.google.com/p/android/issues/detail?id=38282
【讨论】:
完美。这应该是这个问题的解决方案。 此解决方案不适用于我在连接到 Mac 的 Nexus 7、Android 4.4.2 上。我正在外部存储中创建一个新文件夹并将文件存储在该文件夹中。如果我只在文件夹中的文件上运行它,Mac 什么也不会显示。如果我还在我的新目录上运行它,Mac 会显示我的目录是 4k 文件(而不是目录)。我也试过打电话context.sendBroadcast()
没有效果。
我只是在标准下载目录中进行媒体扫描和广播文件,但在连接到 Mac 时它们从未出现过。
啊。这不能通过 onDestroy() 完成。如果我在其他地方做,它会起作用。我可以在创建文件时执行此操作,但桌面文件浏览器显示的大小为零。即便如此,当我复制文件时,它也会复制整个文件。
适用于 8.1。删除的文件只有在重新启动后才会消失。这样,至少写入的文件会立即出现在已挂载系统的文件浏览器中。【参考方案3】:
在这个问题上花了几个小时后,我这样解决了:
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);
【讨论】:
非常有用的答案,我能够递归地使用它,现在我可以通过 MTP 看到所有新创建的文件。无论如何,如何处理服务的解除绑定?我收到一个 ServiceConnectionLeaked 错误:“活动已泄漏 ServiceConnection android.media.MediaScannerConnection@42164d98,它最初绑定在此处”。关于如何解决它的任何想法,因为静态使用 MediaScannerConnection.scanFolder() 没有机会 disconnect() 绑定服务......【参考方案4】:对于accepted answer 中提到的错误,我发现的最佳解决方法是使用 SSH 将数据从 Android 操作系统复制到另一台机器/服务器(Linux、MacOS、Windows)。
确保设备 (Android) 和机器(您要复制数据的位置)可通过 IP 或主机名访问,例如将它们连接到同一个 wifi 网络。可选和推荐
使用 USB 网络共享连接安卓设备。由于有线连接,这确保了快速的速度,并保证了两个 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 不保证文件的完整性。如果断开连接,它会覆盖或跳过所有文件,因此其中一个文件可能不完整。其他协议可能难以安装,其他应用可能使用专有协议。【讨论】:
【参考方案5】:在 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
【讨论】:
【参考方案6】:注意/存储/模拟。 Android 4.2 有一些时髦的模拟每个应用程序/用户访问的东西,例如每个用户都有一个单独的 /sdcard/。尝试将文件移动到 /sdcard/ 而不是显示的模拟 sdcard。
【讨论】:
无论如何,一切都是指向/storage/emulated/legacy
的链接,它本身就是指向包含文件的/mnt/shell/emulated/0
的链接。【参考方案7】:
如果在我将文件放在外部存储上之后调用,则提出问题 How can I refresh MediaStore on Android? 的简单代码会执行必要的 MediaStore 更新。我的 Nexus 4 上的内容会立即在 Window 7 文件资源管理器中刷新。
【讨论】:
刚体验,可能最终会停止更新。【参考方案8】:我需要为我的应用创建一个目录并复制一些示例文件。经过大量的实验和研究,以下程序对我来说完美无缺:
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[] 数组来组合这两个调用,其中列出了文件和父项。另见***.com/a/25086535/911550【参考方案9】:我的 OneplusOne 也有类似的问题:
软件更新(到 6.0.1)后,我在连接到计算机(PTP 和 MTP)时无法看到我的相机照片。应用的 SDRescan 和 SDscanner 均无效。
我的解决方案是使用终端或手机上的任何文件资源管理器应用程序将所有图片从 DCIM 复制到另一个文件夹。连接到计算机时,我能够看到复制的文件..我将它们移动到我的计算机并清除了我的相机文件夹。没有永久的解决方案,但至少在我进行下一次备份之前,它为我解决了这个问题。 =D
【讨论】:
【参考方案10】:以上答案对于创建文件很好。如果您稍后删除该文件并希望也反映该更改,您可以执行以下操作之一;让我们首先介绍两种看似可行但会在某些设备上引起问题的解决方案。第一个是扫描删除的文件:
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
这适用于许多设备删除文件,但在某些设备上,它实际上会导致创建一个新的 0 字节文件,这可能不是您想要的。在这种情况下,如果你在
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(folder)));
其中文件夹等于 file.getParentFile()。不幸的是,在 KitKat 4.4 及更高版本上,这将导致抛出 SecurityException,因此对于这些设备,您可以尝试直接从媒体商店中删除:
final Uri externalFilesUri = Files.getContentUri("external");
context.getContentResolver().delete(externalFilesUri, Files.FileColumns.DATA + "=?", new String[] file.getAbsolutePath());
我已经测试了这个作为 ACTION_MEDIA_MOUNTED 在 KitKat 上不起作用的解决方法,它在我对 Nexus 5 的测试中起作用。
【讨论】:
【参考方案11】:最近我遇到了同样的问题,但一些额外的研究有助于找到隐藏文件。谷歌似乎在存储结构上做了一些改变。所有这些文件都被移动到另一个文件夹This Computer\HTC One\Internal Storage\storage\emulated\0
。但奇怪的是并非所有文件都被移动了。
Android 4.4.2
【讨论】:
【参考方案12】:从文档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);
);
【讨论】:
以上是关于Nexus 4 未通过 MTP 显示文件的主要内容,如果未能解决你的问题,请参考以下文章