Android Question ESP8266 - ESP32 OTA Update from B4A WebView [SOLVED]

max123

Well-Known Member
Licensed User
Longtime User
Hi all,

for my 3D Printing Host app I need to do ESP8266-ESP32 OTA updates directly inside the app instead of use external browser.

I never used WebView for my projects before now, so I have some problems to know how to do it.

With current code I wrote I'm able to see on the WebView the ESP OTA update page, but when I press the button to choose a binary file (.bin)
the WebView show a message that says there in no application to do it.

This is the code I wrote, next I will put my questions:
B4A Code:
WebView1.JavaScriptEnabled = True  ' Already enabled by default
'WebView1.ZoomEnabled = False
'WebView1.Zoom(True)
WebView1.Color = Colors.LightGray
WebView1.SendToBack
        
Dim wve As WebViewExtras
wve.addWebChromeClient(WebView1, "wve")
wve.addJavascriptInterface(WebView1, "b4a") ' Is this required ???

Dim WebViewSettings1 As WebViewSettings
Log("UserAgent before: " & WebViewSettings1.getUserAgentString(WebView1))

Dim UserAgent As String = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/20100101 Firefox/4.0"
WebViewSettings1.setUserAgentString (WebView1, UserAgent)
'WebViewSettings1.setDefaultZoom(WebView1, "FAR")
'WebViewSettings1.setUseWideViewPort(WebView1, True)
'WebViewSettings1.setLoadWithOverviewMode(WebView1, True)
    
Log("Save passwords: " & WebViewSettings1.getSavePassword(WebView1))
Log("UserAgent after: " & WebViewSettings1.getUserAgentString(WebView1))

..........
..........

Sub btnStart_On(Index As Int, Tag As String)
    btnStart.DisableNoMask
    Dim URL As String = txtHost.Text.Trim
    WebView1.LoadUrl(URL)
    Log("Loading URL: " &  WebView1.Url)
    ToastMessageShow("Loading URL: " & WebView1.Url, False)
    
    WriteSlotVal(79, URL)
End Sub

Sub btnStop_On(Index As Int, Tag As String)
    btnStart.Enabled = True
    WebView1.StopLoading
    Sleep(400)
    btnStart.Value = 0
    btnStop.Value = 0
End Sub

Sub WebView1_UserAndPasswordRequired (Host As String, Realm As String) As String()
    ToastMessageShow(Host & " require Username and Password to access: " & Realm, True)
    Log(Host & " require Username and Password to access: " & Realm)
    Return Array As String("admin", "password") ' OTA update page, we set on ESP to require a login
End Sub

Sub WebView1_OverrideUrl (Url As String) 'As Boolean
    ToastMessageShow("Override URL: " &  Url, False)
    Log("Override URL: " &  Url)
End Sub

Sub WebView1_PageFinished (Url As String)
    ToastMessageShow("PageFinished: " &  Url, False)
    Log("PageFinished: " & Url)
End Sub

My questions are:

1) I've used UserAndPasswordRequired sub to pass the username and password, after I added this It successfull login and I see the OTA update page, but want I want is to show the original login (as showed on browser) so the user insert username and password itself directly on the login view, is that possible?

2) When I load a page, pressing on button to choose a binary file, a message show that there are no applications to do it, I do not khow how I can handle it... Maybe need an Intent or I'm wrong ?

Attached some images of attemp on the app and the original login from Android FireFox browser.

Many thanks for any clarification.
 

Attachments

  • Page_loaded.jpg
    99.6 KB · Views: 343
  • No_app_found.jpg
    69.3 KB · Views: 337
  • Firefox_login.jpg
    97.4 KB · Views: 365

Ivica Golubovic

Active Member
Licensed User
I sugest you to try with B4AExample and library from below link:
Pay atention on "FileChooserInitialized" event
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Many thanks for your reply Ivica,

I do not tried yet your library, seem to be complex to me, but add a lots of funtionality to a default WebView, and this is the best anyone can found here I think.

Do you asked to Erel to implement it as default WebView in B4X enviroment (B4A, B4J, B4i) ?

Now I will read better your long library post, then download it and try the example. I've already found "FileChooserInitialized" event and still know how it works.

THAT I DO NOT LIKE is to add a lots of permisson on the manifest, I already have a long manifest because my app add some permissons and even USB host permissons for any USB-Serial chip to control any 3D printer and GRBL CNC machine.

At this point I've a question...
But I need to add all permissons to manifest to make your library work or I just can add only permissons I need ?

