安卓6.0-应用卸载时外部存储文件被删除

13
我的应用程序使用 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操作系统的设备上卸载应用程序时会删除文件(在旧的操作系统版本上不会发生这种情况)。你对此有什么想法吗?

谢谢


我可以重现这种行为。我并不是非常震惊他们会这样做,但那确实感觉像是一个退步。 - CommonsWare
2
注意,在Android 5.1(在Nexus 4上测试)中也会出现相同的行为,但在Android 4.1(在Galaxy Nexus上测试)中不会出现,因此更改发生在该范围内。 这并不是严格针对Android 6.0的。根据模拟器测试,似乎更改发生在Android 5.0中 - 4.4保留下载,而5.0则不保留。 - CommonsWare
1
@323go 这仅适用于已下载的文件。但我想知道是否也适用于使用 addCompletedDownload() 放置在那里的文件。 - tynn
1
@323go 看起来只有下载的文件才会出现这种情况。我已经实现了一个文件复制作为这个 bug 的解决方法:请注意,复制的文件需要有不同的文件名,交换是行不通的。 - Matteo Innocenti
这个有更新了吗? - Murat Karagöz
显示剩余2条评论
1个回答

5

这是通过一个名为 DownloadReceiver 的内部类实现的,该类在 com.android.providers.downloads 包清单文件 中定义。

<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),而不是一个应用程序(在删除用户后删除用户的下载内容是有意义的)。https://developer.android.com/reference/android/content/Intent.html#ACTION_UID_REMOVED - FaultException
2
@FaultException 表示它没有连接到真实用户。它是指分配给应用程序的 Linux 系统用户 ID。https://developer.android.com/guide/components/fundamentals.html - tynn
我明白了,是我的错误。 - FaultException
太棒了!干得好。 - yshahak
1
@tynn 有什么方法可以防止这种情况发生吗?我希望通过应用程序下载的文件即使应用程序被卸载,也能保留在设备的外部存储器中。 - Adomas
1
@Adomas 我不知道是否有任何官方修复此功能的方法。我一直在做的是,用另一个名称下载文件,并在 android.intent.action.DOWNLOAD_COMPLETE 广播接收器上更改文件名。这实际上保留了文件,但有点像黑客行为。如果您有其他解决方案,请告诉我。 - theapache64

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