【问题标题】:Android file delete leaves empty placeholder in GalleryAndroid文件删除在图库中留下空占位符
【发布时间】:2011-05-24 18:32:17
【问题描述】:

我通过以下方式插入图像:

    ContentValues values = new ContentValues();   
    values.put(Images.Media.TITLE, filename);
    values.put(Images.Media.DATE_ADDED, System.currentTimeMillis()); 
    values.put(Images.Media.MIME_TYPE, "image/jpeg");

    Uri uri = this.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);

但是当我尝试删除时

    File f = new File(imageURI);
    f.delete();

图片不再存在,而是一个空的占位符。有什么想法吗?

【问题讨论】:

    标签: android gallery


    【解决方案1】:

    Android 有一个用于跟踪媒体文件的缓存。

    试试这个:

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

    它使 MediaScanner 服务再次运行,这应该会从设备的缓存中删除已删除的图像。

    看起来您还需要将此权限添加到您的 AndroidManifest.xml:

    <intent-filter>
      <action android:name="android.intent.action.MEDIA_MOUNTED" />
      <data android:scheme="file" /> 
    </intent-filter>
    

    【讨论】:

    • @aloneguid,想解释一下原因吗?
    • Intent.ACTION_MEDIA_MOUNTED 重新扫描所有媒体集合,Android 操作系统在安装 SD 卡时只执行一次是有充分理由的。
    • 似乎没有等效的 MediaScannerConnection.scanFile() 用于删除文件。如果您发现了另一种方法,请告诉我,否则我坚持我的答案是正确的。
    • 非常有帮助。我有一个在 Android 4.1 设备上使用的应用程序,这是操作系统完全识别文件实际上已被删除的唯一方法
    【解决方案2】:

    您也可以使用以下方法从图库中删除图片:

    getContentResolver().delete(imageUri, null, null);

    只需确保“imageUri”是您调用 insert 时返回给您的 uri。

    【讨论】:

    • 我不断收到“未知 URL”错误。您是通过电话根目录传递完整路径还是仅传递顶级路径?我已经尝试了这两种方法并不断收到未知的 url 错误。当我将文件添加到图库时,我无法维护插入 URI 的数据库。我可以仅使用我知道有效的文件路径从库中删除该项目吗?我可以使用媒体扫描仪将项目添加到画廊,但在文件删除后我无法删除项目。
    • 这个方法是从galley中删除真实图像还是只是从galley中隐藏具有此路径的图像?
    • @hadi 这将从 mediaDB 中删除该项目。由于这是通过带有 cascade-file-delete-trigger 的 SQLite 实现的,因此该文件也会被删除。
    【解决方案3】:

    取自:http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.html

    这对我有用(在 HTC Desire、Android 2.3 上测试)

    // Tell the media scanner about the new file so that it is
    // immediately available to the user.
    MediaScannerConnection.scanFile(this,new String[] { file.toString() }, null,
    new MediaScannerConnection.OnScanCompletedListener() {
    public void onScanCompleted(String path, Uri uri) {
    Log.i("ExternalStorage", "Scanned " + path + ":");
    Log.i("ExternalStorage", "-> uri=" + uri);
    }
    });
    

    【讨论】:

      【解决方案4】:

      如 cmets 所述,接受的答案会占用大量内存。虽然 MediaScannerConnection 没有“deleteFile”方法,但只需在删除文件后将旧文件路径传递给“scanFile”方法。媒体扫描仪将重新扫描并移除媒体。

      在 N5 上测试。安卓 4.4。

      编辑:其他人表示这不适用于 4.2

      new AsyncTask<Void, Void, Void>(){
              @Override
              protected Void doInBackground(Void... params) {
                  String filePath = recording.file.getAbsolutePath();
                  recording.file.delete();
                  MediaScannerConnection.scanFile(context,
                          new String[]{filePath}, null, null);
                  return null;
              }
          }.execute();
      

      【讨论】:

      • 这比使用 Intent.ACTION_MEDIA_MOUNTED 广播要好!
      • 我在 android 4.2 上做了这个,但没有用。这个问题只针对4.4版本以下的android吗?
      • 只需在 Android 4.4 之前接受的答案中使用缓慢可怕的方式
      【解决方案5】:

      使用这个方法 getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
      MediaStore.Images.Media._ID + "=?", new String[]{ Long.toString(id) } );

      【讨论】:

      • “id”的值应该是多少?
      【解决方案6】:

      如果您不知道@manisha 的回答中要求的图像 ID 和 @Muhammad Waqas Khan 你也可以按文件名删除

          String fullPathToFile = "/storage/sdcard0/DICM/test.jpg";
          getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
              MediaStore.Images.Media.DATA + "=?", new String[]{ fullPathToFile } );
      

      [2016-06-16 更新]

      危险:这看起来像“仅从 mediaDB 中删除项目”。 由于 mediaDB 中有一个 SQLite-cascade-file-delete-trigger,引用的文件也会被删除(如果存在)。

      为避免这种情况,您必须在调用 delete 之前将列 MediaStore.Images.Media.DATA 更​​改为不存在的文件路径。

      【讨论】:

        【解决方案7】:

        File.delete();之后添加这一行:

        MediaScannerConnection.ScanFile(this,new string[]{fileUrl.ToString()}, null, null);
        

        【讨论】:

          【解决方案8】:

          删除文件后立即添加:

          MediaScannerConnection.scanFile(context, arrayOf(imageURI.getPath()), null, null)

          :)

          【讨论】:

            【解决方案9】:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
              MediaScannerConnection.scanFile(context,new String[]{selectedVideoDelete}, null, null);
            } else {
              context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
            }
            

            【讨论】:

              猜你喜欢
              • 2021-07-10
              • 1970-01-01
              • 1970-01-01
              • 2020-12-15
              • 2014-07-16
              • 1970-01-01
              • 2012-12-29
              • 2017-05-02
              • 2019-05-15
              相关资源
              最近更新 更多