I do not need other funtionalities (for now) other than open the file chooser to select an ESP8266-ESP32 binary files and then press the upload button to start OTA update.

As you can see from my screnshots I use the same WebView to do OTA updates and to stream an IP camera (ESP32CAM or Raspberry Cam or any compatible IP camera that stream MJPEG format). It can open any URL the WebView can.
I had problems to resize the camera web server, so I searched (with WebViewExtras) to force use a Desktop user agent but not found the right I wanted, maybe I need need to edit the ESP32CAM CameraWebServer.ino html to resise it the right way if it recognize a mobile device.

THAT I LIKE is a way to use UltimateWebView on top of a default WebView
You can now import an existing WebView object into UltimateWebView, it is not necessary to add an UltimateWebView object through the Designer.

But I can even use it in the Designer, the current WebView is on the Designer.

To be clear, because my app is already very very complex (I working on it from 4 years), it can control most of 3D printers, CNC machines, Laser cutter and engraving machines, Foam cutter machines an in future Plasma machines, with just a smartphone or tablet or any Android device, over USB and over WiFi on local network and over internet, and even offline, just simulate it by draw, and while working draw the work on Canvas, even while work on the network... stream a reatime IP cam, receive timelapse images over network from second ESP32CAM or Raspberry etc... etc..., I can use your library ONLY if I can add just the needed functionalities in a fashion way without add a lots of functionalities not reqired that increase the final APK size and the app overhead.

If this is not possible, my question remains open, maybe just use an Intent or use some JavaObject solves the problem ?
I'm not expert on this, you are the expert here
 
Last edited:
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
After a lot of searchs on the forum..... Take a look on this page from Erel..... Maybe the solution ?
Upload files with WebView
 
Upvote 0

Ivica Golubovic

Active Member
Licensed User
Do you asked to Erel to implement it as default WebView in B4X enviroment (B4A, B4J, B4i) ?
I did not talk to Erel about the implementation of the library. I think it's too early for that, the library is still in development.

If you read the description more carefully, it says "add to the manifest for the full functionality of the library". So, if you don't need webrtc, then you don't need camera and microphone permissions, if you don't need geolocation, you don't need permissions for geolocation, etc. Leave only "SetApplicationAttribute (android: usesCleartextTraffic," true ")" and the part for FileProvider.

THAT I LIKE is a way to use UltimateWebView on top of a default WebView

But I can even use it in the Designer, the current WebView is on the Designer.
Yes, the object can be added via the designer, but since version 2.0 it is not possible to implement WebView in UltimateWebView (it has become a standalone view). I forgot to delete that in the description.

As for the damage in the size of the application, everyone has the opinion that each added library will be too much for the final sum of megabytes. That's wrong. This library does not require additional JAR files and uses the android.webkit set of classes that are already in the Android Web View system. It requires no more space than the WebViewExtra you have already implemented. If the problem is a hundred kilobytes, then that's another story.

After a lot of searchs on the forum..... Take a look on this page from Erel..... Maybe the solution ?
Upload files with WebView
Yes, you can use that solution as well. I suggested a much simpler solution because you said you had no experience using WebView. If you are not an "expert", you may encounter a lot of difficulties while adapting everything for your application and the way you need it. It's up to you.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Many Many Thankssss Ivica for your precious time and suggestions I will try both solutions, the Erel's example and your library in a separate project to know what is better for me (not expert on this) ....

For the apk file size yes, the problem is a hundred kilobytes, my app is complex as I explained but even if I used a lots of Internal libraries, External libraries and some libraries I've developed, the final apk file size still very small, around 5.9 MB. I still searched to optimize to reduce it or at least do not increase.

My library tab on this project show 21 libraries used and I use some (compiled) my libraries inline to adapt to the project. Total about 40.000 lines of code, a lots of global variables and controls, the Activity_Create still on line 780

I even program a lots Arduino, ESP8266, ESP32 in general, so I always search to optimize my code when possible, to be more elegant, smaller, readable (to me and others) and expecially to be more fast possible, for every command I repeat hundred times in a second, I always try 2 or more solutions with a loop that repeat it a milion of times and I measure accurately the time in milliseconds or microseconds before use finally on my applications.

With this in mind some time ago I developed an ESP8266-ESP32 library capaple to show on color oled video read from sdcard up 140 fps. When I started it using other libraries the max I archivied around 8-10 fps.

Another time Many Thanks, I will post here my results if I've success, so other user can avoid problems on this.
 
Last edited:
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Can I ask you some stupid questions that has nothing to do with this post ?

