2014-10-09 3 views
1

Есть ли простой механизм для определения того, когда DownloadManager remove() завершен, поскольку он выглядит частично асинхронным. Функция возвращается почти мгновенно с подсчетом записей в таблице «Загрузить», которую она удаляет, но фактическое ведение домашнего хозяйства файловой системы, похоже, вставляется в некоторый фоновый поток.Android DownloadManager remove() - как определить, когда операция remove() завершается?

Проблема. Я написал немного кода, который ищет и удаляет любую существующую запись DownloadManager для файла X (и, надеюсь, объект файловой системы), прежде чем вытаскивать новую копию. К сожалению, новая копия делает это в каталоге до того, как домашняя работа файловой системы началась, для предыдущего воплощения. Таким образом, ведение домашнего хозяйства в конечном итоге удаляет новую версию в какой-то момент и оставляет запись сироты в таблице DownloadManager.

Возможно, каким-то образом блокируется до тех пор, пока не будет предпринята попытка удаления файловой системы.

Debug код:

DownloadManager.Query query = new DownloadManager.Query().setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL); 
    downloads = getAllDownloadIds(manager.query(query)); 

    path = activity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); 

    //If a file name was passed remove any existing entry/version of the file 
    if (fileName != null && ! fileName.isEmpty()){ 
     if (downloads.containsKey(fileName)){ 
      ids = downloads.get(fileName); 
      for (Long id : ids) { 
       Uri path = manager.getUriForDownloadedFile(id); 
       File checkFile = new File(path.toString()); 
       Log.e(TAG, "Removing existing file: " + path.toString() + ":" + id); 
       int entriesRemoved = manager.remove(id); 
       Log.e(TAG, "Existing files removed: " + entriesRemoved);     
      } 
     } 
    } 


... 
Log.v(TAG, "Attempting to create a file in the 'Download' directory on the external storage::" + path.toString() +"/"+ fileName); 
file = new File(path, fileName); 
Log.v(TAG, "Does the file already exist::" + file.exists()); 

Пример вывода:

… V/Export﹕ Removing existing file: file:///storage/sdcard/Download/appData.csv:101 
… V/Export﹕ Existing files removed: 1 
… V/Export﹕ Attempting to create a file in the 'Download' directory on the external storage::/storage/sdcard/Download/appData.csv 
… V/Export﹕ Does the file already exist::true 
+0

поместите ваш пункт назначения в папку temp в папку пакета внешнего хранилища и удалите его самостоятельно. – mmlooloo

ответ

1

У меня была такая же проблема - при замене небольших файлов в быстрой сети, файлы замены иногда прибывают в течение доли второй после вызова DownloadManager.remove(...) В этом случае новые файлы будут удалены.

Решение, которое я использую, до того, как я позвонил DownloadManager.remove(...), я установил FileObserver для контроля файла. Затем я вызываю remove(...), но затем дождитесь запуска события DELETE перед началом загрузки.

Это закончилось значительным количеством кода, распределенного между несколькими классами. Существуют и другие осложняющие факторы - например, я помещаю механизм тайм-аута на случай, если DownloadManager никогда не удалит этот файл. (Я не могу представить, почему это не так, но это не мой компонент).

Так что в ответ на вопрос «Есть ли простой механизм .....»: есть доступные вам механизмы, но, к сожалению, не очень легкие.

0

Способ, которым я решил эту проблему времени, - это просто удалить файл перед функцией DownloadManager.remove. Ссылка на загрузку будет удалена функцией «удалить» в любом случае.

int idFromCursor = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_ID)); 
String localPathOfFile =cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)); 
File fileToDelete= new File(localPathOfFile); 

if(fileToDelete.exists()){ 
    fileToDelete.delete(); 
} 
downloadManager.remove(idFromCursor); 

после этого больше не было проблем с синхронизацией.