Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 无法从SD卡中删除歌曲_Android_File_Android Sdcard - Fatal编程技术网

Android 无法从SD卡中删除歌曲

Android 无法从SD卡中删除歌曲,android,file,android-sdcard,Android,File,Android Sdcard,我正在尝试创建允许我的音乐应用程序从存储中删除歌曲的代码。 到目前为止,如果文件位于内部(模拟)存储(即,不是应用程序的内部存储,而是手机的内部共享存储)上,is将成功删除该文件。 但是,只要歌曲在外部SD卡上,file.delete()就不会删除该文件并返回false 以下是我目前的代码: //Remove selected tracks from the database activity.getContentResolver() .delete(MediaStore.Audio

我正在尝试创建允许我的音乐应用程序从存储中删除歌曲的代码。 到目前为止,如果文件位于内部(模拟)存储(即,不是应用程序的内部存储,而是手机的内部共享存储)上,is将成功删除该文件。 但是,只要歌曲在外部SD卡上,file.delete()就不会删除该文件并返回false

以下是我目前的代码:

//Remove selected tracks from the database 
activity.getContentResolver()
     .delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, selection.toString(), null);

//Delete File from storage
File file = new File(song.getFilePath);
if(!file.delete()){
   Log.e("MusicFunctions", "Failed to delete file: " + song.getFilePath());
}
当我选择SD卡上的一首歌曲时,它不会被删除,而只是从数据库中删除;以下是logcat输出:

E/MusicFunctions: Failed to delete file: /storage/3138-3763/Music/Test/Odesza/In Return/Always This Late.mp3
我也尝试过
context.deleteFile(file)
,但也没有成功

正如我所说,只有当文件在SD卡上时,它才能删除。当它保存在内部存储器上时,它会很好地删除。 为什么不删除?在Android 5.0+上,从SD卡删除文件的正确方法是什么

非常感谢

编辑: 我忘了提到我已经添加了权限:

<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"/>
另一次编辑: 我注意到文件管理器应用程序需要被授予额外的权限,如下步骤:

我怎样才能做到这一点呢?

试试这个

File file = new File(song.getFilePath);
  if(!file.delete()){
   if(file.exists()){
      file.getCanonicalFile().delete();
      if(file.exists()){
        getApplicationContext().deleteFile(file.getName());
     }
    }
  }
试试这个

File file = new File(song.getFilePath);
  if(!file.delete()){
   if(file.exists()){
      file.getCanonicalFile().delete();
      if(file.exists()){
        getApplicationContext().deleteFile(file.getName());
     }
    }
  }

您可以尝试使用规范文件删除方法

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

您可以尝试使用规范文件删除方法

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

您的文件路径错误,您应该按uri从ContentProvider查询绝对路径,有关如何按uri获取绝对路径,请检查此问题,

您的文件路径错误,您应该按uri从ContentProvider查询绝对路径,有关如何按uri获取绝对路径,请检查此问题,

我注意到这个问题再次引起了人们的兴趣。我很高兴地说,我确实找到了解决问题的办法。我做了大量的在线调查,找到了一些源代码文件(尽管很抱歉,我记不起在哪里找到的),解决了我的问题

Android 4.4及以上版本的问题在于,为了让第三方应用程序删除/修改外部SD卡文件,您需要通过存储访问框架获得额外的权限

为了获得这些特权,您需要获取文档的URI或其父文件(目录)之一的URI。要做到这一点,你需要打开Android的内置文件浏览器。用户最好通过文件浏览器选择SD卡根目录,以便您的应用程序可以修改/删除SD卡上的任何文件。 要执行此操作,您可以遵循以下代码:

private int REQUEST_CODE = 42;
private void getSDCardAccess(){
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    startActivityForResult(intent, REQUEST_CODE);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (resultCode == RESULT_OK) {
        Uri treeUri = resultData.getData();
        DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);

        getContentResolver().takePersistableUriPermission(treeUri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION |
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        if(shrdPref == null){
            shrdPref = getSharedPreferences(PREF_MAIN_FILE, MODE_PRIVATE);
        }
        //Takes the access so that we can use it again after the app reopens
        shrdPref.edit().putString(KEY_SDCARDSTORAGE, treeUri.toString()).apply();
    }
}
此外,您还需要文件的“文档文件”才能修改和删除文件。 下面的代码片段可以帮助您做到这一点,还可以使用document file方法检测文件/目录是否可写。。。 (我知道它有很多代码,其中大部分来自另一个来源。我真的很后悔忘记了我从哪里得到它,因为它们确实值得很多赞扬)。您需要注意的函数是:isWritableNormalOrSAF()、deleteFile()和copyFile()。请注意,大多数其他功能都是这些功能工作所必需的)

公共静态布尔值可写(@NonNull final File){
布尔值isExisting=file.exists();
试一试{
FileOutputStream输出=新的FileOutputStream(文件,true);
试一试{
output.close();
}
捕获(IOE异常){
//什么也不做。
}
}
catch(filenotfounde异常){
返回false;
}
布尔结果=file.canWrite();
//确保在此过程中未创建文件。
如果(!i存在){
//无检查结果方法Callignored
delete();
}
返回结果;
}
公共静态布尔值isWritableNormalOrSaf(@Nullable final文件夹,上下文){
//确认这是一个目录。
Log.e(“StorageHelper”、“start”);
if(folder==null | | |!folder.exists()| |!folder.isDirectory()){
Log.e(“StorageHelper”,“返回1”);
返回false;
}
//在此目录中查找不存在的文件。
int i=0;
文件;
做{
字符串fileName=“AugendiagnoseDummyFile”+(++i);
文件=新文件(文件夹、文件名);
//Log.e(“StorageHelper”,“文件:”+文件名);
}
while(file.exists());
//首先检查常规可写性
如果(可写(文件)){
//Log.e(“StorageHelper”,“返回2 true”);
返回true;
}
//接下来检查SAF可写性。
Log.e(“StorageHelper”、“开始2”);
文件文件;
试一试{
document=getDocumentFile(文件,false,false,上下文);
}
捕获(例外e){
//Log.e(“StorageHelper”,“返回3异常”);
返回false;
}
if(document==null){
//Log.e(“StorageHelper”,“返回4 doc null”);
返回false;
}
//这应该已经创建了文件-否则访问URL会出错。
布尔结果=document.canWrite()&&file.exists();
//确保虚拟文件未保留。
文件。删除();
//Log.e(“StorageHelper”、“返回端”);
返回结果;
}
公共静态布尔deleteFile(@NonNull final File,Context){
//首先尝试正常删除。
if(file.delete()){
返回true;
}
//尝试使用存储访问框架。

DocumentFile document=getDocumentFile(文件、假、真、上下文); 返回文档!=null&&document.delete(); } 私有静态DocumentFile getDocumentFile(@NonNull final File File,final boolean isDirectory,final boolean createDirectories,Context Context){ SharedReferences SharedReferences=context.getSharedReferences(PREF_MAIN_文件,context.MODE_PRIVATE); String uriString=SharedReferences.getString(KEY\u SDCARDSTORAGE,null); 如果(uriString==null){ 返回null; } uritreeuri=Uri.parse(uriString); 字符串完整路径; 试一试{ fullPath=file.getCanonicalPath(); } 捕获(IOE异常){ 返回null; } 一串