Don't laugh but I really don't know even though I've been using B4X for almost 10 years ....

In the File Tab I now have many files, mostly images, which are unused by the project but which I keep there in case I need them.
When I am sure that I no longer need files and delete them, will my apk file become smaller?
I assume 'yes' because those files are placed inside the apk file in the resources folder, right?
So when I'm sure I don't need them anymore can I use Tools / Remove Unused Files right?
Or maybe remove it manually one by one to remove only same.....
 
Upvote 0

Ivica Golubovic

Active Member
Licensed User
Yes, you can and the apk file size will be reduced. But be careful. If you use some of the files outside the code, or if they are manually called via a text editor or url (these files will also be deleted). E.g:

Dim FileName as String = EditText1.Text
File.ReadString (File.DirAssets, FileName)

In that case better solution is to remove files manualy.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I tried now the Erel's example, the webview says, max 100KB... This is a limitation, OTA bynary files can be larger files, I think max 3-4 MB, the actual used in my project is around 2 MB.

How I can remove this limitation ?
Your library has this limitation too ?
 

Attachments

  • 20220127_204211.jpg
    82.6 KB · Views: 182
Last edited:
Upvote 0

Ivica Golubovic

Active Member
Licensed User
Try via B4AExample. I uploaded smaller videos of about 100 to 500 megabytes in size for the test without any problems. I don't know what the problem is in Erel's example.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Hi Ivica,

I tried both solutions, Erel's example and your B4AExample...

With Erel's example I cannot open the page because I've to manage the login, tried with JavaObject and inline Java but without success with my small experience on this.

With your library I can open the page, I had to pass back UserName and Password or the login has no success ...

B4X:
Private Sub UltimateWebView1_ReceivedHttpAuthRequest (HttpAuthHandler1 As HttpAuthHandler, HttpAuthRequestProperties1 As HttpAuthRequestProperties) 'Works from API level 1 and above. WebViewClient required.
    Log("ReceivedHttpAuthRequest")
    Log(HttpAuthRequestProperties1.Host)
    Log(HttpAuthRequestProperties1.Realm)
  
    HttpAuthHandler1.Proceed("admin", "password")
End Sub

After this the login was successfull, but no way to show original login screen so the user can login with it ?

After this if I press on the button to choose an OTA binary file B4A always return:
onActivityResult: wi is null

So the FileChooser never appear, note that first time it required me the permisson that I've accepted.

I've attached my changed B4AExample zip file and some screenshots.
Please can you see because it won't work ?

I never changed nothing in particular in original example, just changed the Host and uncommented some logs.

Uncommented almost all logs in the code but not known what happen here. ?
Note that because I use a pretty old system (32bit) and cannot update B4A to latest (my version is 7.80) I had to change the:
CreateResourceFromFile(Macro, Themes.DarkTheme) ' Require B4A 8.0
... in the manifest to a traditional way.... just commented this line and add others, if this a problem for you just comment new lines and leave just the original one line.

Many Thanks
 

Attachments

  • ESP_OTA_Update.zip
    13.3 KB · Views: 214
  • 20220128_154832.jpg
    62.2 KB · Views: 236
  • Screen Shot 01-28-22 at 03.45 PM.PNG
    27.3 KB · Views: 200
Last edited:
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
If you can see it, inform me here, If you want to try, I can send you my current public IP address,
just replace it on library example project and you are able to reprogram my ESP32 (in Italy) over internet.
After OTA update ESP32 auto reboots itself and start executing the new code.
If you want to try I can provide one or more simple .bin files just to test, eg. to blink a led every second ...
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I try it now....
Many Tks
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I had no
Service.StopAutomaticForeground 'Starter service can start in the foreground state in some edge cases.
in B4A 7.80, just it support
Service.StopForeground
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
In your example project I replaced:
Service.StopAutomaticForeground
with:
Service.StopForeground(0)

The page appear, I press the button to select a file, the FileChooser works, as Erel's example I can select a file, but when I press the Upload button the webview says, no page found net:ERR_NAME_NOT_RESOLVED.

Ive tried to open the page with desktop browser, I can select a file, when I press upload button I have the same error....

Is this link working?
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Sorry, but not so simple, you have to inform me when you can do it... I need to power on my ESP32, so it load and start OTA update service, after this (and only after this) it exposes a webserver page to access to it from local or public network.
I even need to add an exception in my router and open the exact port (that I set as 3232 for ESP32 or 8266 for ESP8266) but this is not a problem.

Please inform me when you have some time to test it, so just ten minutes we are able to do it.

