不一致的 MediaConnection 行为,某些文件未显示在 Android 文件传输中
Inconsistent MediaConnection behaviour, some files don't show in Android File Transfer
我有一个外部存储文件的目录结构。它们没有出现在 Android 文件传输应用程序中,因此我认为这是媒体扫描仪的问题。
我在基于 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
.
的目录中使用 FileOutputStream
创建它们
我有以下方法,从 activity 调用,所以 context
是一个 activity(暂时忘记这会阻塞主线程!):
public void scan(Context context, File base) {
File[] files = base.listFiles();
if (files == null) {
return;
} else {
for (File file : files) {
if (file.isFile()) {
String path = file.getAbsolutePath();
MediaScannerConnection.scanFile(context, new String[]{path}, null, null);
Log.e("Langstroth", path);
} else if (file.isDirectory()) {
this.scan(context, file);
}
}
}
}
public void scan(Context context) {
this.scan(context, this.baseDir);
}
}
日志的输出符合预期:
E/MyApp﹕ /storage/emulated/0/Documents/Langstroth/sample/5000/1430576404874.wav
E/MyApp﹕ /storage/emulated/0/Documents/Langstroth/sample/5000/1430577209491.wav
然后很多:
E/MyApp﹕ Scan completed path /storage/emulated/0/Documents/Langstroth/sample/5000/1430576404874.wav uri content://media/external/audio/media/7836
E/MyApp﹕ Scan completed path /storage/emulated/0/Documents/Langstroth/sample/5000/1430577209491.wav uri content://media/external/audio/media/7838
这证明文件存在。不过,它们不会出现在 Android 文件传输中。
奇怪的是。另一种方法:
public void otherDemo(Context context, File baseDir) {
String newPath = baseDir.getAbsolutePath() + "/some/random/dirs";
Log.e("Langstroth", "New path " + newPath);
File dir = new File(newPath);
dir.mkdirs();
Log.e("Langstroth", dir.exists() ? "Dir exists": "Dir does not exist");
File f = new File(dir, "myfile.txt");
try {
new BufferedOutputStream(new FileOutputStream(f)).close();
} catch (IOException e) {
e.printStackTrace();
}
Log.e("Langstroth", f.exists() ? "File exists": "File does not exist");
MediaScannerConnection.scanFile(context, new String[]{f.getAbsolutePath()}, null, null);
}
和日志输出:
E/MyApp﹕ New path /storage/emulated/0/Documents/Langstroth/some/random/other/dirs
E/MyApp﹕ Dir exists
E/MyApp﹕ File exists
E/MyApp﹕ File: /storage/emulated/0/Documents/Langstroth/some/random/other/dirs/myfile.txt
E/MyApp﹕ Other scan completed path /storage/emulated/0/Documents/Langstroth/some/random/other/dirs/myfile.txt uri content://media/external/file/7842
一个测试文件出现,其他的没有
证明:
其他文件在哪里?
一般来说,在让另一个进程处理文件之前,您需要确保所有字节都通过 getFD().sync()
刷新到磁盘。特别是,这似乎有助于整个媒体扫描。
the files shows up in a .listFiles(), and .exist(), and the callback for the MediaScanner says that it completed correctly. Surely an extant (if empty) file should show up?
媒体扫描仪的方式很神秘。 :-) IOW,打败了我。
请记住,这里有多个活动部件:您的应用程序、媒体扫描器、Android 上的 MTP 守护程序和您的 MTP 客户端。崩溃可能发生在任何阶段。如果您拔下并重新插入设备,现在文件显示在您的 MTP 客户端中,我的猜测是 MTP 客户端正在使用稍微陈旧的缓存。
我有一个外部存储文件的目录结构。它们没有出现在 Android 文件传输应用程序中,因此我认为这是媒体扫描仪的问题。
我在基于 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
.
FileOutputStream
创建它们
我有以下方法,从 activity 调用,所以 context
是一个 activity(暂时忘记这会阻塞主线程!):
public void scan(Context context, File base) {
File[] files = base.listFiles();
if (files == null) {
return;
} else {
for (File file : files) {
if (file.isFile()) {
String path = file.getAbsolutePath();
MediaScannerConnection.scanFile(context, new String[]{path}, null, null);
Log.e("Langstroth", path);
} else if (file.isDirectory()) {
this.scan(context, file);
}
}
}
}
public void scan(Context context) {
this.scan(context, this.baseDir);
}
}
日志的输出符合预期:
E/MyApp﹕ /storage/emulated/0/Documents/Langstroth/sample/5000/1430576404874.wav
E/MyApp﹕ /storage/emulated/0/Documents/Langstroth/sample/5000/1430577209491.wav
然后很多:
E/MyApp﹕ Scan completed path /storage/emulated/0/Documents/Langstroth/sample/5000/1430576404874.wav uri content://media/external/audio/media/7836
E/MyApp﹕ Scan completed path /storage/emulated/0/Documents/Langstroth/sample/5000/1430577209491.wav uri content://media/external/audio/media/7838
这证明文件存在。不过,它们不会出现在 Android 文件传输中。
奇怪的是。另一种方法:
public void otherDemo(Context context, File baseDir) {
String newPath = baseDir.getAbsolutePath() + "/some/random/dirs";
Log.e("Langstroth", "New path " + newPath);
File dir = new File(newPath);
dir.mkdirs();
Log.e("Langstroth", dir.exists() ? "Dir exists": "Dir does not exist");
File f = new File(dir, "myfile.txt");
try {
new BufferedOutputStream(new FileOutputStream(f)).close();
} catch (IOException e) {
e.printStackTrace();
}
Log.e("Langstroth", f.exists() ? "File exists": "File does not exist");
MediaScannerConnection.scanFile(context, new String[]{f.getAbsolutePath()}, null, null);
}
和日志输出:
E/MyApp﹕ New path /storage/emulated/0/Documents/Langstroth/some/random/other/dirs
E/MyApp﹕ Dir exists
E/MyApp﹕ File exists
E/MyApp﹕ File: /storage/emulated/0/Documents/Langstroth/some/random/other/dirs/myfile.txt
E/MyApp﹕ Other scan completed path /storage/emulated/0/Documents/Langstroth/some/random/other/dirs/myfile.txt uri content://media/external/file/7842
一个测试文件出现,其他的没有
证明:
其他文件在哪里?
一般来说,在让另一个进程处理文件之前,您需要确保所有字节都通过 getFD().sync()
刷新到磁盘。特别是,这似乎有助于整个媒体扫描。
the files shows up in a .listFiles(), and .exist(), and the callback for the MediaScanner says that it completed correctly. Surely an extant (if empty) file should show up?
媒体扫描仪的方式很神秘。 :-) IOW,打败了我。
请记住,这里有多个活动部件:您的应用程序、媒体扫描器、Android 上的 MTP 守护程序和您的 MTP 客户端。崩溃可能发生在任何阶段。如果您拔下并重新插入设备,现在文件显示在您的 MTP 客户端中,我的猜测是 MTP 客户端正在使用稍微陈旧的缓存。