DownloadTask is unexecutable on android

I wrote a thread for download some video to my storage. The video was created but with 0 bytes. Code:

DownloadThread::run() {
    std::unique_ptr<juce::URL::DownloadTask> taskProgress = download_url.downloadToFile(dest_file);
    if (taskProgress)
    {
        while (taskProgress->isFinished() == false)

… and the taskprogress is nullptr. And when I run the same code on my computer, everything is fine.
What is going on? Is there anything special with this on android?

Thank you guys.

If the taskProgess pointer is null, it looks like that’s either because:

  • the system failed to open the file for writing, or
  • creating a native input stream for the URL failed.

If you’re able to download the resource at the provided URL from other systems, then my guess is that the file is not writable for some reason. What value are you using for dest_file? Note that, when targeting recent API levels, the locations that can be written using standard file paths are limited. Writing to the ‘home directory’ special location should work, but writing to the downloads folder or to shared storage is likely to fail.

To work around the file writing restrictions, you might find the AndroidDocument class helpful. Instances of this class can be constructed from content URLs, such as those returned by the native file chooser. To download a file to shared storage, you’d need to:

  • Show a native file picker so that the user can choose where to save the file.
  • Use downloadToFile to download the file to a temporary file in a safe location.
  • Once the download has finished, copy the file to the location selected by the user, then delete the temporary file.
  • Its not possible, because it would be a background work, dont want to show this process for the user.
  • before the thread I do the following operation:
tmp_dir_main = File::getSpecialLocation(juce::File::SpecialLocationType::userMoviesDirectory).getChildFile("VIDEOCREATOR");

        if (!tmp_dir_main.exists()) {
            tmp_dir_main.createDirectory();
        }

I create a directory where the program should write the background videos and after that I add to this location the name of the downloadable file with .getChildFile("name.mp4") and this path is what the thread get as dest_file.

Which locations are “safe locations”? I tried this method with every possible path, with root and every built-in speciallocation namespaces and I get the same results.

THE MAIN POINT: I can create a directory without problem with the code you can see above.

Thanks for you answer.

You might be able to get away with juce::File::getSpecialLocation depending on your use case, but if you need to know the full context: Data and file storage overview  |  Android Developers

You will also need to first set the enablement of these permissions up for you project. In the Projucer, the initial enablement is done at the root Android configuration (scroll down):

Then, you may need to request read/write permissions from the user (this should be checked at runtime because users can disable permissions while the app runs - by putting it in the background): JUCE: RuntimePermissions Class Reference.

Yes, I can also reproduce this behaviour. This doesn’t change the fact that Android prevents applications from writing files to these locations as a security precaution.

In my testing, the system allowed writes to subdirectories of SpecialLocationType::userDocumentsDirectory, so perhaps you could try that. If you need the files to be visible to the user in shared storage, then you must use the procedure I described above: open a native file chooser to allow the user to pick where the file(s) should be saved, and use AndroidDocument to write to this location. Again, this is a restriction put in place by Android, so it cannot be circumvented by JUCE.

Just found the reason, the link was pointing to a GET request, I only can download a video when its exactly a .mp4 file. So it wasn’t caused by android, however on windows it just worked.