Android设备以文件传输(mtp模式)方式连接pc时,你会发现在手机上新建的文件/文件夹通通不能立即显示出来,但是重启Android设备就可以显示出来。这要从mtp来说起,mtp是一个媒体传输协议,这个模式下获取到的文件结构实际上是一个数据库映射出来的
(外置存储的数据库路径:/data/data/com.android.providers.media/databases/external.db),在每次开机时系统会重新扫描磁盘文件然后将目录结构保存到数据库。
但是有没办法在每次新建文件/文件夹时,立即可以通过mtp模式查看到文件/文件夹呢?当然是有的,前面我们已经知道了mtp模式查看到的文件结构就是数据库里面存储的文件结构,如果我们能找到方法能将新建的文件/文件夹路径更新到数据库就可以实现我们的目标。虽然我们不能直接操作文件结构数据库,但是我们可以通过系统提供一些方法间接操作。
更新文件的话比较简单,发送一个广播即可;更新文件夹的话,系统没有提供这种类型的广播(低版本好像是android4.4有提供),所以我们需要使用MediaScanner。
下面直接贴上代码:
/**
* 目录更新
*/
public static void notifyDirUpdate(Context context, File file) {
MediaScanner scanner = new MediaScanner(context, "external");
scanner.scanDirectories(new String[]{file.getParentFile().getAbsolutePath()});
}
/**
* 文件更新
*/
public static void notifyFileUpdate(Context context, File file) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
context.sendBroadcast(intent);
}
更新:MediaScanner
这个类在android source是可以发现,但是在jar包里面却没有,可能故意隐藏了这个类。所以需要另外的方法,更新mtp的external.db可以通过提供的ContentProvider方法(参考MediaStore类),下面贴上具体实现(在api23、api25测试可用)
public static void notifyDirUpdate(File file) {
ContentResolver resolver = App.getInstance().getContentResolver();
Uri uri = Uri.parse("content://" + MediaStore.AUTHORITY + "/external/file");
ContentValues values = new ContentValues();
values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
values.put(MediaStore.Files.FileColumns.PARENT, 0);
values.put(MediaStore.Files.FileColumns.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Files.FileColumns.TITLE, file.getName());
values.put("format", "12289");
values.put("storage_id", "65537");
try {
resolver.insert(uri, values);
} catch (Exception e) {
e.printStackTrace();
}
}
网友评论