Android Question HTTPS Download Progress bar does not work etc

johnaaronrose

Active Member
Licensed User
Longtime User
I am trying to use Erel's code from https://www.b4x.com/android/forum/t...from-server-with-progress.126797/#post-793290 post #12 in my simple B4XPages example project. The download Progress Bar & Label showing the downloaded size out of the size amount in my project do not show anything downloaded. I have a Log of the count of every 1,000 times the TrackProgress sub is entered . The log seems to show that the file is downloaded at least 1,000 times but that happens before the file is supposedly copied from available storage to the accessible (using GetSafeDirDefaultExternal). And there is no file there!
Here is the code from the relevant module:

B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private Title As String ="HTTPS"
    Private LabelTrackDownload As Label
    Private ProgressBarDownload As ProgressBar
    Private FileName As String = "HTTPSLargeFile.txt"
    Private ASFolder As String
    Private FileSize As Long
End Sub

'You can add more parameters here.
Public Sub Initialize As Object
    Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("https")
    B4XPages.SetTitle(Me, Title)
    Dim rp As RuntimePermissions
    ASFolder = rp.GetSafeDirDefaultExternal("")
    Log("Accessible Storage Folder: " & ASFolder)
    If File.Exists(ASFolder, FileName) Then
        Log(FileName & " File Exists in Accessible Storage Folder " & ASFolder)
        Log("Deleting " & FileName & " from Accessible Storage Folder " & ASFolder)
        File.Delete(ASFolder, FileName)
    End If
End Sub

Private Sub B4XPage_Appear
    LabelTrackDownload.Text = "Not Started"
    ProgressBarDownload.Progress = 0
    Wait For (DownloadAndTrackProgress) Complete (Success As Boolean)
    If Success Then
        Log("File was copied successfully")
    Else
        Log("File was not copied")
    End If
End Sub
    
Private Sub DownloadAndTrackProgress As ResumableSub   
    Dim WebServer As String = "https://johnrose.mywire.org"
    Dim WebDirectory As String = "Test"
    Dim ServerPath As String = WebServer & "/" & WebDirectory & "/" & FileName
    Log("ServerPath: " & ServerPath)
    Dim HTTPS1 As HttpJob
    HTTPS1.Initialize("", Me)
    Log("HTTPS Initialize Started")
    'For a non-https link, need to add SetApplicationAttribute(android:usesCleartextTraffic, "true") in B4A.
    HTTPS1.Download(ServerPath)
    Log("Started HTTPS")
    Sleep(0)
    Dim TaskToJob As Map = HttpUtils2Service.TaskIdToJob
    Do While HttpUtils2Service.TaskIdToJob.IsInitialized = False
        Sleep(30)
    Loop
    Log("HTTPS Initialize Finished")
    Dim TaskId As Int
    For Each Id As Int In TaskToJob.Keys
        If TaskToJob.Get(Id) = HTTPS1 Then
            TaskId = Id
            Exit
        End If
    Next
    Dim JobFinished As Boolean = False
    TrackProgress(HTTPS1, JobFinished, TaskId)
    Log("Wait For Start")
    Wait For (HTTPS1) JobDone (HTTPS1 As HttpJob)
    Log("Wait End")
    JobFinished = True
    If JobFinished = True Then
        Log("Job Finished")
    Else
        Log("Job Not Finished")   
    End If
    If HTTPS1.Success Then
        Log(HTTPS1.GetString)
        Log("File was downloaded successfully")
        Dim out As OutputStream = File.OpenOutput(File.DirInternal, FileName, False)
        File.Copy2(HTTPS1.GetInputStream, out)
        out
Logger connected to:  Blackview A80Pro
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
*** mainpage: B4XPage_Created 
*** mainpage: B4XPage_Appear 
** Activity (main) Resume **
*** https page: B4XPage_Created [mainpage]
Accessible Storage Folder: /storage/emulated/0/Android/data/org.mywire.johnrose.httpprogresssexample/files
*** mainpage: B4XPage_Disappear [mainpage]
*** https page: B4XPage_Appear [mainpage]
ServerPath: https://johnrose.mywire.org/Test/HTTPSLargeFile.txt
HTTPS Initialize Started
Started HTTPS
*** Service (httputils2service) Create ***
(Http client initialized with accept all option.)
** Service (httputils2service) Start **
HTTPS Initialize Finished
Start of TrackProgress
Track Job Not Finished
Wait For Start
Wait End
Job Finished
** First few lines of Large Text file **
Message longer than Log limit (4000). Message was truncated.
File was downloaded successfully
Accessible Storage File Size = 0KB
File was copied successfully
i=1000
i=2000
i=3000

