Android Tutorial Download huge files with HttpUtils2

Status
Not open for further replies.
Better to use: https://www.b4x.com/android/forum/threads/simple-progress-http-download.127214/#post-796463

The attached project includes a slightly modified version of HttpUtils2 and a new service named DownloadService. The purpose of DownloadService is to make it simple to download files of any size.

SS-2013-06-13_17.34.35.png


It is very simple to use this service.

Start a download:
B4X:
Sub btnDownload_Click
   Dim dd As DownloadData
   dd.url = link1 '<--- download link
   dd.EventName = "dd"
   dd.Target = Me
   CallSubDelayed2(DownloadService, "StartDownload", dd)
End Sub

Handle the events:
B4X:
Sub dd_Progress(Progress As Long, Total As Long)
   ProgressBar1.Progress = Progress / Total * 100
   Label1.Text = NumberFormat(Progress / 1024, 0, 0) & "KB / " & _
      NumberFormat(Total / 1024, 0, 0) & "KB"
End Sub

Sub dd_Complete(Job As HttpJob)
   Log("Job completed: " & Job.Success)
   Job.Release
End Sub

Cancel a download:
B4X:
Sub btnCancel_Click
   CallSubDelayed2(DownloadService, "CancelDownload", link1)
End Sub

DownloadService allows you to download multiple files at once and track the progress of each one of them.

The following libraries are required:
OkHttp
StringUtils
Phone (required in order to acquire a partial lock during the download)
RandomAccessFile

As this is a modified version of OkHttpUtils2 you should not reference OkHttpUtils2 library. You should instead add the three modules from the attached project. Note that the modified code is in Sub hc_ResponseSuccess.
 

Attachments

  • LargeFileDownload.zip
    11.5 KB · Views: 2,676
Last edited:

Callan

Member
Licensed User
Longtime User
Hi Erel,
The reason why I had asked this is because I am downloading comic books via xampp control panel pages and saving it to the users ext SD card and to download separate jpg's each time will be abit slow since comic books have about 28+ pages each. Is there a workaround for this. Maybe another class/library that you'll be able to suggest.
Cheers,
Callan
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
No. But you can create a server side php-script for example

call php-script from you app giving the desired name of folder. The phpscript can compress the files in that folder into one zip and returns the zip-file then.
You then need to uncompress the zip to get all images which where inside zip.
 

Callan

Member
Licensed User
Longtime User
That's abit out of my context. Thanks for the help though. I am now thinking of using Imagedownloader and have a clickevent so I could enlargen the first image and write some code for swipe gestures to move to the next image.
Do you think it'd be possible?
 

DonManfred

Expert
Licensed User
Longtime User
btw... Calling a url http://localhost will NOT call your XAMPP on your PC. Android will call a webserver ON YOUR DEVICE (it´s localhost :D)

When you want to access your xampp on pc from your app you need to call a valid url. In this case you need to call http://w.x.y.z:p/comics/...
Replace w.x.y.z with the Internetip of your PC and p with the port you are running apache.
Make sure calls to this port will be forwarded to your PC (Router, "Port forwarding")
 

Callan

Member
Licensed User
Longtime User
Great thanks for that:). Was wondering why it wasn't loading up in the app. Will get to that that right away
 

Leomar_NS

Member
Licensed User
Longtime User
Sorry for this question, but I'm still newbie to B4A and am trying to understand through programming examples and trial and error.
In LargeFileDownload, I can not set the Username and Password.
The site I'm using requires. Someone could help me please?
 

Leomar_NS

Member
Licensed User
Longtime User
Thank you for your reply. I'm learning, so I'm testing the possibilities of use. Tested with large files and small files. Everything worked fine. As for authentication: I got no where to put the code. Sorry, I'm still quite muddled with so much information.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You need to add it in DownloadService.StartDownload:
B4X:
Public Sub StartDownload(data As DownloadData)
   If jobs.ContainsKey(data.url) Then
     Log("Ignoring duplicate request.")
     Return
   End If
   Dim J As HttpJob
   J.Initialize(data.url, Me)
   '<--- add the user and password here
   Dim tag As JobTag
   tag.Initialize
   tag.data = data
   J.tag = tag
   jobs.Put(data.url, J)
   J.Download(data.url)
   If timer1.Enabled = False Then StartTimer(data.Target)
End Sub
 

deantangNYP

Active Member
Licensed User
Longtime User
hi Erel..
How should i modify this routine "Sub hc_ResponseSuccess" to use it for both of the following scenario. Please advise.. Thanks.

B4X:
'1) Scenario 1 JSON
Dim job_json As HttpJob
job_json.Initialize("JOB_Done", Me)   
job_json.Download(URLHost & "/inspections/file.json")

'2) Scenario 2 LARGE FILE
Dim dd As DownloadData
dd.url = URLHost & "/files/uploads/" & "file.zip"
dd.EventName = "dd"
dd.Target = Me
CallSubDelayed2(DownloadService, "StartDownload", dd)
 

deantangNYP

Active Member
Licensed User
Longtime User
You don't need to modify this code at all.

You should handle the complete event. If the files you are downloading are not really large then it will be simpler to use HttpUtils2 instead.

i encountered errors when using the codes without changes. What do you mean by "Complete Event"? i need to download both small and large files.
How to merge the codes together to work seamlessly for small and large files?

B4X:
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
 
 
    ''This WORKS for SMALL Files like my JSON
         '*************'*************
        Response.GetAsynchronously("response", File.OpenOutput(TempFolder, TaskId, False), _
            True, TaskId)
         '*************'*************
 
    'This WORKS for Large Files
    ' ********** Modified code *************
    Dim cs As CountingOutputStream
    cs.Initialize(File.OpenOutput(TempFolder, TaskId, False))
    Dim j As HttpJob = TaskIdToJob.Get(TaskId)
    Dim jt As JobTag = j.Tag
    jt.CountingStream = cs
    jt.Total = Response.ContentLength
    If jt.Data.url = "" Then
        Log("Job cancelled before downloaded started")
        cs.Close
    End If
    Response.GetAsynchronously("response", cs , _
        True, TaskId)
    '**************************************
End Sub
 
Last edited:

deantangNYP

Active Member
Licensed User
Longtime User
You shouldn't modify the original code. This code should work for both small and large files. However for small files it will be easier to work with HttpJob directly.
Thanks for the reply. i got error while using them in this manner:

B4X:
'1) Scenario 1 JSONDim job_json As HttpJob
job_json.Initialize("JOB_Done", Me)
job_json.Download(URLHost & "/inspections/file.json")

'2) Scenario 2 LARGE FILEDim dd As DownloadData
dd.url = URLHost & "/files/uploads/" & "file.zip"
dd.EventName = "dd"
dd.Target = Me
CallSubDelayed2(DownloadService, "StartDownload", dd)
 
Status
Not open for further replies.
Top