如何禁止MediaScanner自动清除MediaProvider数据库中已经拔掉设备的数据

如何禁止MediaScanner自动清除MediaProvider数据库中已拔掉U盘的数据

以Android O为例,MediaScanner文件的位置在如下路径:

frameworks/base/media/java/android/media/MediaScanner.java

Android系统中U盘扫描机制我会在下一篇文章里详细介绍,这里只简单说明一下该机制的基本流程。在设备挂载成功后, MediaProvider模块的MediaScannerReceiver会监听到StorageManagerService发来的"Intent.ACTION_MEDIA_MOUNTED"广播,最终会调到MediaScanner.scanDirectories(String[] directories)接口。进入该接口后,会调到prescan方法,该方法的作用是清除掉MediaProvider数据库中不存在的数据:

 public void scanDirectories(String[] directories) {
      try {
          long start = System.currentTimeMillis();
          prescan(null, true);  //注意这里传的filePath参数为null
          long prescan = System.currentTimeMillis();
          ...
private void prescan(String filePath, boolean prescanFiles) throws RemoteException {
      Cursor c = null;
      String where = null;
      String[] selectionArgs = null;
  
      mPlayLists.clear();
  
      if (filePath != null) {
          // query for only one file
          where = MediaStore.Files.FileColumns._ID + ">?" +
              " AND " + Files.FileColumns.DATA + "=?";
          selectionArgs = new String[] { "", filePath };    //如果filePath不为null,则只query该path对应的内容
      } else {
          where = MediaStore.Files.FileColumns._ID + ">?";
          selectionArgs = new String[] { "" };    //如果filePath为null, 则不限制query条件
      }
  
      ...
                  while (c.moveToNext()) {
                  ...
                          if (!exists && !MtpConstants.isAbstractObject(format)) {
                              // do not delete missing playlists, since they may have been
                              // modified by the user.
                              // The user can delete them in the media player instead.
                              // instead, clear the path and lastModified fields in the row
                              MediaFile.MediaFileType mediaFileType = MediaFile.getFileType(path);
                              int fileType = (mediaFileType == null ? 0 : mediaFileType.fileType);
  
                              if (!MediaFile.isPlayListFileType(fileType)) {
                                  deleter.delete(rowId);
                                  if (path.toLowerCase(Locale.US).endsWith("/.nomedia")) {
                                      deleter.flush();  //删除不存在的内容
                                      ...
}

从代码可以发现,默认调prescan时传的filePath参数为null, 这就会导致在query的时候不限制条件,所有不存在的数据都会被清除。
解决办法:

public boolean scanDirectories(String[] directories) {
      try {
          long start = System.currentTimeMillis();
          for (String path : directories) {
              prescan(path, true);    //将当前扫描设备的路径传递过去
          }

这样一来,在prescan方法里,query的时候就只会处理当前扫描设备相关的数据,其它设备的数据不会被删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值