Hi all.
I'm new to Basic4Android and am writing my first application - a store finder - and this is my first (rather long) post on the forum .
I have three activities in my application:
The first activity gets the user's location using GPS and queries a database for nearest stores to the user location.
The activity parses the XML response and stores it as a process global variable.
The second activity creates a list view of these stores and a click on a list view item saves that store data as a process global and opens the third activity.
The third activity contains a WebView that loads a local HTML file with a query string generated from the location of the selected store - it gets the values from the second activitys process global.
The HTML file creates a Google Map displaying directions from the user location to the selected store.
All works perfectly so far.
Now when the third activity is paused - the device orientation changes - and is then resumed, the map displays exactly as it's displayed when initially viewed.
That is, if the user changes the map center, zoom level or map type and then changes their device orientation then when the third activity is resumed the map doesn't retain the view set by the user.
I can add event listeners to my web page and store (as javascript variables) the map center, zoom level and map type whenever any of these values change.
But how can i get these javascript values from my web page back to the third activitys Resume method, where i can add them to the query string and the map can restore the state of the map before the activity was paused?
My only solution so far is:
Whenever the user changes the map center, zoom level or map type to set the javascript location.href property to a new URL with the current map center, zoom level and/or map type in the new URL query string.
For example:
Then in my application listen for the WebView OverrideUrl event.
If this is the first time that the WebView URL has changed then do not consume the event otherwise consume the event - parsing out new map center, zoom level and/or map type values to the third activity process global:
Activity #3 code:
This solution so far doesn't work .
All the logic seems to be fine BUT OverrideUrl event does not fire when the map javascript sets the location.href property.
Instead the page reloads - losing the original directions and other map state.
PageFinished event fires when the page is first loaded and then each time the map javascript changes the location.href property BUT OverrideUrl event nevers fires if the page is reloaded by setting the location.href property within the page javascript.
The IDE reports the 'debug1' messages but no 'debug2' messages.
Now every Google Map has a link bottom corner - i gave it a click and 'debug2' message appeared in the IDE and OverrideUrl event has been called!
So i have two questions:
1) Should the OverrideUrl event be expected to fire when javascript (within a page being displayed in a WebView) changes the DOM location.href property?
2) Can anyone suggest any other methods that i can use to get values from my web page javascript into an activity where they can be saved as process globals?
Thanks a lot.
Martin.
I'm new to Basic4Android and am writing my first application - a store finder - and this is my first (rather long) post on the forum .
I have three activities in my application:
The first activity gets the user's location using GPS and queries a database for nearest stores to the user location.
The activity parses the XML response and stores it as a process global variable.
The second activity creates a list view of these stores and a click on a list view item saves that store data as a process global and opens the third activity.
The third activity contains a WebView that loads a local HTML file with a query string generated from the location of the selected store - it gets the values from the second activitys process global.
The HTML file creates a Google Map displaying directions from the user location to the selected store.
All works perfectly so far.
Now when the third activity is paused - the device orientation changes - and is then resumed, the map displays exactly as it's displayed when initially viewed.
That is, if the user changes the map center, zoom level or map type and then changes their device orientation then when the third activity is resumed the map doesn't retain the view set by the user.
I can add event listeners to my web page and store (as javascript variables) the map center, zoom level and map type whenever any of these values change.
But how can i get these javascript values from my web page back to the third activitys Resume method, where i can add them to the query string and the map can restore the state of the map before the activity was paused?
My only solution so far is:
Whenever the user changes the map center, zoom level or map type to set the javascript location.href property to a new URL with the current map center, zoom level and/or map type in the new URL query string.
For example:
B4X:
google.maps.event.addListener(map, 'center_changed', function(){
location.href='file:///android_asset/store_detail.htm?newcenter='+map.getCenter().toUrlValue();
});
Then in my application listen for the WebView OverrideUrl event.
If this is the first time that the WebView URL has changed then do not consume the event otherwise consume the event - parsing out new map center, zoom level and/or map type values to the third activity process global:
Activity #3 code:
B4X:
'Activity module
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Type State (Lat As Float, Lng As Float, Zoom As Int, MapType As String)
Dim mapState As State
End Sub
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Dim handleUrls As Boolean
Dim storeDetailWebView As WebView
End Sub
Sub Activity_Create(FirstTime As Boolean)
If FirstTime=True Then
ProgressDialogShow("Creating map view")
mapState.Lat=0
mapState.Lng=0
mapState.Zoom=0
mapState.MapType="ROADMAP"
handleUrls=False
End If
End Sub
Sub Activity_Resume
Activity.LoadLayout("lytStoreDetail")
storeDetailWebView.Width=100%x
storeDetailWebView.Height=100%y
Dim mapUrl As StringBuilder
mapUrl.Initialize
mapUrl.Append("file:///android_asset/store_detail.htm?saddr=")
mapUrl.Append(Main.userLocation.Latitude).Append(",").Append(Main.userLocation.Longitude)
mapUrl.Append("&daddr=").Append(actStoreList.selectedStore.Lat).Append(",").Append(actStoreList.selectedStore.Lng)
storeDetailWebView.LoadUrl(mapUrl.ToString)
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub storeDetailWebView_PageFinished (url As String)
Log("debug1: "&url)
' consume the OverrideUrl event now that the initial page view URL has loaded
handleUrls=True
ProgressDialogHide
End Sub
Sub storeDetailWebView_OverrideUrl (url As String) As Boolean
Log("debug2: "&url)
If handleUrls Then
' parse map state from url and save to a process global
End If
Return handleUrls
End Sub
This solution so far doesn't work .
All the logic seems to be fine BUT OverrideUrl event does not fire when the map javascript sets the location.href property.
Instead the page reloads - losing the original directions and other map state.
PageFinished event fires when the page is first loaded and then each time the map javascript changes the location.href property BUT OverrideUrl event nevers fires if the page is reloaded by setting the location.href property within the page javascript.
The IDE reports the 'debug1' messages but no 'debug2' messages.
Now every Google Map has a link bottom corner - i gave it a click and 'debug2' message appeared in the IDE and OverrideUrl event has been called!
So i have two questions:
1) Should the OverrideUrl event be expected to fire when javascript (within a page being displayed in a WebView) changes the DOM location.href property?
2) Can anyone suggest any other methods that i can use to get values from my web page javascript into an activity where they can be saved as process globals?
Thanks a lot.
Martin.