如何从SD卡中删除文件

131

我正在创建一个文件作为电子邮件的附件发送。现在我想在发送电子邮件后删除这个文件中的图像。有没有办法删除这个文件?

我已经尝试过 myFile.delete(); 但它并没有删除这个文件。


我正在使用Android编写代码,所以编程语言是Java,采用通常的Android方式来访问SD卡。我正在 onActivityResult 方法中删除这个文件,当一个 Intent 在发送电子邮件后返回到屏幕上时。


你需要提供更多关于问题的信息,例如你正在使用哪种编程语言,如何访问SD卡等。 - Amok
你是否将更改刷新到磁盘? - Charles Ma
10
我认为可以假设他正在使用Java,因为他没有具体说明。 - Jeremy Logan
14个回答

358
File file = new File(selectedFilePath);
boolean deleted = file.delete();

selectedFilePath是您想要删除的文件的路径 - 例如:

/sdcard/YourCustomDirectory/ExampleFile.mp3


我认为内部子节点没有被删除,你必须删除所有内部子节点。请参见下面的答案。 - Zar E Ahmer
3
很遗憾,这在Android 4.4及以上版本无法使用。请参见我下面的回答。 - stevo.mit
我不明白这是如何适用于许多人的。在Android Studio中,“已删除”看起来变灰了。 - TheOnlyAnil
是的,我之前发送了类似于“file:///storage/…”这样的路径,但是没有起作用。 - Jemshit Iskenderov
1
@stevo.mit,你找到解决方案了吗?我也遇到了同样的问题,无法在Android 4.4+以上的SD卡中删除文件。但是相同的代码适用于4.3/以下版本。 - hasnain_ahmad
显示剩余4条评论

79

如果您正在使用1.6 SDK以上的版本,则还需授予权限。

uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

AndroidManifest.xml 文件中


但是,如果您需要可移动的SD卡存储,则还需要使用ContentResolver - user25

37

Android 4.4+更改

应用程序不允许外部存储器(删除、修改...)写入,除非是它们的特定于包的目录。

正如Android文档所述:

"应用程序不得被允许写入到次要外部存储设备,除了由合成权限允许的它们特定于包的目录。"

然而,存在一个可恶的解决方法(请参见下面的代码)。 在三星Galaxy S4上进行了测试,但是这个修复程序并不能在所有设备上工作。另外,我不会指望这个解决方法在未来版本的Android中可用。

有一篇很棒的文章解释了(4.4+)外部存储权限的更改

您可以在此处了解更多关于解决方法的信息。解决方法源代码来自此网站

public class MediaFileFunctions 
{
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static boolean deleteViaContentProvider(Context context, String fullname) 
    { 
      Uri uri=getFileUri(context,fullname); 

      if (uri==null) 
      {
         return false;
      }

      try 
      { 
         ContentResolver resolver=context.getContentResolver(); 

         // change type to image, otherwise nothing will be deleted 
         ContentValues contentValues = new ContentValues(); 
         int media_type = 1; 
         contentValues.put("media_type", media_type); 
         resolver.update(uri, contentValues, null, null); 

         return resolver.delete(uri, null, null) > 0; 
      } 
      catch (Throwable e) 
      { 
         return false; 
      } 
   }

   @TargetApi(Build.VERSION_CODES.HONEYCOMB)
   private static Uri getFileUri(Context context, String fullname) 
   {
      // Note: check outside this class whether the OS version is >= 11 
      Uri uri = null; 
      Cursor cursor = null; 
      ContentResolver contentResolver = null;

      try
      { 
         contentResolver=context.getContentResolver(); 
         if (contentResolver == null)
            return null;

         uri=MediaStore.Files.getContentUri("external"); 
         String[] projection = new String[2]; 
         projection[0] = "_id"; 
         projection[1] = "_data"; 
         String selection = "_data = ? ";    // this avoids SQL injection 
         String[] selectionParams = new String[1]; 
         selectionParams[0] = fullname; 
         String sortOrder = "_id"; 
         cursor=contentResolver.query(uri, projection, selection, selectionParams, sortOrder); 

         if (cursor!=null) 
         { 
            try 
            { 
               if (cursor.getCount() > 0) // file present! 
               {   
                  cursor.moveToFirst(); 
                  int dataColumn=cursor.getColumnIndex("_data"); 
                  String s = cursor.getString(dataColumn); 
                  if (!s.equals(fullname)) 
                     return null; 
                  int idColumn = cursor.getColumnIndex("_id"); 
                  long id = cursor.getLong(idColumn); 
                  uri= MediaStore.Files.getContentUri("external",id); 
               } 
               else // file isn't in the media database! 
               {   
                  ContentValues contentValues=new ContentValues(); 
                  contentValues.put("_data",fullname); 
                  uri = MediaStore.Files.getContentUri("external"); 
                  uri = contentResolver.insert(uri,contentValues); 
               } 
            } 
            catch (Throwable e) 
            { 
               uri = null; 
            }
            finally
            {
                cursor.close();
            }
         } 
      } 
      catch (Throwable e) 
      { 
         uri=null; 
      } 
      return uri; 
   } 
}

