B4A Library AppUpdating - automate apps updating from a webserver

Status
Not open for further replies.

udg

Expert
Licensed User
Hi, didn't see your thread 'till now, sorry.
Since the problem you experience could be specific to that installation I'll try to support you posting in the thread you mentioned.

udg
 

Olimpias Knitting Serbia

New Member
Licensed User
For anyone who have problems setting it up. Here is a little example. It updates itself from 1.0 to 1.2 after click on a button.
Hello Don,
I have some problems, I have some unknown members can you help me?

-apkupdt.NewVerAvailable
-apkupdt.IsDone
-apkupdt.LookForNewVersion

Thank you, also really nice lib.
Best Regards
 

udg

Expert
Licensed User
Hi OKS,

can you describe in more detail which is the problem you're experiencing?
Please, be sure to specify which version of the lib you are using. Thank you.

udg
 

johndb

Active Member
Licensed User
Is there any thought about upgrading this app updating system to utilize Firebase storage?

Regards,

John
 

udg

Expert
Licensed User
Hi John,

unfortunately I am lagging behind with upgrades.
My plans are that once on vacations I could at least take it offcially to okHttp/okHttpUtils and satisfy a few requested posted above.
Then I have the "dynamic broadcast" fork to build since that is a need a feel from some time now.
Oh..and I have to renew my B4A license too!

Anyway, how will you suggest to use the FB storage? AppUpdating was intended to "avoid" dependencies on Google by publishing an app on a general-purpose site and having iy updated at will. Please feel free to add your considerations here. I always read with interest and pleasure any comment and suggestion.

udg
 

Pisinho

Active Member
Licensed User
Hi Umberto,
in your Tutorial in the first page/post, you write this code:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
     ... 'any specific code for your app initialization
   End If
   Activity.LoadLayout("Main")
   .... 'more stuff
   If FirstTime Then
     apkupdt.Initialize(Me,"tab1")                   'tab1 has no meaning; use any name you like
     'this is yor app's package name (see "Project/Package name")
     apkupdt.PackageName = "eu.dgconsulting.tmb"
     'this is the complete path to the text file holding the newer version number  
     apkupdt.NewVerTxt = "http://umbetest.web44.net/p_apk/tmb.txt" 
     'this is the complete path to your newer apk
     apkupdt.NewVerApk = "http://umbetest.web44.net/p_apk/tmb.apk"
     apkupdt.UserName = "test"         'needed since folder p_apk has access restrictions
     apkupdt.UserPassword = "test"    'as above
     'not needed- just to show use of function GetCurVN
     Log("I am version: " & apkupdt.GetCurVN)
     'use only if you like to show a splash screen while update checking goes on
     apkupdt.SetAndStartSplashScreen(Activity,LoadBitmap(File.DirAssets, "tmb0.png"))
     'this function starts checking for any newer version of the current app
     apkupdt.LookForNewVersion                                                      
  End If
End Sub
when compile is varous error because the member for example apkupdt.LookForNewVersion or apkupdt.IsDone unknown.

Where find a complete tutorial similar at this...? Thanks in advance
 

udg

Expert
Licensed User
Hi @Pisinho (and others),

I read with greater attention your post now and the solution is, luckily, very simple:
the code shown on post #2 is outdated!
As explained on post #1 AppUpdating version 1.25 introduced a few modifications that broke existing code so everyone was invited to read notes from post #60 on (particulary, post #62 substitutes post #2 as a glimpse on how to use the lib).

