在特定路径(文件夹)上触发mediascanner,如何?

时间:2012-02-23 14:28:02

标签: android android-mediascanner

我上了这堂课:

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

public class MediaScannerWrapper implements  
MediaScannerConnection.MediaScannerConnectionClient {
    private MediaScannerConnection mConnection;
    private String mPath;
    private String mMimeType;


    // filePath - where to scan; 
    // mime type of media to scan i.e. "image/jpeg". 
    // use "*/*" for any media
    public MediaScannerWrapper(Context ctx, String filePath, String mime){
        mPath = "/sdcard/DCIM/Camera";
        mMimeType = "jpg";
        mConnection = new MediaScannerConnection(ctx, this);
    }

    // do the scanning
    public void scan() {
        mConnection.connect();
    }

    // start the scan when scanner is ready
    public void onMediaScannerConnected() {
        mConnection.scanFile(mPath, mMimeType);
        Log.w("MediaScannerWrapper", "media file scanned: " + mPath);
    }

    public void onScanCompleted(String path, Uri uri) {
        // when scan is completes, update media file tags
    }
}

如何在其他课程中使用它? 我不知道如何正确使用类,我试过但没有任何工作。 我做错了什么,但我不知道是什么,有人可以帮我解决这个问题。

6 个答案:

答案 0 :(得分:49)

故事

在Android 4.4之前,我们可以发送广播来触发任何特定文件,文件夹甚至存储根目录上的媒体扫描程序。但是从4.4 KitKat开始,这已由Android开发者修复。

为什么我说固定?原因很简单。在根目录上使用MEDIA_MOUNTED发送广播非常昂贵。运行Media Scanner是一项昂贵的操作,当用户在存储和深层文件夹结构中获得大量文件时,情况会变得更糟。

Android 4.4之前

保持简单直接。如果您在Android 4.4之前定位您的应用。但请记住,除非绝对必要,否则不要在根目录中使用它。

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));

来自Android 4.4

有两种方法可供选择。

i)第一个与前一个示例非常相似,但可能效率不高,也不建议使用。

sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + Environment.getExternalStorageDirectory())));

ii)现在,让我们继续讨论这个问题的最佳推荐和有效解决方案。

在String类型ArrayList

中添加已更新的文件的文件路径,如下所示
ArrayList<String> toBeScanned = new ArrayList<String>();
toBeScanned.add(item.getFilePath());

现在,您需要运行MediaScannerConnection类的scanFile()静态方法,并传递包含已更新且需要进行媒体扫描的所有文件列表的String数组。

您还可以让侦听器在单个文件的扫描完成后作出响应。

String[] toBeScannedStr = new String[toBeScanned.size()];
                toBeScannedStr = toBeScanned.toArray(toBeScannedStr);

                MediaScannerConnection.scanFile(getActivity(), toBeScannedStr, null, new OnScanCompletedListener() {

                    @Override
                    public void onScanCompleted(String path, Uri uri) {
                        System.out.println("SCAN COMPLETED: " + path);

                    }
                });

答案 1 :(得分:10)

嘿,我发现了如何用一个非常简单的代码来完成它。

只需拨打以下代码:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));

这应该触发mediascanner。

答案 2 :(得分:6)

在Android中,媒体扫描程序使用内容数据库来跟踪设备上存在的所有媒体内容。

当Android启动时,启动mediascanner服务并在整个外部存储中运行,以查找是否有任何新媒体内容,如果找到,则

  • 它将该媒体内容的条目添加到内容数据库
  • 内容数据库中的每个条目都包含媒体内容的元数据,如姓名,日期,文件大小,文件类型等。
  • 因此,当您对媒体内容进行修改时,您还需要更新内容数据库。
  • 如果内容数据库未更新,则其他应用程序也将无法访问该特定媒体内容。
  • 运行媒体扫描程序只会更新内容数据库

您可以自行更新内容数据库,而不是运行媒体扫描程序,它可以解决问题。

这是关于如何使用内容解析器插入,删除和更新的explanation。 (搜索“插入,更新和删除数据”部分)

修改answer中有一个示例代码。检查Janusz的答案。

答案 3 :(得分:6)

   File file = new File(absolutePath);
   Uri uri = Uri.fromFile(file);
   Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
   sendBroadcast(intent);

答案 4 :(得分:1)

private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}

参考:http://developer.android.com/training/camera/photobasics.html#TaskGallery

Add the Photo to a Gallery部分

答案 5 :(得分:0)

作为@Aritra Roy的回答,我决定对这个问题进行实验。 我在这里得到的是:

  • Intent.ACTION_MEDIA_MOUNTED和Intent.ACTION_MEDIA_SCANNER_SCAN_FILE 可以接受单个文件路径,所以sendBroadcast(新的 意图(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.parse(filePath))); 或sendBroadcast(新意图(Intent.ACTION_MEDIA_MOUNTED, Uri.parse(文件路径)));将是有效的。
  • 如果您在Kitkat或更高版本上使用Intent.ACTION_MEDIA_MOUNTED的单个文件路径,您的应用程序仍会崩溃
  • 如果您在低于Kitkat的设备上使用Intent.ACTION_MEDIA_SCANNER_SCAN_FILE或MediaScannerConnection,您的应用程序将不会强行关闭,但该方法根本无法正常工作。

从那个实验中,我认为最好的方法是

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    MediaScannerConnection.scanFile(context, new String[]{imagePath}, null, new MediaScannerConnection.OnScanCompletedListener() {
        public void onScanCompleted(String path, Uri uri) {
            //something that you want to do
        }
    });
} else {
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
            Uri.parse("file://" + imagePath)));
}

如果我错过了什么,请告诉我