Android MediaScannerConnection扫描文件

本文详细介绍了在Android 4.4及以后版本中,如何使用MediaScannerConnection替代ACTION_MEDIA_MOUNTED广播来扫描文件并更新系统媒体库。文章对比了两种方法的优缺点,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 Android 4.4 之后,ACTION_MEDIA_MOUNTED 这个广播只能由系统发出,APP 只能监听,不能广播,所以通过发送广播的方式来让系统扫描文件的做法已经是走不通了。在 4.4 以后,会因为权限不够抛出运行时异常
MediaScannerConnection
Android 认为,使用 MediaScannerConnection 会更加廉价,也就是系统的开销少。
1、如果是通过广播 ACTION_MEDIA_MOUNTED 的话,很多 APP 都会直接广播一个目录,于是系统就一直在扫描整个目录。而 MediaScannerConnection 每次只能扫描一个文件,这样的约束条件可能一定程度上能减少扫描的次数和个数。
2、 MediaScannerConnection 使用了比 ACTION_MEDIA_MOUNTED 更高效或更轻便的实现。

MediaScannerConnection 两种使用方式
1、创建MediaScannerConnection对象,调用scanFile() 方法。

public void scanFile(String path, String mimeType),

创建MediaScannerConnection对象的时候需要实现 MediaScannerConnection.MediaScannerConnectionClient接口,这个接口只有两个方法。在调用MediaScannerConnection.connect()方法后,MediaScannerConnectionClient接口的onMediaScannerConnected()方法会被回调,然后就可以调用 MediaScannerConnection.scanFile(String,String)方法了。在扫描完成后,MediaScannerConnectionClient的方法onScanCompleted(String path, Uri uri)会被回调,在这个方法里,一般调用MediaScannerConnection.disconnect()方法。

这个方法一次只能扫描一个文件,path 必须是一个具体的文件,不能是目录。在创建一个MediaScannerConnection对象后,如果要多次调用 scanFile() 方法,就不要在onScanCompleted() 方法里调用disconnect()方法。
2、使用 MediaScannerConnection.scanFile() 静态方法。
public static void scanFile(Context context, String[] paths, String[] mimeTypes, OnScanCompletedListener callback)

这是一个静态方法,使用就比较简单了。OnScanCompletedListener 可实现可不实现,它只有一个方法,在扫描完成的时候回调。scanFile 静态方法可以一次传递多个文件,如果 mimeTypes 不为空,就必须于 paths 的长度一致。mimeTypes 可以为空。

MimeType 的选择。

如果 MimeType ,将会使用文件的后缀名来判断文件的类型,但是千万别用 / ,我以为使用这个它会自动判断文件的类型的,结果不是这样子的。使用 / 的结果就是扫描完成后,相册里的东东全部没有出现在 MediaStore 里,也就是没有被当成多媒体文件扫描进多媒体数据库里。

完成代码

package com.huahan.lovebook.utils;

import java.io.File;

import com.huahan.hhbaseutils.HHLog;

import android.content.Context;
import android.media.MediaScannerConnection;
import android.net.Uri;

public class MediaScanner {

    private static final String TAG = "mtj";

    private MediaScannerConnection mConn = null;
    private SannerClient mClient = null;
    private File mFile = null;
    private String mMimeType = null;

    public MediaScanner(Context context) {
        if (mClient == null) {
            mClient = new SannerClient();
        }
        if (mConn == null) {
            mConn = new MediaScannerConnection(context, mClient);
        }
    }

    class SannerClient implements
            MediaScannerConnection.MediaScannerConnectionClient {

        public void onMediaScannerConnected() {

            if (mFile == null) {
                return;
            }
            scan(mFile, mMimeType);
        }

        public void onScanCompleted(String path, Uri uri) {
            mConn.disconnect();
        }

        private void scan(File file, String type) {
            HHLog.i(TAG, "scan " + file.getAbsolutePath());
            if (file.isFile()) {
                mConn.scanFile(file.getAbsolutePath(), null);
                return;
            }
            File[] files = file.listFiles();
            if (files == null) {
                return;
            }
            for (File f : file.listFiles()) {
                scan(f, type);
            }
        }
    }

    public void scanFile(File file, String mimeType) {
        mFile = file;
        mMimeType = mimeType;
        mConn.connect();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅气的铅笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值