1
无法在Note3上工作。我收到了错误消息“MediaProvider:无法删除/mnt/extSdCard/test.zip”。 - iscariot
2
我有一部未root的Moto X手机,运行在4.4.4系统上,并且在/sdcard/mydirectory目录下写入没有任何问题。 - Rob
很不幸,在较新版本的Kitkat上它已经无法工作了,因为所有功能都被锁定了。——ghisler(作者) - HendraWD
Android越来越关闭自己。我们最终会得到一个丑陋的iOS副本!! - Phantômaxx
这在我的设备上失败了(Android 7.1)。它总是返回 false 并且不会删除文件 :-( - Spikatrix

18

Android的Context类有以下方法:

public abstract boolean deleteFile (String name)

我相信只要应用程序权限如上所列,这将实现你想要的功能。


3
这应该是正确的答案。context.deleteFile(filename); - Lisandro

11

递归删除文件的所有子级...

public static void DeleteRecursive(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory()) {
        for (File child : fileOrDirectory.listFiles()) {
            DeleteRecursive(child);
        }
    }

    fileOrDirectory.delete();
}

自从Android KitKat以来,有一些变化。未来的读者可以使用下面的链接作为参考之一:https://dev59.com/4FcO5IYBdhLWcg3wxEYP - Gleichmut

9
这对我很有用:(从图库中删除图片)
File file = new File(photoPath);
file.delete();

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(photoPath))));

2
context.sendBroadcast()是用来做什么的? - Megaetron
基本上,它将意图(要执行的操作)发送/广播给所有与此意图匹配的接收器。[链接](http://developer.android.com/reference/android/content/Context.html) - Jiyeh

6
 public static boolean deleteDirectory(File path) {
    // TODO Auto-generated method stub
    if( path.exists() ) {
        File[] files = path.listFiles();
        for(int i=0; i<files.length; i++) {
            if(files[i].isDirectory()) {
                deleteDirectory(files[i]);
            }
            else {
                files[i].delete();
            }
        }
    }
    return(path.delete());
 }

这段代码将会对你有所帮助。在Android Manifest文件中,你需要获取权限来进行修改。
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

如果以下条件成立,则files[]可以为null: file.exists:true file.isDirectory:true file.canRead:false file.canWrite:false - ilw
我猜你们可能完全不知道一些安卓手机限制了对SD卡的写入访问权限。 - user9599745

4

试一下这个。

File file = new File(FilePath);
FileUtils.deleteDirectory(file);

来自Apache Commons


1

我曾经遇到一个与4.4版本相关的应用程序问题。我的做法是一种巧妙的方法。

我将文件重命名并在我的应用程序中忽略它们。

例如:

File sdcard = Environment.getExternalStorageDirectory();
                File from = new File(sdcard,"/ecatAgent/"+fileV);
                File to = new File(sdcard,"/ecatAgent/"+"Delete");
                from.renameTo(to);

1

抱歉:由于网站验证,我的代码之前存在错误。

String myFile = "/Name Folder/File.jpg";  

String myPath = Environment.getExternalStorageDirectory()+myFile;  

File f = new File(myPath);
Boolean deleted = f.delete();

我认为很明显... 首先,你需要知道你的文件位置。 其次,Environment.getExternalStorageDirectory() 是一个获取你的应用程序目录的方法。 最后,使用 File 类来处理你的文件...

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