Android关于本地多媒体(图片、视频、音频)Media的选择总结
- 获取本地多媒体文件
- 获取本地文件的坑
2.1 .nomedia
2.2 对于多媒体库的刷新
1、获取多媒体文件
说到多媒体文件,就不得不提MediaStore。MediaStore这个类是android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取。Android把所有的多媒体数据库接口进行了封装,所有的数据库不用自己进行创建,直接调用利用ContentResolver去掉用那些封装好的接口就可以进行数据库的操作了。
路径是在 /data/data/com.android.providers.media/databases/external.db
在这个db的files表中可以查看所有多媒体信息
无图无真相:
具体操作如下
private final static String[] PROJECTION = {
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Video.Media.DATE_ADDED,
MediaStore.Video.Media._ID,
};
switch (type) {
case TYPE_IMAGE://图片
cursor = mContext.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
PROJECTION,
MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?",
new String[]{"image/jpeg", "image/png", "image/jpg"},
IMAGE_PROJECTION[2] + " DESC");
break;
case TYPE_VIDEO://視頻
cursor = mContext.getContentResolver().query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
PROJECTION,
null,
null,
VIDEO_PROJECTION[2] + " DESC");
break;
case TYPE_AUDIO://音频
cursor = mContext.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
PROJECTION,
null,
null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
break;
String path = cursor.getString(cursor.getColumnIndex(PROJECTION[0]));//全路径
通常情况下是可以获取到机子上的多媒体信息,既然说了通常情况,那就是说还有埋好的坑在等着我们去实践中吸取教训。
2、坑来了
2.1 .nomedia
“.nomedia”文件放在任何一个文件夹下都会把该文件夹下所有媒体文件(图片,mp3,视频)隐藏起来不会在系统图库,铃声中出现。
通俗来说就是用来屏蔽媒体软件扫描的。在文件夹里放了这个文件,播放软件或者阅读软件就扫描不到这个文件夹的东西了。
我是在获取音频文件时,一直拿不到录音的文件,在同事的交流中才了解了 “.nomedia”这个文件,默认在录音保存的文件夹下会自动生成该文件,一直不知如何去避免生成(查无此法),就采用了简单粗暴的方式–直接删除,如果有更好的方法也希望共享一下
/**
* 删除 .nomedia 文件夹
*
* @param dir
*/
public void deleteFiles(File dir) {
if (dir.exists()) {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
deleteFiles(file);
} else if (file.isFile() && file.getName().equals(".nomedia")) {
file.delete();
}
}
dir.delete();
}
}
2.2 对于多媒体库的刷新
通过adb去push多媒体数据的时候,利用1中获取多媒体文件的方式是没法展示出来的,实际上是由于文件传到本地了,但是多媒体库并没有遍历这些文件,导致在external.db中并没有存储这些文件的信息,在网上找了好几种方法都失败了
方法一
/**
* 通知媒体库更新文件夹
* @param context
* @param filePath 文件夹
*
* */
public void scanFile(Context context, String filePath) {
Intent scanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
scanIntent.setData(Uri.fromFile(new File(filePath)));
context.sendBroadcast(scanIntent);
}
该方法在4.4以后就被禁止使用了,4.4以后会报权限的错误
方法二
new SingleMediaScanner(this,new File("遍历的文件夹路径");
public class SingleMediaScanner implements MediaScannerConnectionClient {
private MediaScannerConnection mMs;
private File mFile;
public SingleMediaScanner(Context context, File f) {
mFile = f;
mMs = new MediaScannerConnection(context, this);
mMs.connect();
}
@Override
public void onMediaScannerConnected() {
mMs.scanFile(mFile.getAbsolutePath(), null);
}
@Override
public void onScanCompleted(String path, Uri uri) {
mMs.disconnect();
}
}
经测试,该方法也没用
方法三
public static final String ACTION_MEDIA_SCANNER_SCAN_DIR = "android.intent.action.MEDIA_SCANNER_SCAN_DIR";
public void scanDirAsync(Context ctx, String dir) {
Intent scanIntent = new Intent(ACTION_MEDIA_SCANNER_SCAN_DIR);
scanIntent.setData(Uri.fromFile(new File(dir)));
ctx.sendBroadcast(scanIntent);
}
经测试,该方法也没效果
最终是通过adb命令去主动遍历多媒体库
adb shell am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///sdcard/+"你自己的路径"
这样就可以了,多么痛的领悟!!!!
希望与君共勉,有什么不对的地方积极留言讨论呦