15

我得到了这个类:

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
    }
}

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

4

6 回答 6

52

故事

在 Android 4.4 之前,我们可以只发送一个广播来触发任何特定文件、文件夹甚至存储根目录上的媒体扫描器。但是从 4.​​4 KitKat 开始,Android 开发人员已经修复了这个问题。

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

安卓 4.4 之前

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

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

从安卓 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[] 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);

                    }
                });
于 2014-08-01T18:33:43.537 回答
10

嘿,我发现了如何用一个非常简单的代码来做到这一点。

只需调用这行代码:

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

这应该会触发 mediascanner。

于 2012-02-27T09:00:22.533 回答
7

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

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

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

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

下面是关于如何使用内容解析器插入、删除、更新的说明。(搜索“插入、更新和删除数据”部分)

编辑: 这个答案中有一个示例代码。检查 Janusz 的答案。

于 2012-02-24T11:35:07.197 回答
6
   File file = new File(absolutePath);
   Uri uri = Uri.fromFile(file);
   Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
   sendBroadcast(intent);
于 2014-03-19T06:34:08.857 回答
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部分

于 2016-03-27T14:13:58.847 回答
0

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

  • Intent.ACTION_MEDIA_MOUNTED 和 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE 可以接受单独的文件路径,所以 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(filePath))); 或 sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse(filePath))); 将是有效的。
  • 如果您在 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)));
}

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

于 2016-06-15T06:33:47.390 回答