在安卓系统中如何通过程序删除文件?

75

我正在使用4.4.2版本的系统,尝试通过URI删除一个文件(图像)。这是我的代码:

File file = new File(uri.getPath());
boolean deleted = file.delete();
if(!deleted){
      boolean deleted2 = file.getCanonicalFile().delete();
      if(!deleted2){
           boolean deleted3 = getApplicationContext().deleteFile(file.getName());
      }
}

现在,这些删除函数中没有一个实际上删除文件。我也在我的AndroidManifest.xml文件中有这个:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />

我不使用getCanonicalFile(),而是直接使用File.delete(),在我的系统上它可以正常工作。除非你的URI路径无效。 - Jay Snayder
我的路径是这样的: /external/images/media/2918 看起来正确吗? - Randall Stephens
不,像 /mnt/sdcard/your_folder/your_file.png 这样的路径不是最好的选择。相反,最好通过 getExternalDirectory 获取存储路径。最后,权限 WRITE_EXTERNAL_... 包括 READ_EXTERNAL_... 的权限。 - Phantômaxx
谢谢,现在我已经解决了。 - Randall Stephens
可能是android:删除图像的重复问题。 - Aashish Kumar
7个回答

167

为什么不使用这段代码进行测试:

File fdelete = new File(uri.getPath());
if (fdelete.exists()) {
    if (fdelete.delete()) {
        System.out.println("file Deleted :" + uri.getPath());
    } else {
        System.out.println("file not Deleted :" + uri.getPath());
    }
}

我认为问题的一部分在于你从未尝试删除文件,而是只不断地创建一个具有方法调用的变量。

因此,在你的情况下,你可以尝试:

File file = new File(uri.getPath());
file.delete();
if(file.exists()){
      file.getCanonicalFile().delete();
      if(file.exists()){
           getApplicationContext().deleteFile(file.getName());
      }
}

不过我认为那有点过头了。

你添加了一条评论,说明你正在使用外部目录而非uri。因此,你应该添加类似于以下内容:

String root = Environment.getExternalStorageDirectory().toString();
File file = new File(root + "/images/media/2918"); 

接着尝试删除该文件。


1
我认为你可能有所发现。它一直说fdelete不存在。我的文件路径是/external/images/media/2918。看起来对吗? - Randall Stephens
我认为你的解决方案在他的情况下不起作用,因为他已经按照你告诉他的方式做了。 - migos
@Saturisk他几乎做了你告诉他该做的事情。他的问题是路径错误。 - migos
我的解决方案是可行的,他只是回答错误了。他说他正在使用URI获取路径,但实际上并没有。我修正了我的答案以回答他的问题。 - Shawnic Hedgehog
没错。我只是在修复我的应用程序并测试它,然后我会点赞并将事情标记为正确。 - Randall Stephens
显示剩余6条评论

15

试试这个。对我来说它有效。

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Set up the projection (we only need the ID)
        String[] projection = { MediaStore.Images.Media._ID };

        // Match on the file path
        String selection = MediaStore.Images.Media.DATA + " = ?";
        String[] selectionArgs = new String[] { imageFile.getAbsolutePath() };

        // Query for the ID of the media matching the file path
        Uri queryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        ContentResolver contentResolver = getActivity().getContentResolver();
        Cursor c = contentResolver.query(queryUri, projection, selection, selectionArgs, null);

        if (c != null) {
            if (c.moveToFirst()) {
                // We found the ID. Deleting the item via the content provider will also remove the file
                long id = c.getLong(c.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
                Uri deleteUri = ContentUris.withAppendedId(queryUri, id);
                contentResolver.delete(deleteUri, null, null);
            } else {
                // File not found in media store DB
            }
            c.close();
        }
    }
}, 5000);

10

我在Nougat模拟器上测试了这段代码,它可以正常工作:

在清单文件中添加:

<application...

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>
</application>

在res文件夹中创建一个空的xml文件夹,并将provider_paths.xml文件粘贴进去。
<?xml version="1.0" encoding="utf-8"?>
 <paths xmlns:android="http://schemas.android.com/apk/res/android">
   <external-path name="external_files" path="."/>
  </paths>

然后将下一个片段放入您的代码中(例如片段):
File photoLcl = new File(homeDirectory + "/" + fileNameLcl);
Uri imageUriLcl = FileProvider.getUriForFile(getActivity(), 
  getActivity().getApplicationContext().getPackageName() +
    ".provider", photoLcl);
ContentResolver contentResolver = getActivity().getContentResolver();
contentResolver.delete(imageUriLcl, null, null);

6

我看到你找到了答案,但对我没有用。删除一直返回false,所以我尝试了以下方法,它起作用了(对于任何其他选择的答案不起作用的人):

System.out.println(new File(path).getAbsoluteFile().delete());

系统输出显然可以忽略,我将其放置在那里只是为了方便确认删除。

3
File file=new File(getFilePath(imageUri.getValue()));
boolean b= file.delete();

在我的情况下无法工作。通过使用以下代码,问题已得到解决-

ContentResolver contentResolver = getContentResolver ();
contentResolver.delete (uriDelete,null ,null );

OP正在询问如何删除文件,而您的情况涉及Scoped Storage,这是完全不同的。 - Ezequiel Adrian

1

你可以使用delete()方法删除文件。

首先,你需要在代码中通过指定文件路径作为参数来创建一个文件引用,然后调用delete()方法来删除该文件。

String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/video1.mp4";
new File(path).delete();

1

首先调用意图

Intent intenta = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intenta, 42);

然后调用结果。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case 42:
            if (resultCode == Activity.RESULT_OK) {
                Uri sdCardUri = data.getData();
                DocumentFile pickedDir = DocumentFile.fromTreeUri(this, sdCardUri);
                for (DocumentFile file : pickedDir.listFiles()) {
                    String pp = file.getName();
                    if(pp.equals("VLC.apk"))
                        file.delete();
                    String ppdf="";
                }
                File pathFile = new File(String.valueOf(sdCardUri));
                pathFile.delete();
            }
            break;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接