Android 6.0 - файлы внешнего хранилища удаляются при удалении приложения

Мое приложение использует 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 (это не происходит в более старых версиях ОС). У вас есть идеи по этому поводу?

Спасибо


person Matteo Innocenti    schedule 04.02.2016    source источник
comment
Я могу воспроизвести это поведение. Я не очень шокирован тем, что они сделали это, но это действительно похоже на регресс.   -  person CommonsWare    schedule 05.02.2016
comment
Обратите внимание, что такое же поведение происходит с Android 5.1 (проверено на Nexus 4), но не с Android 4.1 (проверено на Galaxy Nexus), поэтому изменение произошло в этом диапазоне. Это не совсем ново для Android 6.0. Основываясь на тестировании эмулятора, похоже, что изменение появилось в Android 5.0 — 4.4 сохраняет загрузку, а 5.0 — нет.   -  person CommonsWare    schedule 05.02.2016
comment
Это происходит только для загруженных файлов или для всех файлов, помещенных в одну из общедоступных папок приложением? Если только для загруженных файлов, то быстрое копирование облегчило бы это, да?   -  person 323go    schedule 05.02.2016
comment
@ 323go это только для загруженного файла. Но интересно, это также сделано для файлов, помещенных туда с addCompletedDownload().   -  person tynn    schedule 07.02.2016
comment
@ 323go, похоже, это происходит только для загруженных файлов. Я реализовал копию файла в качестве обходного пути для этой ошибки: обратите внимание, что скопированный файл должен иметь другое имя файла, обмен не будет работать.   -  person Matteo Innocenti    schedule 07.03.2016
comment
@MatteoInnocenti, спасибо. Это хорошо знать.   -  person 323go    schedule 07.03.2016
comment
Есть новости по этому поводу?   -  person Murat Karagöz    schedule 01.06.2017


Ответы (1)


Это делается с помощью внутреннего класса с именем 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);
person tynn    schedule 07.02.2016
comment
Похоже, что это намерение относится к удаленному пользователю (UID), а не к приложению (имело бы смысл удалить загрузки пользователя после удаления его пользователя). developer.android.com/reference/android/content/ - person FaultException; 11.08.2016
comment
@FaultException Он не подключен к реальному пользователю. Это относится к идентификатору пользователя системы Linux, назначенному приложению. developer.android.com/guide/components/fundamentals.html - person tynn; 11.08.2016
comment
Я понимаю. Моя ошибка. - person FaultException; 11.08.2016
comment
Отличная находка! Хорошая работа. - person yshahak; 28.09.2016
comment
@tynn Есть ли способ предотвратить эту активность? Я хочу, чтобы файлы, загруженные через приложение, оставались во внешней памяти устройства, даже если приложение было удалено. - person Adomas; 19.11.2016
comment
@ Адомас Я не знаю, есть ли официальное исправление для этой функции. Что я делал, так это загружал файл с другим именем и менял имя файла на android.intent.action.DOWNLOAD_COMPLETE приемнике bcast. на самом деле он сохраняет файл, но что-то похоже на взлом. Если у вас есть другое решение, пожалуйста, дайте мне знать. - person theapache64; 28.12.2016