Java Android Q-删除媒体(音频)文件
我一直在尝试让我的应用程序能够删除音频文件。然而,在尝试了许多可能的解决方案之后,我并没有真正找到一个有效的解决方案 到目前为止,我的解决方案如下:Java Android Q-删除媒体(音频)文件,java,android,android-contentresolver,android-10.0,scoped-storage,Java,Android,Android Contentresolver,Android 10.0,Scoped Storage,我一直在尝试让我的应用程序能够删除音频文件。然而,在尝试了许多可能的解决方案之后,我并没有真正找到一个有效的解决方案 到目前为止,我的解决方案如下: public static void deleteFiles(List<Track> tracks, Context context, final MutableLiveData<IntentSender> deletionIntentSenderLD){
public static void deleteFiles(List<Track> tracks, Context context,
final MutableLiveData<IntentSender> deletionIntentSenderLD){
final Uri AUDIO_URI = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
for(Track t : tracks){
try {
context.getContentResolver().delete(ContentUris
.withAppendedId(AUDIO_URI, t.getUriId()), null, null);
}catch (SecurityException securityException) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (securityException instanceof RecoverableSecurityException) {
deletionIntentSenderLD
.postValue(((RecoverableSecurityException) securityException)
.getUserAction().getActionIntent().getIntentSender());
} else
throw securityException;
} else
throw securityException;
}
}
}
我尝试过实现onRequestPermissionResult()方法,但没有任何效果。我也尝试过使用
File File File=new File()
删除文件,但是,由于对Android 10所做的更改,我没想到它会起作用。因此,在多次谷歌搜索之后,我得出结论,(据我所知)最好的方法是简单地关闭Android Q(10)的作用域存储
在这里,我将提供两种解决方案。第一个是我关闭的,第二个是仍然启用范围存储的。但是,您应该注意的是,第二种解决方案有点问题,有时它实际上会删除实际的媒体文件并更新媒体存储,但大多数情况下它只是从媒体存储中删除。显然,这不是一个很好的解决方案,因为在重新启动应用程序时,应用程序会重新加载这些文件,因为媒体存储会扫描它们
解决方案1-关闭作用域存储
对于这个解决方案,您仍然可以针对Android 11。您只需转到模块级的build.gradle
文件,将compileSdkVersion
和targetSdkVersion
设置为30
然后,进入AndroidManifest.xml
并将uses权限和应用程序标记设置为如下所示:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:ignore="ScopedStorage"/>
<application
android:requestLegacyExternalStorage="true"
...
旁注-在Android 11上删除
要在Android 11上删除,只需调用createDeleteRequest()
,它将返回一个pendingent
。从这个pendingent
中,您可以使用getIntentSender
获取IntentSender
。将此意图发送者传递给活动/片段,然后在活动/片段中调用startinentsenderforresult()
。这会弹出一个对话框,询问用户应用程序是否可以删除文件。如果用户给予许可,系统将继续删除文件并更新媒体存储
旁注-范围存储、Android 10和未来
从我所看到的一切来看,这似乎表明作用域存储只在Android 11中强制实施,但我不完全确定遗留选项是否仍然可以无限期地在Android 10中使用。但我必须对此做更多的研究…尝试让我的应用程序能够删除属于该文件的音频文件
?谁把它放在那里的。安卓11对文件所有者的限制非常严格。进一步:为什么你要带着一张我们看不到的完整的清单来。为什么没有一个简单的例子尝试删除一个uri!?为什么删除任务需要实时数据和片段?“该文件属于谁?”-对于用户来说,它是一个可共享的媒体文件,而不是特定于应用程序的文件。“安卓11限制性很强…”-我理解。只是想澄清一下,安卓Q是10。“你为什么要带着一个完整的列表来”——用于批量删除。“我们看不到其中的内容”-不要认为这很重要,除非跟踪中的uri id来自内容解析程序MediaStore.Audio.Media.\u id.不想夸大这篇文章。“为什么需要实时数据和片段…”来使用startIntentSenderForResult。第一个代码块不在活动或片段中,而是在一个util类中。如果您需要有关如何删除文件的帮助,请选择一个,而不是一个完整的列表。此外,不要把生命数据和碎片弄得乱七八糟。只需发布可以复制/粘贴的简单代码即可尝试。我已将参数更改为获取单个对象而不是列表,但仍然不起作用。奇怪的是,如果我删除context.getContentResolver().delete(),然后编译并将其添加回,那么delete函数可以完美地工作(无论是否接受列表),但只在第一次删除时工作。之后,它就停止正常工作。尽管如此,我还是想出了一个似乎对安卓10和11都有效的解决方案。只是一个问题,我知道你在android 11中被强制使用作用域存储,但是requestLegacyExternalStorage在android 10中永远可用吗?至于我的解决方案,我将在明天发布(并可能关闭此线程),但我感兴趣的是看到在android 10中使用作用域存储删除文件的解决方案。安卓11不是一个问题,因为它有一个更干净的方式删除文件。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29"
tools:ignore="ScopedStorage"/>
<application
android:requestLegacyExternalStorage="true"
...