Можно ли отменить/остановить загрузку, начатую с помощью DownloadManager?

Я использую DownloadManager для загрузки набора файлов в свое приложение. Я не могу понять, как отменить загрузки, поставленные в очередь менеджером загрузки.

Есть две возможности: а. Пользователь может вручную отменить его, скажем, щелкнув его на панели уведомлений. б. Отменить и удалить загрузку через код.

У меня определен следующий приемник.

<receiver 
        android:name=".DownloadStatusReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
            <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
     </intent-filter>
 </receiver> 

И в приемнике

if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) {

    Constants.showLog(TAG, "Notification clicked");
    long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
    DownloadManager dm =(DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);             
    dm.remove(downloadId);

}

Любые идеи?


person PravinCG    schedule 28.12.2012    source источник
comment
remove() должно работать, согласно документам. Конечно, похоже, вы не звоните remove() до тех пор, пока загрузка не будет завершена. Это как запирать сарай после того, как лошадь убежала. :-)   -  person CommonsWare    schedule 28.12.2012
comment
Я бы реализовал свой собственный рабочий процесс загрузки, потому что встроенный менеджер загрузок глючит и не работает на старых устройствах.   -  person vortexwolf    schedule 28.12.2012
comment
@CommonsWare: я вызываю удаление при нажатии на панель уведомлений. Я предполагаю, что событие щелчка уведомления происходит независимо от того, завершена загрузка или нет.   -  person PravinCG    schedule 29.12.2012
comment
Бьет меня. Я не играл много с щелчками уведомлений. Попробуйте поэкспериментировать с remove() чем-то, что находится под вашим контролем, например Button или элементом панели действий. Кроме того, вы подтвердили, что downloadId возвращается со значением, которое соответствует вашему первоначальному запросу?   -  person CommonsWare    schedule 29.12.2012
comment
Я починил это. Для меня я загружал несколько файлов, и они группировались вместе на одном индикаторе выполнения. Итак, теперь, как только я получаю оповещение по клику, я запрашиваю и перебираю идентификаторы и удаляю их один за другим. Работает. Единственная проблема, в которой я не уверен, это то, что она также удалит загрузки, не запущенные моим приложением.   -  person PravinCG    schedule 29.12.2012


Ответы (2)


Вы можете отменить загрузку через DownloadManager, вызвав его метод remove(long...). Для этого вам нужен ID загрузки. По моему опыту, в основном есть два надежных способа, как его получить:

  1. Запомните возвращаемое значение метода enqueue(DownloadManager.Request).
  2. Запросите DownloadManager для загрузки с помощью метода query(DownloadManager.Query). Затем извлеките идентификаторы из возвращенного Cursor, они хранятся в столбце с именем DownloadManager.COLUMN_ID.

Приемник вещания

По моему опыту, ненадежно получать ID загрузки через BroadcastReceiver для действия android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED (хотя трансляция всегда отправляется).

  1. Получение идентификаторов загрузки из дополнительных DownloadManager. EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS не работает должным образом. На некоторых устройствах он всегда возвращает ноль. Если он возвращает что-то на некоторых устройствах, это идентификатор первой загрузки. И если первая загрузка завершена/отменена, он возвращает ноль для уведомления об оставшихся загрузках.
  2. Получение значения из дополнительных DownloadManager.EXTRA_DOWNLOAD_ID не работает для этого действия.

Получение идентификатора в трансляции для действия android.intent.action.DOWNLOAD_COMPLETE кажется надежным. Вы должны получить его из дополнительных DownloadManager.EXTRA_DOWNLOAD_ID. Обратите внимание, что рассылка отправляется не только при завершенной загрузке, она также отправляется при отмене загрузки по телефону remove().

Примечание. Загрузки иногда группируются в одном уведомлении, иногда создаются несколько уведомлений. Я не смог выяснить условия, когда уведомления группируются и не группируются. Кажется, это зависит от многих факторов, таких как версия ОС, устройство, название загрузки и т. д., и в целом кажется довольно непредсказуемым.

Примечание. Я проверил, можно ли отменить загрузку другого приложения, и оказалось, что это не так. Несмотря на то, что идентификаторы являются идентификаторами базы данных, которые уникальны для всех приложений. Звонок remove() не отменяет загрузку другого приложения.

person Tomik    schedule 30.12.2012
comment
Спасибо, Томик, вы хорошо обобщили, и я согласен, что наблюдал то же самое. Я принимаю этот ответ, так как он поможет другим в будущем. - person PravinCG; 30.12.2012
comment
очень полезно. личный опыт — это всегда самое ценное, что можно предложить, вы экономите много времени. - person mmlooloo; 16.09.2014
comment
@Tomik, так как же на самом деле лучше всего получить идентификатор DOWNLOAD_NOTIFICATION_CLICKED? Я скачиваю несколько файлов одновременно, не могу сохранить все идентификаторы. - person MadDeveloper; 27.11.2014
comment
Что делать, если я не знаю идентификатор, потому что он был запущен другим приложением или экземпляром? Как закрепить все загрузки? - person djdance; 11.08.2017
comment
Ваш ответ правильный. но как начать эту загрузку снова. у вас есть какой-нибудь полный источник в качестве примера. - person Tariqul; 28.08.2017

Если вы ищете, как остановить загрузку, то я уверен, что вы знаете, как загружать данные через URL-адрес.
Я надеюсь, вы знакомы с пунктом 1, пунктом 2 и пунктом 3, и ваше решение — пункт 4.

  1. private var mgr: DownloadManager? = null
  2. private var enqueue: Long? = null
  3. enqueue = mgr?.enqueue(request)
  4. mgr?.remove(enqueue!!)
person sachin pathak    schedule 29.12.2020