Version 1.26 introduced minor changes and it is complete of source code and a demo you may refer to (you may download all the files from post #1).
As stated a few weeks ago, I plan to publish version 1.30 in a few days. Its main goal will be to switch to OkHtpp libs and include a few suggestions collected so far.

BTW, the hoster for domain web44.net (a free one) changed its configuration in a way that the apk extension is no more allowed so for AppUpdating's new release I'll use a different server to run the demo app.

udg
 
Last edited:

udg

Expert
Licensed User
Hi all,
you won't believe it but finally I had some time to update my lib! Please download all relevant files from post #1.
Version number jumped from 1.26 to 1.30 due to a few experiments and personalized versions; this is simply to say that you didn't miss any valuable update.

So, what's new with version 1.30? Not so much, but it now finally makes use of okHttp (version 1.01) and okHttpUtils2 (version 2.20).
A word of caution: AppUpdating version 1.30 was compiled with B4A 4.30, so you may want to recompile it from its source code.

I tried to replicate problems from posts #198 (missing info file) and #211 (version row with wrong format) but wasn't able to crash the app.

As soon as possible I will align AppUpdatingLFD (the Large File Download counterpart) to this same version 1.30.

AutoUpdate example code now refers to a different server of mine. The change was mainly due to previous hoster having changed its server configuration in a way that ".apk" files became unreachable. This note may comes handy if suddenly you experience a similar, unexpected behaviour..


udg
 
Last edited:

Harris

Expert
Licensed User
Hi all,
you won't believe it but finally I had some time to update my lib! Please download all relevant files from post #1.
Version number jumped from 1.26 to 1.30 due to a few experiments and personalized versions; this is simply to say that you didn't miss any valuable update.

So, what's new with version 1.30? Not so much, but it now finally makes use of okHttp (version 1.01) and okHttpUtils2 (version 2.20).
A word of caution: AppUpdating version 1.30 was compiled with B4A 4.30, so you may want to recompile it from its source code.

I tried to replicate problems from posts #198 (missing info file) and #211 (version row with wrong format) but wasn't able to crash the app.

As soon as possible I will align AppUpdatingLFD (the Large File Download counterpart) to this same version 1.30.

AutoUpdate example code now refers to a different server of mine. The change was mainly due to previous hoster having changed its server configuration in a way that ".apk" files became unreachable. This note may comes handy if suddenly you experience a similar, unexpected behavior..


udg
My app doesn't use okHttp or okHttputils2... (too busy to update all sections that works fine now..).
Previous ver is getting updates to device - as desired (works fine).
Shall I stay at my current ver or upgrade and add these libs (and modify what I need to since I hacked the previous to accommodate my specific needs)?

Real Question: Is there a significant advantage to update at this time? My time is very limited (plenty of dev time - yet it generates no money).

BTW...
I notice that some times, my app downloads the 5 meg update in (about) 2 seconds, where as other times it takes up to 30 seconds (over wifi) - same distance from AP.
It is hard to believe that it got the 5 meg update in that time yet it it installs it just fine...
go figure...

Thanks
 

udg

Expert
Licensed User
Hi @Harris ,

in my opinion you have no reason to upgrade. Since you may have large files, you may want to test AppUpdatingLFD when some spare time arises.
There a version of it (based on 1.26 code) in post #105. That's the one I'll take to 1.30 (so basing it on okHttp) asap.

udg
 

Declan

Well-Known Member
Licensed User
I am basing my app on your example V1.30 with B4A V6.00.
My connection to my server is:
B4X:
apkupdt.NewVerTxt = "http://197.189.XXX.XXX/eBuki/Updates/AppUpdateEbuki.txt"
On my server in folder:
C:\eBuki\Updates I have a text file: "AppUpdateEbuki.txt" that has "ver=1.02".
When I click "Get Web Version" button, I get the following error:
B4X:
Status: -100
I have changed the syntax on the HTTP connection string, but still have the error?
 

udg

Expert
Licensed User
Hi @Declan

Status = -100 is caused by httputils (any reason, from connection refused to file not found).
In my experience, the folder containing files to be served by the webserver should be located in the root path of it. I mean that if the webserver at address 197.189.xxx.xxx has its root at c:\xampp\htdocs then it is able to serve files from folders like c:\xampp\htdocs\eBuki\Updates.

I am not 100% sure of the above, but try to copy the exact string from apkupdt.NewVerTxt to the URL bar in your browser. If the browser can reach the file so should the lib. Let me know.

udg
 

Declan

Well-Known Member
Licensed User
Hi @Declan

Status = -100 is caused by httputils (any reason, from connection refused to file not found).
In my experience, the folder containing files to be served by the webserver should be located in the root path of it. I mean that if the webserver at address 197.189.xxx.xxx has its root at c:\xampp\htdocs then it is able to serve files from folders like c:\xampp\htdocs\eBuki\Updates.

I am not 100% sure of the above, but try to copy the exact string from apkupdt.NewVerTxt to the URL bar in your browser. If the browser can reach the file so should the lib. Let me know.

udg
Thanks, after Googling into the unknown.......I finally have the solution.
My server is a Windows Server 2008R2 with IIS7.
I had to create a "virtual folder" and point that to my physical folder which has the "AppUpdateEbuki.txt" file.

This was all very confusing and I have attached the links below to hopefully assist anyone who runs into this problem:
Also, don't forget to add the MIME type - "application/android":
 
Last edited:
  • Like
Reactions: udg

Declan

Well-Known Member
Licensed User
In order to check that my app is running correctly, I have the following:
Application on device: #VersionName: 1.01
Within text file on server: ver=1.02
All OK and app downloads and installs the server version (1.02).

However, when I change the text file on server back to: ver=1.01
to ensure that the the app on the server is not downloaded and installed as both versions are 1.01.

The app reads the server version as 1.02, as shown:
B4X:
** Activity (main) Pause, UserClosed = false **
** Activity (appupdate) Create, isFirst = true **
---- AppUpdating.ReadCurVN
    Current Version: 1.01
---- AppUpdating.ReadWebVN
** Activity (appupdate) Resume **
** Service (httputils2service) Create **
** Service (httputils2service) Start **
---- AppUpdating.JobDone --
    JobName = JobWebVNonly, Success = true
    Read while in JobWebVNonly: ver=1.02
    Web version number: 1.02
webvnl: 4
 

techknight

Well-Known Member
Licensed User
I have noticed a bug thats driving me nuts.

---- AppUpdating.ReadCurVN Hangs, and never fires the event if I reopen the app.

If I kill the app and restart it from scratch, it works.

But When it works, I get this:

B4X:
---- AppUpdating.ReadCurVN
UpdateComplete - time: 11:09:07
Running apk version: 4.15
---- AppUpdating.ReadWebVN
** Service (httputils2service) Create **
** Service (httputils2service) Start **
---- AppUpdating.JobDone --
UpdateComplete - time: 11:09:08
Webserver apk version: 4.16
Optional Change Log data: 
V4.1.6: 
Added support for automatic updating. 
---- AppUpdating.UpdateApk
---- AppUpdating.JobDone --
    -- JoWebVNcompare
    -- ApkUpdate
---- AppUpdating.JobDone --
    Error: java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
UpdateComplete - time: 11:09:57
Status: -100
** Activity (main) Pause, UserClosed = true **
** Service (servicemain) Destroy **
** Service (servicetxrx) Destroy **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Service (servicemain) Create **
** Service (servicemain) Start **
releasing KeepAlive
No wakelock.
turning screen on
using partialLock
** Service (servicetxrx) Create **
** Service (servicetxrx) Start **
---- AppUpdating.ReadCurVN
HANGS HERE....
 

techknight

Well-Known Member
Licensed User
I have noticed a bug thats driving me nuts.

---- AppUpdating.ReadCurVN Hangs, and never fires the event if I reopen the app.

If I kill the app and restart it from scratch, it works.

But When it works, I get this:

B4X:
---- AppUpdating.ReadCurVN
UpdateComplete - time: 11:09:07
Running apk version: 4.15
---- AppUpdating.ReadWebVN
** Service (httputils2service) Create **
** Service (httputils2service) Start **
---- AppUpdating.JobDone --
UpdateComplete - time: 11:09:08
Webserver apk version: 4.16
Optional Change Log data:
V4.1.6:
Added support for automatic updating.
---- AppUpdating.UpdateApk
---- AppUpdating.JobDone --
    -- JoWebVNcompare
    -- ApkUpdate
---- AppUpdating.JobDone --
    Error: java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
UpdateComplete - time: 11:09:57
Status: -100
** Activity (main) Pause, UserClosed = true **
** Service (servicemain) Destroy **
** Service (servicetxrx) Destroy **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Service (servicemain) Create **
** Service (servicemain) Start **
releasing KeepAlive
No wakelock.
turning screen on
using partialLock
** Service (servicetxrx) Create **
** Service (servicetxrx) Start **
---- AppUpdating.ReadCurVN
HANGS HERE....
Nevermind, I have to call the initialize every single time even outside of if Firsttime.
 

udg

Expert
Licensed User
Glad to hear you found the cause of the problem and could fix it.

udg
 

techknight

Well-Known Member
Licensed User
Hey, can this library be updated to use the OkHttp since regular HTTPUtils is not available in Android 6?

Edit: Nevermind, it already does.

I am using dropbox to host my APKs and TXT files. works like a charm.
 
Last edited:
  • Like
Reactions: udg

techknight

Well-Known Member
Licensed User
As time goes on, I am starting to notice a problem.

AppUpdating keeps creating/starting a service like 500 times on app launch. So much so that when I back out and close the app, it will relaunch.

B4X:
LogCat connected to: 30044ad22ed23200
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
** Activity (main) Create, isFirst = true **
Config Version: v210
Expected: v210
** Activity (main) Resume **
** Service (servicemain) Create **
** Service (servicemain) Start **
releasing KeepAlive
No wakelock.
turning screen on
using partialLock
** Service (servicetxrx) Create **
** Service (servicetxrx) Start **
---- AppUpdating.ReadCurVN
UpdateComplete - time: 11:15:00
---- AppUpdating.ReadWebVN
** Service (httputils2service) Create **
** Service (httputils2service) Start **
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL (****BLANKED OUT HERE****) was not found on this server.</p>
<hr>
<address>Apache/2.4.16 (Win32) OpenSSL/1.0.2d PHP/5.5.12 Server at BLANKED FOR PRIVACY Port 80</address>
</body></html>
---- AppUpdating.JobDone --
    Error: Not Found
UpdateComplete - time: 11:15:01
Status: -100
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
** Service (newinst2) Create **
---- AppUpdating.newinst2: service created
** Service (newinst2) Start **
---- AppUpdating.newinst2: service_started
This is a problem. I have no idea whats going on or how to fix it. It seems if the file isn't on the server (which is the case here) yet that its muuuch worse.
 

udg

Expert
Licensed User
Thanks for reporting. I'll have to check the code but looks you're right.
I suspect that when ReadWebVN gets back a 404 error it doesn't parse correctly the response.
No idea at the moment about the loop on create/start service newinst2. It should be called by OS when a package is replaced and start Main only if that package is the current one.

Edit:
I replicated the 404 error on my server and it seems to work as expected (while in log it shows the 404 page content, but code simply reports error:-100 as to indicate a generic Http problem). This is to say that it shouldn't be the reason for the crazy create/start newinst2 service loop.

Do you mind to experiment with my original Example code?
I'd like you to substitute my data with anything similar on your server. The idea is to see whether the create/start loop is started even with that simplified code, since it doesn't happen on my server.
In case you're willing to experiment, change the lines:
B4X:
'ALWAYS NEEDED - this is your app's package name (see "Project/Package name")
apkupdt.PackageName = "b4a.example.appupdate"
'ALWAYS NEEDED - this is the complete path to the text file holding the newer version number  
apkupdt.NewVerTxt = "http://www.dgconsulting.eu/free_apk/AppUpdateExample.inf"
'ALWAYS NEEDED - this is the complete path to your newer apk
apkupdt.NewVerApk = "http://www.dgconsulting.eu/free_apk/AppUpdateExample.apk"
'OPTIONAL - Set credentials to access a protected folder. Not needed for this example
apkupdt.setCredentials("test","test")
to their equivalents on you server. Something like
B4X:
apkupdt.PackageName = "b4a.example.appupdate"
apkupdt.NewVerTxt = "http://yourserver/YourTestFile.inf"
apkupdt.NewVerApk = "http://yourserver/YourTestFile.apk"
TIA
 
Last edited:
Status
Not open for further replies.
Top