Android关于本地多媒体(图片、视频、音频)Media的选择总结

Android关于本地多媒体(图片、视频、音频)Media的选择总结

  1. 获取本地多媒体文件
  2. 获取本地文件的坑
    2.1 .nomedia
    2.2 对于多媒体库的刷新

1、获取多媒体文件

说到多媒体文件,就不得不提MediaStore。MediaStore这个类是android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取。Android把所有的多媒体数据库接口进行了封装,所有的数据库不用自己进行创建,直接调用利用ContentResolver去掉用那些封装好的接口就可以进行数据库的操作了。
路径是在 /data/data/com.android.providers.media/databases/external.db
在这个db的files表中可以查看所有多媒体信息
无图无真相:
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/+"你自己的路径"

多么痛的领悟
这样就可以了,多么痛的领悟!!!!

希望与君共勉,有什么不对的地方积极留言讨论呦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值