Android Question [SOLVED] AppUpdating 2.0 error IsValidComplete not start

makis_best

Well-Known Member
Licensed User
Longtime User
Hi

I try to run in my application the AppUpdating 2 library
When I run the application I get one error in line ApkUpdt.ReadWebVN

The error I get says
B4X:
Activity Height: 752 - Activity Width: 1280
17
sending message to waiting queue of uninitialized activity (subscribetotopics)
SDK#: 25 - UseFP: true - SharedFolder: /data/user/0/gr.long.view/files/shared
---- AppUpdating.ReadCurVN
    Current Version: 1.32
UpdateComplete - time: 18:34:00
Running apk version: 1.32
---- AppUpdating.ReadWebVN
IsValidComplete start
before
Error occurred on line: 121 (cl_appupdate)
java.lang.NumberFormatException: empty String
    at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1071)
    at java.lang.Double.parseDouble(Double.java:547)
    at anywheresoftware.b4a.debug.RDebugUtils.numberCast(RDebugUtils.java:58)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
    at anywheresoftware.b4a.shell.DebugResumableSub$RemoteResumableSub.resume(DebugResumableSub.java:22)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
    at anywheresoftware.b4a.BA$2.run(BA.java:387)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6186)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)

I check my long.inf file and the format is UTF8.
Inside the file for the moment I have
B4X:
ver=1.33
<ChangeLog>
1) Auto update 1
2) Auto update 2
</ChangeLog>
<FileSize>
1456777
</FileSize>

Anything else I can check?

Thank you.
 

udg

Expert
Licensed User
Longtime User
Could it be a timeout when reading your config file?
I ask this because, as you can see, sub IsvalidWV logs "before-after" surrounding the wait for instruction used for downloading it and the error (an empty string where a number is expected) appears before the "after" log string.

Please try with setVerbose(True) at lib initialization. This will show us in log what's exactly is received from the server.

ps: config file look ok to me
 
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
I have
B4X:
ApkUpdt.Verbose = True