I do not know because it do not accept your link if it is a working link, now I will try directly with my OTA link.
But it is supposed to work with Desktop browser too? I used Firefox on Windows and it show a file manager, then I can select a file, but after this it cannot upload.

Many thanks for your great support and precious time Ivica.
 
Last edited:
Upvote 0

Ivica Golubovic

Active Member
Licensed User
I see in your example that you put Header for desktop when you trying to load URL. I think that may be the reason because you get error code. Try to remove headers and open page with default User Agent and send me feedback.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
This is the code, I've removed UserAgent, but nothing change:
B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

#BridgeLogger: True

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    Private UltimateWebView1 As UltimateWebView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
  
    UltimateWebView1.SetWebChromeClient
    UltimateWebView1.SetWebViewClient
  
    UltimateWebView1.Settings.JavaScriptEnabled=True
    UltimateWebView1.Settings.JavaScriptCanOpenWindowsAutomatically=True
  
    'Optional
    UltimateWebView1.Settings.AllowFileAccess=True
    UltimateWebView1.Settings.AllowContentAccess=True
    UltimateWebView1.Settings.AllowFileAccessFromFileURLs=True
    UltimateWebView1.Settings.AllowUniversalAccessFromFileURLs=True
    UltimateWebView1.Settings.AppCacheEnabled=True
    UltimateWebView1.Settings.DatabaseEnabled=True
    UltimateWebView1.Settings.DisplayZoomControls=False
    UltimateWebView1.Settings.DomStorageEnabled=True
    '----------------------------
  
    ' My addons
'    UltimateWebView1.Settings.AllowFileAccessFromFileURLs = True
'    UltimateWebView1.Settings.AllowUniversalAccessFromFileURLs = True
'    UltimateWebView1.Settings.ForceDark = 2
'    UltimateWebView1.Settings.UseWideViewPort = True
'    UltimateWebView1.Settings.UserAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36" 
    '-------------
  
    Dim link As String = "http://ps.uci.edu/~franklin/doc/file_upload.html" ' Original
'    Dim link As String = "http://192.168.178.52/Update"
    UltimateWebView1.LoadUrl(link)
  
'    ' My addons
'    Dim Headers As Map
'    Headers.Initialize
'    Headers.Put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36")
'    UltimateWebView1.LoadUrl2(link, Headers)
'    '--------------
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If UserClosed Then ExitApplication
End Sub

'Most important event for UltimateWebView permissions request (Camera, Geolocation, Microphone, Write Storage itd.)!!!
Private Sub UltimateWebView1_PermissionRequest (RequestedPermission As String) 'Works from API level 21 and above. WebChromeClient required.
    Dim rp As RuntimePermissions
    rp.CheckAndRequest(RequestedPermission)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    UltimateWebView1.GrantPermission(Result)
End Sub

Private Sub UltimateWebView1_FileChooserInitialized (FilePathCallback As Object, FileChooserParams1 As FileChooserParams) 'Works from API level 21 and above. WebChromeClient required.
    Log("Chooser Initialized")
    UltimateWebView1.FileChooserStart(FilePathCallback, FileChooserParams1, False)
End Sub

Private Sub UltimateWebView1_ReceivedHttpAuthRequest (HttpAuthHandler1 As HttpAuthHandler, HttpAuthRequest1 As HttpAuthRequestProperties) 'Works from API level 1 and above. WebViewClient required.
    Log("ReceivedHttpAuthRequest from " & HttpAuthRequest1.Host & ": " & HttpAuthRequest1.Realm)
    Log(HttpAuthRequest1.Host)

    HttpAuthHandler1.Proceed("admin", "password")
End Sub

Private Sub UltimateWebView1_ReceivedLoginRequest (LoginRequest1 As LoginRequestProperties) 'Works from API level 12 and above. WebViewClient required.
    Log("ReceivedLoginRequest: " & LoginRequest1.Realm & "   Account: " & LoginRequest1.Account & "   Args: " & LoginRequest1.Args)
End Sub

''''''''''''''''''

Private Sub UltimateWebView1_PageStarted (Url As String, FavIcon As Bitmap) 'Works from API level 1 and above. WebViewClient required.
    Log("PageStarted: " & Url)
    'If FavIcon<> Null Then
    'do stuff...
    'End If
End Sub

Private Sub UltimateWebView1_PageFinished (Url As String) 'Works from API level 1 and above. WebViewClient required.
    Log("PageFinished: " & Url)