.Close '<------ very important
    Else
        Log(HTTPS1.GetString)
        Log("File was NOT downloaded successfully")
        xui.MsgboxAsync("File was NOT downloaded successfully", Title)
        Wait For MsgBox_Result (Result As Int)
        B4XPages.ClosePage(Me)
    End If
    HTTPS1.Release   
    FileSize = File.Size(ASFolder, FileName)
    Log("Accessible Storage File Size = " & Round(FileSize / 1000) & "KB")
    ProgressBarDownload.Progress = 100
    Sleep(0)
    Return HTTPS1.Success
End Sub

Sub TrackProgress (HTTPS1 As HttpJob, JobFinished As Boolean, TaskId As Int)
    Log("Start of TrackProgress")
    Dim i As Int = 0
    Dim j As Int = 0
    If JobFinished = True Then
        Log("Track Job Finished")
    Else
        Log("Track Job Not Finished")
    End If
    Do While JobFinished = False
        If HTTPS1.Out.IsInitialized Then
            i = i + 1
            j = Floor(i/1000)*1000
            If i = j Then           
                Log("i="&i)
            End If                       
            Dim TotalSize As Long = HTTPS1.Response.ContentLength
            Dim DownloadedSize As Long = File.Size(HttpUtils2Service.TempFolder, TaskId)
            LabelTrackDownload.Text = NumberFormat(DownloadedSize, 0, 0) & " of " & NumberFormat(TotalSize, 0, 0)
            ProgressBarDownload.Progress = (DownloadedSize*100)/TotalSize
        End If
        Sleep(100)
    Loop
    Log("End of TrackProgress")
End Sub

I have 2 questions about the original code from Erel:
1. I don't understand the use of the Boolean array b to check whether the download has finished: Each element is defined with value False in DownloadAndTrackProgress. Then TrackProgress is called with array passed as a parameter. The parameter Stop(0), which has the value of b(0), is then used to loop continually in TrackProgress until its value becomes True. But it is not set to True in TrackProgress. But it is set to True after the 'Wait For' command (in Download AndTrackProgress) after the Job has Finished due the JobDone parameter in that command. I presume that this is because the TrackProgress sub will be continually invoked even after that command is executed. I guess that this is due to the way that Android code works in that code after a line of code is started even though that line of code has not finished execution. Am I correct?
2. Why use a Boolean array when only the first element is ever used rather than a Boolean variable?
 

Attachments

  • HTTPSProgressExampleLog.txt
    5 KB · Views: 244
  • HTTPSProgressExample.zip
    12.5 KB · Views: 252

Erel

B4X founder
Staff member
Licensed User
Longtime User
Am I correct?
No.

to the way that Android code works in that code after a line of code is started even though that line of code has not finished execution
No such thing.

The correct approach is to start with the example code. Try it, it will work.

Later you can debug it and understand why it works and your code doesn't.
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
@Erel I have tried the example code in a new project: zip attached. The only code that I have altered is the URL as the URL you specified of http://mirror.filearena.net/pub/speed/SpeedTest_16MB.dat gave an error of "ResponseError. Reason: java.net.UnknownServiceException: CLEARTEXT communication to mirror.filearena.net not permitted by network security policy, Response: ". So I changed the URL to https://johnrose.mywire.org/Test/HTTPSLargeFile.txt that file being 2.3MB. After waiting for 5 minutes: according to the log this seemed to resulted in the download NOT working and I was not able to find the file on my phone when I looked in the Downloads folder.