But nothing else show on the log.
When I execute on Chrome my URL
B4X:
http://www.xxxxx.com/free_apk/long.inf
The contents of the file come out correctly and fast
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Could it be that you try to read getWebVN before the download and parsing of the config file is complete?
The error refers to line 121 which is where the version number extracted from the config file should be returned (and obviously an empty string isn't a valid value)
This explains why we don't see the "after" log and the following log string too:
If sVerbose Then Log($"Webserver's info file content: ${CRLF}${J.GetString}"$)
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Last edited:
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
Could it be that you try to read getWebVN before the download and parsing of the config file is complete?
The error refers to line 121 which is where the version number extracted from the config file should be returned (and obviously an empty string isn't a valid value)
This explains why we don't see the "after" log and the following log string too:
If sVerbose Then Log($"Webserver's info file content: ${CRLF}${J.GetString}"$)

I don't exactly understand what you mean...
The *.inf file downloaded and opened inside phone?
 
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
Need to open a layout like example do or I can open my application
Layout and then execute the "Steps" (as in example) one by one?
 
Upvote 0

udg

Expert
Licensed User
Longtime User
No need to follow the example as is; just keep the exposed concepts.
If I correctly understood a previous message of you, you'd like to load different layouts based on the success/fail test about a new version of your app.
So, you use lib's functions to:
1. read current version from running app
2. read remote (web) version from your config file
3. compare the two values and decide which layout to show.

The only critical point is that each AU function returns a status (int variable) in sub xxx_UpdateComplete (xxx is the name you gave it as second parameter for AU.Initialize)
and before you can execute step 3 you have to be sure that preceding steps returned no errors.

To reply to your post #6 above: yes, the lib downloads your config file, parse it and set internal variable for WebVN. But since it looks the download never completes, that var remains set to an empty values, so the error about the wrong format.
My comment was about the possibility that you execute step2 and step3 one after the other, not waiting for step2 to be properly completed (we should expect an error due to failing download)

Sincerely, reading the post by @DonManfred I thought that was the right solution. A clear cause because the server don't come back (or at least it should fail somehow and something should show in the logs).

Anyway, do you mind to publish some code from your Main so we can see how the flow is organized? Even the whole Main, if possible. Obviously you can modify critical data as webiste/username/password.

Note: since today is the last day before another not clearly defined lockdown, I will spend the day at the beach and so won't be able to be back to you before this evening. I am sure that others would help in the meantime. This is a gret community.
 
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
Here some of the code I have on Main.
Some code left out but the way it is like that.

B4X:
If FirstTime = True Then
        Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_ACCESS_FINE_LOCATION)
        Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
        If Result Then
            StartService(Tracker)
        Else
            ToastMessageShow("No permission...", True)
        End If
   
        G1.Initialize
        ImeKeyboard.HideKeyboard
        ImeKeyboard.Initialize("")
        Drawer.Initialize(Me, "Drawer", Activity, 250dip)
        Drawer.CenterPanel.LoadLayout("1")
        ACToolBarLight1.Title = "View"
        ACToolBarLight1.SubTitle = "Version - (" & Application.VersionName & ")"
        SyncBtn.Initialize("SyncBtn")
        SyncBtn.Typeface = Typeface.MATERIALICONS
        SyncBtn.Text = ""
'        SyncBtn.Text = "Show Table"
        ACToolBarLight1.AddView(SyncBtn, 150dip, 50dip, Gravity.RIGHT)
        RemoteSync.Initialize("RemoteSync")
        RemoteSync.Text = "Remote Sync"
        LocalSync.Initialize("LocalSync")
        LocalSync.Text = "Refresh"
        ToolbarHelper.Initialize
        ToolbarHelper.ShowUpIndicator = True 'set to true to show the up arrow
        Menu.addMenuItem3(RemoteSync).addMenuItem3(LocalSync).triggerOnAnchorClick(True).build
        Dim bd As BitmapDrawable
        If G1.IsNightMode = True Then
            bd.Initialize(LoadBitmap(File.DirAssets, "hamburger.png"))
        Else
            bd.Initialize(LoadBitmap(File.DirAssets, "hamburger-dark.png"))
        End If
        ToolbarHelper.UpIndicatorDrawable =  bd
        ACToolBarLight1.InitMenuListener
        Drawer.LeftPanel.LoadLayout("Left")
        Panel1.SetBackgroundImage(LoadBitmap(File.DirAssets, "headonlylogo48x48.png"))
        G1.TheLeftMenu(ListView1)
End If
    '   ==================================   Check for Update   ========================================
    Wait For CheckInstallationRequirements (index As Int)
    If index <> DialogResponse.CANCEL Then
        ApkUpdt.DownloadApk 'send out command; async result in update_UpdateComplete
        Wait For (CheckInstallationRequirements) Complete (Result As Boolean)
        ApkUpdt.InstallApk(Result)  'send out command; async result in update_UpdateComplete
    End If
    If FirstTime Then
        ApkUpdt.Initialize(Me,"update")               'initializes the class
        ApkUpdt.Verbose = True                    'this one affects the verbosity of the logs
    End If
    'ALWAYS NEEDED - this is your app's package name (see "Project/BuilConfigurations/Package")
    ApkUpdt.PackageName = "gr.iosif.droidview"
    'ALWAYS NEEDED - this is the complete path to the info text file holding the newer version number
    ApkUpdt.NewVerTxt = "https://www.xxxx.com/free_apk/long.inf"
    'ALWAYS NEEDED - this is the complete path to your newer apk
    ApkUpdt.NewVerApk = "https://www.xxxx.com/free_apk/view.apk"
    'OPTIONAL - Set credentials to access a protected folder. Not needed for this example
    'ApkUpdt.setCredentials("test","test")
   
    ' Step 1. Read version number of currently executing apk
    ApkUpdt.ReadCurVN  'send out command; async result in update_UpdateComplete

    ' Step 2. Read version number as showed in txt file on webserver
    ApkUpdt.ReadWebVN 'send out command; async result in update_UpdateComplete
   
    If ApkUpdt.CurVN < ApkUpdt.WebVN Then 'compares current version number to the one reported by the webserver. Must follows steps 1 and 2. Assuming no errors in steps 1 and 2
        Msgbox2Async("New version", "Alert!!!", "Yes", "", "No", Null, False)
        Wait For Msgbox_Result (index As Int)
        If index <> DialogResponse.CANCEL Then
            ApkUpdt.DownloadApk 'send out command; async result in update_UpdateComplete
            Wait For (CheckInstallationRequirements) Complete (Result As Boolean)
            ApkUpdt.InstallApk(Result)  'send out command; async result in update_UpdateComplete
        End If
    End If
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi, I'm back.
Looking at code in your post #10 above, as a first step you should remove lines 42-47.
Insert after current line 65 a couple of logs, one for ApkUpdt.CurVN and another for ApkUpdt.WebVN. These will let you know whether the values for current and new version are read correctly. And a third log as "Log(ApkUpdt.getStatus)" that will print an integer that should be 2 at this stage.

Let's see what the logs show.
 
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
Hi, I'm back.
Looking at code in your post #10 above, as a first step you should remove lines 42-47.
Insert after current line 65 a couple of logs, one for ApkUpdt.CurVN and another for ApkUpdt.WebVN. These will let you know whether the values for current and new version are read correctly. And a third log as "Log(ApkUpdt.getStatus)" that will print an integer that should be 2 at this stage.

Let's see what the logs show.
I make the changes you told me and Log($"WebVN : "$ & ApkUpdt.WebVN) return empty string.
I can't get it...
 
Last edited:
Upvote 0

udg

Expert
Licensed User
Longtime User
There are two ways to solve the problem without applying changes to the lib's code:
1. make each step a resumablesub in Main and call them by waitfor (I suggested this before, altough I can't recall the thread)
2. modify UpdateComplete in a way similar to the following (probably I suggested this alternative too); in Main just call ApkUpdt.ReadCurVN and delete all the other rows relating to calling subs in the lib. What happens is that the chain of events started by ReadCurVN will be regolated by positive statuses in UpdateComplete

B4X:
Sub update_UpdateComplete
    LogColor($"UpdateComplete - time: ${DateTime.Time(DateTime.Now)}"$, 0xFF556B2F)
    'too lazy to manage error conditions..check apkupdt.ERR_xxx codes if you like
    Select apkupdt.Status
        Case apkupdt.OK_CURVER
            Log($"Running apk version: ${apkupdt.CurVN}"$)
            ApkUpdt.ReadWebVN
        Case apkupdt.OK_WEBVER
            Log($"Webserver apk version: ${apkupdt.WebVN}$"$)
            If ApkUpdt.CurVN < ApkUpdt.WebVN Then
               Msgbox2Async("New version", "Alert!!!", "Yes", "", "No", Null, False)
               Wait For Msgbox_Result (index As Int)
               If index <> DialogResponse.CANCEL Then ApkUpdt.DownloadApk 
            end if
        Case apkupdt.OK_DOWNLOAD
             Wait For (CheckInstallationRequirements) Complete (Result As Boolean)
             ApkUpdt.InstallApk(Result) 
        Case apkupdt.OK_INSTALL
           Log($"User asked to install newer version"$)
        Case apkupdt.ERR_NOPERM
            Log("No permission to install")
        Case Else
            Log($"Status: ${apkupdt.Status}"$
    End Select
End Sub
Note: if you go this way, remember to manage lib's error codes too (since each failing step will stop the chain of events and you should have a a way to properly react and inform the user)
 
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
I also notice in my log the line
SDK#: 25 - UseFP: true - SharedFolder: /data/user/0/com.stat.view/files/shared
but when I try to go to that path with file explorer folder shared not exist.
 
Upvote 0

udg

Expert
Licensed User
Longtime User
That path is in DirInternal.
That line is "printed" to log by AU. Initialize as its last action.
It means:
- SDK used is #25 (phone.SdkVersion)
- Use File Provider : true
- Shared Folder: File.Combine(File.DirInternal, "shared")

Share Folder is where the temporary downloaded file is saved
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Yes, it's created by AU.Initialize. I don't know if the file explorer is allowed to look at that area. File Provider is the safe way to access files on more recent versions of Android (that's the reason is used in the lib).

Note: my dinner is ready. I'm not sure I'll be able to check later. Eventually post logs following the last modifications suggested and I'll surely look at them tomorrow morning. Have a nice evening.
 
Last edited:
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
I just finish trying your suggestion with ResumableSub but nothing change.
Keep getting the same error.
I also notice code passing through without waiting ApkUpdt.ReadWebVN.
Like ApkUpdt.ReadWebVN never execute.
Also Log(ApkUpdt.getStatus) before and after ApkUpdt.ReadWebVN it is always 1.
 
Last edited:
Upvote 0

udg

Expert
Licensed User
Longtime User
Also Log(ApkUpdt.getStatus) before and after ApkUpdt.ReadWebVN it is always 1.
That confirms that ReadWebVN is not executed (or completed) since status=1 means OK_CURVER (current version read correctly) and it's set by previous step (ReadCurVN)

Did you try the specially crafted UpdateComplete from post #13?
Or did you rewrtite what was in demo are buttons' clicks as resumables and called them by wait for? Do you mind to publish your most recent attempt (and logs)?
 
Upvote 0

makis_best

Well-Known Member
Licensed User
Longtime User
This is the new code I have now.
The message on error log are the same.
B4X:
    Wait For (CallSub(Me, "ReadCurVN")) complete  'send out command; async result in update_UpdateComplete
    Log(ApkUpdt.getStatus)

    ' Step 2. Read version number as showed in txt file on webserver
    Log($"WebVN : "$ & ApkUpdt.WebVN)
    Wait For (CallSub(Me, "ReadWebVN")) complete 'send out command; async result in update_UpdateComplete
    Log($"WebVN : "$ & ApkUpdt.WebVN)

    If ApkUpdt.CurVN < ApkUpdt.WebVN Then 'compares current version number to the one reported by the webserver. Must follows steps 1 and 2. Assuming no errors in steps 1 and 2
        Msgbox2Async("Υπάρχει νέα έκδοση για εγκατάσταση. Να προχωρήσω στην εγκατάσταση της νέας εφαρμογής;", "Προσοχή!!!", "Ναι", "", "Όχι", Null, False)
        Wait For Msgbox_Result (index As Int)
        If index <> DialogResponse.CANCEL Then
            ApkUpdt.DownloadApk 'send out command; async result in update_UpdateComplete
            Wait For (CheckInstallationRequirements) Complete (Result As Boolean)
            ApkUpdt.InstallApk(Result)  'send out command; async result in update_UpdateComplete
        End If
    End If
    '   ==================================   Check for Update   ========================================
   
End Sub

Sub ReadWebVN As ResumableSub
    Return ApkUpdt.ReadWebVN
End Sub

Sub ReadCurVN As ResumableSub
    Return ApkUpdt.ReadCurVN
End Sub

If I try to download with the code

B4X:
    Wait For (DownloadAndSave("https://www.xxxxx.com/free_apk/long.inf", File.DirDefaultExternal & "/shared", "long.inf")) Complete (Success As Boolean)
    If Success Then
        Log("ok then")
    End If
  
    Sub DownloadAndSave (Url As String, Dir As String, FileName As String) As ResumableSub
    Dim j As HttpJob
    j.Initialize("", Me)
    j.Download(Url)
    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        Dim out As OutputStream = File.OpenOutput(Dir, FileName, False)
        File.Copy2(j.GetInputStream, out)
        out.Close
    End If
    j.Release
    Return j.Success
End Sub

The file downloaded correctly
Any other idea?
 
Last edited:
Upvote 0
Top