End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub UltimateWebView1_FileDownloadInitialized (DownloadProperties1 As DownloadProperties) 'Works from API level 1 and above. DownloadListener required.
    Log("Download INITIALIZED:")
  
    Log(DownloadProperties1.url)
    Log(DownloadProperties1.userAgent)
    Log(DownloadProperties1.contentDisposition)
    Log(DownloadProperties1.mimeType)
    Log(DownloadProperties1.contentLength)
    Log(DownloadProperties1.cookies)
    Log(DownloadProperties1.fileName)
    Log(DownloadProperties1.FileExtension)
    Log(DownloadProperties1.DownloadID)
  
    UltimateWebView1.StartFileDownload(DownloadProperties1,"TEST",True,True)
End Sub

Private Sub UltimateWebView1_FileDownloadStarted (DownloadProperties1 As DownloadProperties) 'Works from API level 9 and above. DownloadListener required.
    Log("Download STARTED:")
  
    Log(DownloadProperties1.url)
    Log(DownloadProperties1.userAgent)
    Log(DownloadProperties1.contentDisposition)
    Log(DownloadProperties1.mimeType)
    Log(DownloadProperties1.contentLength)
    Log(DownloadProperties1.cookies)
    Log(DownloadProperties1.fileName)
    Log(DownloadProperties1.FileExtension)
    Log(DownloadProperties1.DownloadID)
End Sub

Private Sub UltimateWebView1_FileDownloadCompleted (Success As Boolean, DownloadProperties1 As DownloadProperties) 'Works from API level 9 and above. DownloadListener required.
    Log("Download COMPLETED; Success:" & Success)
  
    Log(DownloadProperties1.url)
    Log(DownloadProperties1.userAgent)
    Log(DownloadProperties1.contentDisposition)
    Log(DownloadProperties1.mimeType)
    Log(DownloadProperties1.contentLength)
    Log(DownloadProperties1.cookies)
    Log(DownloadProperties1.fileName)
    Log(DownloadProperties1.FileExtension)
    Log(DownloadProperties1.DownloadID)
End Sub

Private Sub UltimateWebView1_ReceivedIcon (Icon As Bitmap) 'Works from API level 1 and above. WebChromeClient required.
    Log("ReceivedIcon: Size: " & Icon.Width & "x" & Icon.Height)
    'If Icon <> Null Then
        'do stuff...
    'End If
End Sub


Private Sub UltimateWebView1_OverrideUrl (Url As String) As Boolean 'Works from API level 1 to API level 23. WebViewClient required.
    Log("OverrideUrl: " & Url)
    Return False
End Sub

Private Sub UltimateWebView1_OverrideUrl2 (WebResourceRequest1 As WebResourceRequest) As Boolean 'Works from API level 24 and above. WebViewClient required.
    Log("OverrideUrl2: " & WebResourceRequest1.GetUrl)
    Return False
End Sub

'--------------- ERRORS ---------------

Private Sub UltimateWebView1_ReceivedError (ErrorCode As Int, Description As String, FailingUrl As String) 'Works from API level 1 to API level 23. WebViewClient required.
    Log("ERROR: (" & ErrorCode & ")    Description: " & Description & "    URL: " & FailingUrl)
End Sub

Private Sub UltimateWebView1_ReceivedError2 (WebResourceRequest1 As WebResourceRequest, WebResourceError1 As WebResourceError) 'Works from API level 23 and above. WebViewClient required.
    Log("ERROR2: (" & WebResourceError1.ErrorCode & ")    Description: " & WebResourceError1.Description & "    URL: " & WebResourceRequest1.GetUrl)
End Sub

Private Sub UltimateWebView1_ReceivedHttpError (WebResponseRequest1 As WebResourceRequest, WebResourceResponse1 As WebResourceResponse) 'Works from API level 23 and above. WebViewClient required.
    Log("HTTP ERROR: (" & WebResourceResponse1.StatusCode & ")    Encoding: " & WebResourceResponse1.Encoding & "    URL: " & WebResponseRequest1.GetUrl)
End Sub

I have different results if I use your or mine URL:
- with your I can load a page, pressing the button I can see the FileChooser, then press the upload button I've error (POSTED THE FULL LOG)
- with mine (after login) I can see the page, when press the button to open files, return an error onActivityRequest as explained in latest post

The strange is that I always (with your or with mine URLs) see strange errors on the log, see below.


I do not know because using your URL PageStarted is called 2 times, so even the favicon request, but the PageFinished is only one.
 
Last edited:
Upvote 1
Cookies are required to use this site. You must accept them to continue using the site. Learn more…