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

Big*_*low 14 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Ari*_*Roy 50

故事

在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())));
Run Code Online (Sandbox Code Playgroud)

来自Android 4.4

你有两种方式.

i)第一个与前一个示例非常相似,但可能无法有效工作,也不建议使用.

sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
Run Code Online (Sandbox Code Playgroud)

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

在String类型ArrayList中添加已更新的文件的文件路径,如下所示

ArrayList<String> toBeScanned = new ArrayList<String>();
toBeScanned.add(item.getFilePath());
Run Code Online (Sandbox Code Playgroud)

现在,您需要运行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);

                    }
                });
Run Code Online (Sandbox Code Playgroud)

  • 方式我没有效果(两个评论都指的是Android 5) (2认同)

Big*_*low 10

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

只需调用以下代码:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
Run Code Online (Sandbox Code Playgroud)

这应该触发mediascanner.

  • 它将触发mediascanner,但它将扫描SD卡中的所有文件(除了那些带有.nomedia文件的文件夹).扫描需要一些时间,具体取决于SD卡中的文件数量. (5认同)
  • Intent.ACTION_MEDIA_MOUNTED将在Android 4.4+设备上中断,因为目的仅限于系统应用程序. (4认同)

blu*_*con 6

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

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

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

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

以下是有关如何使用内容解析程序插入,删除和更新的说明.(搜索"插入,更新和删除数据"部分)

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


小智 6

   File file = new File(absolutePath);
   Uri uri = Uri.fromFile(file);
   Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
   sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)