Logger connected to: Blackview A80Pro --------- beginning of main ** Service (httputils2service) Destroy ** ** Service (starter) Destroy (ignored)** Logger connected to: Blackview A80Pro --------- beginning of main *** Service (starter) Create *** ** Service (starter) Start ** ** Activity (main) Create, isFirst = true ** Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events. ** Activity (main) Resume ** *** Service (httputils2service) Create *** ** Service (httputils2service) Start ** 0, 2292481 0, 2292481 0, 2292481 0, 2292481 0, 2292481 0, 2292481 0, 2292481 ** Activity (main) Pause event (activity is not paused). **:
Logger connected to:  Blackview A80Pro
--------- beginning of main
** Service (httputils2service) Destroy **
** Service (starter) Destroy (ignored)**
Logger connected to:  Blackview A80Pro
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
0, 2292481
0, 2292481
0, 2292481
0, 2292481
0, 2292481
0, 2292481
0, 2292481
** Activity (main) Pause event (activity is not paused). **
 

Attachments

  • Test1.zip
    9.3 KB · Views: 218
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Replace DownloadAndTrackProgress with:
B4X:
Private Sub DownloadAndTrackProgress (url As String) As ResumableSub
    Dim j As HttpJob
    j.Initialize("", Me)
    j.Download(url)
    Wait For (FindTaskId(j)) Complete (TaskId As Int)
    Dim b() As Boolean = Array As Boolean(False)
    TrackProgress(j, b, TaskId)
    Wait For (j) JobDone (j As HttpJob)
    b(0) = True
    j.Release
    Return j.Success
End Sub

Private Sub FindTaskId (job As HttpJob) As ResumableSub
    Do While True
        Sleep(30)
        If HttpUtils2Service.TaskIdToJob.IsInitialized = False Then Continue
        Dim TaskToJob As Map = HttpUtils2Service.TaskIdToJob
        For Each id As Int In TaskToJob.Keys
            If TaskToJob.Get(id) = job Then
                Return id
            End If
        Next
    Loop
    Return -1
End Sub
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
2 questions:
1. The log is now showing the size of file (for my https://johnrose.mywire.org/Test/HTTPSLargeFile.txt) so far downloaded on each entry to the Sub TrackProgress after the job has been initialized. However, I don't see the downloaded file, after the download is complete, using either Google's Files app or File Manager app to inspect the Downloads folder or Internal Storage's Download folder. Where does the downloaded file get stored?
2. Is the line : 'In B4A you need to add to manifest editor: CreateResourceFromFile(Macro, Core.NetworkClearText) required, even though it's for a https download and where should it go in the Manifest?
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Where does the downloaded file get stored?
nowhere if you do not store it.
Store it after the job completes and job.success is true to anywhere you want it.
even though it's for a https download and where should it go in the Manifest?
Anywhere. Just add a new line in the manifesteditor with this content.
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
I don't understand how to store the downloaded file. Is it correct to use this command:
B4X:
Wait For (File.CopyAsync(File.DirAssets, FileName, ASFolder, FileName)) Complete (Success As Boolean)
where File.DirAssets is where the file is downloaded to and ASFolder would be defined as a string = rp.GetSafeDirDefaultExternal("") using rp as RuntimePermissions?
 
Upvote 0

teddybear

Well-Known Member
Licensed User
Where does the downloaded file get stored?
See following code in your post #1 link
B4X:
    If j.Success Then
        Dim out As OutputStream = File.OpenOutput(File.DirTemp, sFile, False)
        File.Copy2(j.GetInputStream, out)
        out.Close '<------ very important
    End If
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
How is the code related to download with progressbar?
The code does copy a file

Posts #7-9 are partly about how to copy the downloaded file so that I can access it in Android i.e. thru Google's Files or Google's./ File Manager. To me that's often a user requirement. I asked in post #9 for advice on how to copy the downloaded file as I didn't know where it is downloaded which I needed to know in order to copy it to storage. teddybear provided the answer to how to copy a file to storage in post #11.
B4X:
If j.Success Then
        Dim out As OutputStream = File.OpenOutput(File.DirTemp, sFile, False)
        File.Copy2(j.GetInputStream, out)
        out.Close '<------ very important
    End If
I set out's directory as rp.GetSafeDirDefaultExternal("") where rp is defined as RuntimePermissions, so that it would be in accessible storage. But I can't find it on my phone. In which directory will it be?
 
Last edited:
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
I've now set the folder to copy to as File.DirInternal. When I Compile&Run the app, the file is shown in the Log as copied to folder:
/data/user/0/org.mywire.johnrose.httpsexample/files
Where is that file using Google's Files / Google's File Manager apps?
 
Upvote 0
Top