2

I use Xamarin-CrossDownloadManager (https://github.com/SimonSimCity/Xamarin-CrossDownloadManager) and I need waiting for download a file. I have this code:

private static async Task<bool> FileDownloadedTest(string LinkToFile, string PathFile)
    {
        var downloadManager = CrossDownloadManager.Current;
        CrossDownloadManager.Current.PathNameForDownloadedFile = new System.Func<IDownloadFile, string>(file => {
            return PathFile;
        });
        {
            await DeleteFile(PathFile);
            var file = downloadManager.CreateDownloadFile(LinkToFile);
            await Task.Run(() => downloadManager.Start(file, true)); //why this not wait???
        }         
        bool FileExist = await IsFileExist(PathFile);
        return FileExist;    
    }

Why it not wait for finish download action? How to do it?

On library site they wrote, that I can watch the IDownloadManager.Queue to get information when the file is downloaded. But, I don't know how to use this in my method... Can you help me?

PS: Sorry for my english, I'm still learning it ;)

luki
  • 49
  • 1
  • 9

3 Answers3

4

With that library, there is no callback or event published for when a file is finished downloading, but you can do a simple check and wait some more loop.

await Task.Run(async () =>
{
    var downloadManager = CrossDownloadManager.Current;
    var file = downloadManager.CreateDownloadFile(someFileBasedUrl);
    downloadManager.Start(file);
    bool isDownloading = true;
    while (isDownloading)
    {
        await Task.Delay(10 * 1000);
        isDownloading = IsDownloading(file);
    }
});

The IsDownloading method:

bool IsDownloading(IDownloadFile file)
{
    if (file == null) return false;

    switch (file.Status)
    {
        case DownloadFileStatus.INITIALIZED:
        case DownloadFileStatus.PAUSED:
        case DownloadFileStatus.PENDING:
        case DownloadFileStatus.RUNNING:
            return true;

        case DownloadFileStatus.COMPLETED:
        case DownloadFileStatus.CANCELED:
        case DownloadFileStatus.FAILED:
            return false;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

Re: https://github.com/SimonSimCity/Xamarin-CrossDownloadManager/blob/develop/Sample/DownloadExample/Downloader.cs#L46

SushiHangover
  • 73,120
  • 10
  • 106
  • 165
  • This loop don't stop after downloading the file. It works on your device? – luki Mar 24 '17 at 21:41
  • @luki Tested it on iOS... monitor `IDownloadFile.Status`, what is the value of `Status` after the download completes? – SushiHangover Mar 24 '17 at 21:45
  • In the loop: Debug.WriteLine(file.Status); -> RUNNING – luki Mar 24 '17 at 21:48
  • @luki Assuming you meant the method `IsDownloading(file)`...(I change the example code to accept a `IDownloadFile` parameter...) What platform are you testing on? Maybe it is a bug with the library?: https://github.com/SimonSimCity/Xamarin-CrossDownloadManager/issues – SushiHangover Mar 24 '17 at 21:53
  • I'm testing on UWP and Android. Result is the same. File is downloaded, but file.Status = RUNNING. Maybe a bug with the library it's possible - i don't know. If it true, i'll have to write own library... – luki Mar 24 '17 at 22:01
  • I noticed file.Status = INITIALIZED in first few ms atfer start(), then Status=RUNNING and it not change on COMPLETE, when file is downloaded. Have you any idea? – luki Mar 24 '17 at 22:22
  • @luki I just tested it on Android and it worked fine, ending with a status of `DownloadFileStatus.COMPLETED`... So iOS and Android are working ok for me... – SushiHangover Mar 24 '17 at 22:31
  • It's my method: https://wklej.to/6rRCS and not working for me... What I'm doing bad? PS: If i give for this method bad link to file, file.Status = FAILED, so... it's working. With normal link, not.... – luki Mar 24 '17 at 22:38
  • @luki Try it using the default tmp file location like i am instead of setting the `CrossDownloadManager.Current.PathNameForDownloadedFile`.... – SushiHangover Mar 24 '17 at 23:01
  • When i delete this line, on Windows not change, on android throw exception: https://zapodaj.net/c989c2199ee63.png.html ;/ – luki Mar 24 '17 at 23:17
1

I don't know why IDownloadFile.Status = COMPLETED not working, but i found solve problem:

await Task.Run(() =>
        {
            var downloadManager = CrossDownloadManager.Current;
            var file = downloadManager.CreateDownloadFile(LinkToFile);
            downloadManager.Start(file);
            while (file.Status == DownloadFileStatus.INITIALIZED)
            {
                while (file.TotalBytesExpected > file.TotalBytesWritten)
                {
                    Debug.WriteLine(file.Status);
                }
            }
        });         

Somebody know why DownloadFileStatus.INITIALIZED working, but DownloadFileStatus.COMPLETED not?

luki
  • 49
  • 1
  • 9
1

SushiHangover's answer above worked great, and I combined it with ACR User Dialog's package (https://github.com/aritchie/userdialogs) to show a nice loading progress screen to the user while waiting for the download to complete. This works nicely on Android (I couldn't test iOS yet).

   ...
            var downloadManager = CrossDownloadManager.Current;
            var fileToDownload = downloadManager.CreateDownloadFile(args.Url);
            downloadManager.Start(fileToDownload, true);                
            args.Cancel = true;
            UserDialogs.Instance.Progress("Downloading").Show();
            bool isDownloading = true;
            while (isDownloading)
            {
                await Task.Delay(100);
                if (fileToDownload.TotalBytesExpected > 0)
                {
                    UserDialogs.Instance.Progress().PercentComplete = (int)(fileToDownload.TotalBytesWritten / fileToDownload.TotalBytesExpected * 100);
                    Console.WriteLine(("DOWNLOAD PROGRESS: " + fileToDownload.TotalBytesWritten / fileToDownload.TotalBytesExpected * 100).ToString() + "%");
                }
                
                isDownloading = IsDownloading(fileToDownload);
            }
             UserDialogs.Instance.Progress().Hide();

            //Below code opens the download location after download has completed.
            Intent intent = new Intent(DownloadManager.ActionViewDownloads);
            intent.AddFlags(ActivityFlags.NewTask);
            Android.App.Application.Context.StartActivity(intent);
            return;
        }
    }

}

bool IsDownloading(IDownloadFile file)
{
    if (file == null) return false;

    switch (file.Status)
    {
        case DownloadFileStatus.INITIALIZED:
        case DownloadFileStatus.PAUSED:
        case DownloadFileStatus.PENDING:
        case DownloadFileStatus.RUNNING:
            return true;

        case DownloadFileStatus.COMPLETED:
        case DownloadFileStatus.CANCELED:
        case DownloadFileStatus.FAILED:
            return false;
        default:
            throw new ArgumentOutOfRangeException();
    }
}
Daniël J.M. Hoffman
  • 1,539
  • 10
  • 16