Android 6.0 - 卸载应用程序时删除的外部存储文件

Posted

技术标签:

【中文标题】Android 6.0 - 卸载应用程序时删除的外部存储文件【英文标题】:Android 6.0 - external storage files being deleted upon app uninstall 【发布时间】:2016-05-14 13:23:40 【问题描述】:

我的应用使用 DownloadManager 将文件下载到设备音乐文件夹的子目录中。

DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
...
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + "/MyStuff/song.mp3");
request.setDestinationUri(Uri.fromFile(file));

我注意到,当从运行 Marshmallow 的设备上卸载应用程序时,这些文件会被删除(旧操作系统版本不会发生这种情况)。 您对此有什么想法吗?

谢谢

【问题讨论】:

我可以重现这种行为。我对他们这样做并不感到非常震惊,但这确实感觉像是一种倒退。 请注意,android 5.1(在 Nexus 4 上测试)会发生相同的行为,但在 Android 4.1(在 Galaxy Nexus 上测试)则不会,因此变化发生在该范围内。它对 Android 6.0 来说并不是严格意义上的新功能。根据模拟器测试,Android 5.0 似乎发生了变化——4.4 保留下载,5.0 没有。 这种情况只发生在下载的文件上,还是应用程序放置在某个公共文件夹中的所有文件上?如果仅用于下载的文件,那么快速复制会缓解这种情况,是吗? @323go 仅适用于下载的文件。但我想知道它是否也适用于带有addCompletedDownload() 的文件。 @323go 它似乎只发生在下载的文件中。我已经实现了文件复制作为解决此错误的方法:请注意,复制的文件需要具有不同的文件名,交换将不起作用。 【参考方案1】:

这是由一个名为 DownloadReceiver 并在 com.android.providers.downloads package manifest 中定义的内部类完成的

<receiver android:name=".DownloadReceiver" android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        <action android:name="android.intent.action.UID_REMOVED" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_MOUNTED" />
        <data android:scheme="file" />
    </intent-filter>
</receiver>

android.intent.action.UID_REMOVED 动作在这里引人注目。它是在 Lollipop 中引入的,触发了对 handleUidRemoved() 的调用

resolver.delete(ALL_DOWNLOADS_CONTENT_URI, Constants.UID + "=" + uid, null);

【讨论】:

这个意图似乎是指删除的用户 (UID),而不是应用程序,(删除用户后删除用户的下载是有意义的。)developer.android.com/reference/android/content/… @FaultException 它没有连接到真实用户。它是指分配给应用程序的 Linux 系统用户 ID。 developer.android.com/guide/components/fundamentals.html 我明白了。我的错。 @tynn 有什么办法可以阻止这种活动?我希望通过应用程序下载的文件即使在应用程序被卸载后仍保留在设备的外部存储器中。 @Adomas 我不知道这个功能是否有任何官方修复。我一直在做的是,用另一个名称下载文件并在android.intent.action.DOWNLOAD_COMPLETE bcast 接收器上更改文件名。它实际上保留了文件,但有些听起来像是 hack。如果您有任何其他解决方案,请告诉我。

以上是关于Android 6.0 - 卸载应用程序时删除的外部存储文件的主要内容,如果未能解决你的问题,请参考以下文章

在Android上,我在哪里存储将在卸载应用时自行删除的文件

Android M 6.0 - SecurityException 试图删除帐户

Android中使用SQLite的外键约束?在删除级联

我的vc 6.0 可以编译,可用链接,点击执行,显示ready,但弹不出黑框

如何用Inno编译卸载时删除整个文件夹

Android 6.0 删除无用功能