B4A Library GoogleMapsExtras

GoogleMapsExtras is an ongoing project to implement more of the Google Maps Android v2 classes in Basic4Android.

Currently the library allows you to create these objects:

Tutorials for each object will be uploaded to the Google Maps Android v2 tutorial thread.

Martin.
 

Attachments

  • GoogleMapsExtras_v1_71.zip
    59.6 KB · Views: 2,693
  • MapsForgeTileProvider_v1.01.zip
    173.1 KB · Views: 2,567
  • GoogleMapsExtras_v2_0_library_files.zip
    82.5 KB · Views: 2,991
Last edited:

Massimiliano

Member
Licensed User
Longtime User
it's what I expected "with the removed line GoogleMapsExtras1.SetLocationSource(GoogleMap1, CustomLocationSource1)"... object should be initialized :)

I the meantime, Klaus, I'm asking myself, how can I trigger the "Activate" inside the "MapFragment1_Ready" without push my location button over the map
 

Massimiliano

Member
Licensed User
Longtime User
Martin, after testing the new library v2.0, I can confirm that it's working as desired. So if you want, you can move the library to the first post.
Thank you so much.
 

warwound

Expert
Licensed User
Longtime User
GoogleMapsExtras updated to version 2.0

This update adds support for the LocationSource.

If you use the GoogleMaps MyLocation feature then you are using the GoogleMaps' default (built in) LocationSource.
The only control you have over the default LocationSource is the permission you have added to your manifest - you can use ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permissions.
You cannot adjust other default LocationSource parameters such as update interval and accuracy.

This library update contains 2 new objects:

  • CustomLocationSource
    Events:
    • Activate (OnLocationChangedListener1 As OnLocationChangedListener)
    • Deactivate
    Methods:
    • Initialize (EventName As String)
      Initialize the CustomLocationSource.
      Raises the events:

      Activate(OnLocationChangedListener1 As OnLocationChangedListener)
      The CustomLocationSource has been activated.
      OnLocationChangedListener1's OnLocationChanged(Location1 As Location) method should be called each time a new Location is available.

      Deactivate
      The CustomLocationSource has been deactivated.
      No further calls to OnLocationChangedListener1's OnLocationChanged(Location1 As Location) method should be made.
    • IsInitialized As Boolean

  • OnLocationChangedListener
    Methods:
    • IsInitialized As Boolean
    • OnLocationChanged (Location1 As Location)
      Passes a Location to the CustomLocationSource.
      The Location must be initialized and not null.

GoogleMapsExtras also has a new method:

SetLocationSource (GoogleMap1 As GoogleMap, LocationSource1 As LocationSource)
Replaces the default location source of the MyLocation layer.
Pass Null to restore the default location source.


This allows you to:

  • Create a CustomLocationSource.
  • Set your CustomLocationSource as the GoogleMap's LocationSource.
  • Listen for location updates in your b4a code using whatever library you wish.
  • Pass your location updates to the GoogleMap.

The GoogleMap's MyLocation feature will function as normal but use the location updates that your CustomLocationProvider provides instead of the location updates provided by the default (built in) LocationSource.

You now have full control over the MyLocation feature.
You could use low accuracy, low battery usage to provide infrequent updates.
You could use maximum accuracy with constant updates to provide the fastest and most accurate location updates - at the expense of increased battery usage.


There is a skeletal code example in Post #249.
And a full example that uses FusedLocationProvider in Post #261.

Version 2.0 of GoogleMapsExtras is attached to the first post in this thread.
 

Massimiliano

Member
Licensed User
Longtime User
I've noticed a strange thing. After following my FusedLocationProvider position a minute (about) the map doesn't shows fine anymore (look at the screenshot).
If I drag a little bit over the map it shows fine. After a while same problem
Any hint?
I don't know it's something regarding Extras or the basic Googlemap library or something else
For sure it's not the network (i'm over LTE, phone signal is strong and GPS connected)

I'm using PhoneWakeState to set the phone always active during mapping

Massimiliano
 

Attachments

  • Screenshot_2015-05-26-16-04-12.png
    Screenshot_2015-05-26-16-04-12.png
    235.6 KB · Views: 217
Last edited:

warwound

Expert
Licensed User
Longtime User
@Massimiliano

From the screenshot it looks as though the map is failing to download the tile data required for the new map center as the map center changes.
Does PhoneWakeState keep the device's networking active or has the networking gone to sleep?
You say as soon as you drag the map the problems fixes itself - that sounds like the network is asleep and then wakes up as soon as you touch the map.
 

Massimiliano

Member
Licensed User
Longtime User
@Massimiliano

From the screenshot it looks as though the map is failing to download the tile data required for the new map center as the map center changes.
Does PhoneWakeState keep the device's networking active or has the networking gone to sleep?
You say as soon as you drag the map the problems fixes itself - that sounds like the network is asleep and then wakes up as soon as you touch the map.

Probably this is the trick. Martin.
Today I tried Invalidate and then DoEvents, but the problem still exists
I'll look on how to keep networking always active

Many thanks
 

Massimiliano

Member
Licensed User
Longtime User
@Massimiliano

From the screenshot it looks as though the map is failing to download the tile data required for the new map center as the map center changes.
Does PhoneWakeState keep the device's networking active or has the networking gone to sleep?
You say as soon as you drag the map the problems fixes itself - that sounds like the network is asleep and then wakes up as soon as you touch the map.

Martin, was not networking gone to sleep, since this morning I tried mapping with your OSM library v3 (my app support both modes Google and OSM) and all it's working fine (to be sure I deleted the tiles cache folder before starting). So I think there is somewhere a problem with gmap tiles.....
 

warwound

Expert
Licensed User
Longtime User
Does the GoogleMap also fail if you revert to the default MyLocation LocationSource?
That is - if you temporarily disable your CustomLocationSource does the problem persist?
 

Massimiliano

Member
Licensed User
Longtime User
Does the GoogleMap also fail if you revert to the default MyLocation LocationSource?
That is - if you temporarily disable your CustomLocationSource does the problem persist?

I've made a little app without FusedLocation and with the default MyLocation LocationSource and seems to be working fine.
Now I go to prepare another little app with FusedLocation. Probably when I'm inside the car fusedlocation raises too much events ?
I'll try to do my best. I'll post soon the results (2 very small apk and the code inside so you can check it)
 

Massimiliano

Member
Licensed User
Longtime User
Hello Martin,
in the meantime I've 2 minimal codes, ready to test tomorrow

With fusedlocationprovider:
B4X:
Sub Process_Globals
End Sub

Sub Globals
    Dim FIRST_ANIMATE As Boolean

    Dim FLP As FusedLocationProvider
    Dim OLCL As OnLocationChangedListener
    Dim CLS As CustomLocationSource
    Dim GMap As GoogleMap
    Dim GMapEx As GoogleMapsExtras
    Dim MFragment As MapFragment
    Dim MPanel As Panel
    Dim PWS As PhoneWakeState
End Sub

Sub Activity_Create(FirstTime As Boolean)
    FIRST_ANIMATE = True

    MPanel.Initialize("")
    Activity.AddView(MPanel, 0, 0, 100%x, 100%y)
    If MFragment.IsGooglePlayServicesAvailable = False Then
        ToastMessageShow("Google Play services not available.", True)
    Else
        MFragment.Initialize("MFragment", MPanel)
    End If
End Sub

Sub Activity_Resume
    If Not(FLP.IsInitialized) Then
        FLP.Initialize("FLP")
    End If

    If Not(FLP.IsConnected) Then
        FLP.Connect
    End If

    PWS.KeepAlive(True)
    PWS.PartialLock
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If FLP.IsConnected Or FLP.IsConnecting Then
        FLP.Disconnect
    End If

    PWS.ReleaseKeepAlive
    PWS.ReleasePartialLock
End Sub

Sub MFragment_Ready
    GMap = MFragment.GetMap
    If GMap.IsInitialized Then
        GMap.GetUiSettings.CompassEnabled = True
        GMap.GetUiSettings.MyLocationButtonEnabled = True
        GMap.GetUiSettings.ZoomControlsEnabled = True
  
        GMapEx.SetBuildingsEnabled(GMap, True)
        GMapEx.SetIndoorEnabled(GMap, True)
        GMapEx.SetTrafficEnabled(GMap, True)

        CLS.Initialize("CLS")
        GMapEx.SetLocationSource(GMap, CLS)
        GMap.MyLocationEnabled = True
    Else
        ToastMessageShow("Error initializing GoogleMap", False)
    End If
End Sub

Sub CLS_Activate(OnLocChangedListener As OnLocationChangedListener)
    OLCL = OnLocChangedListener
    FLP.Connect
End Sub

Sub CLS_Deactivate
    FLP.Disconnect
End Sub

Sub FLP_ConnectionFailed(ConResult As Int)
    Select ConResult
        Case FLP.ConnectionResult.NETWORK_ERROR
            ToastMessageShow("NETWORK ERROR" & CRLF & "RETRYING ...", False)
            FLP.Connect
        Case Else
            ToastMessageShow("CONNECTION FAILED", False)
    End Select
End Sub

Sub FLP_ConnectionSuccess
    Dim LR As LocationRequest
    LR.Initialize
    LR.SetInterval(1000) 'Milliseconds
    LR.SetPriority(LR.Priority.PRIORITY_HIGH_ACCURACY)
    LR.SetSmallestDisplacement(1) 'Meters
    FLP.RequestLocationUpdates(LR)
End Sub

Sub FLP_ConnectionSuspended(SuspCause As Int)
    Select SuspCause
        Case FLP.SuspendedCause.CAUSE_NETWORK_LOST
            ToastMessageShow("NETWORK LOST", False)
        Case FLP.SuspendedCause.CAUSE_SERVICE_DISCONNECTED
            ToastMessageShow("SERVICE DISCONNECTED", False)
    End Select
End Sub

Sub FLP_LocationChanged(NewLocation As Location)
    OLCL.OnLocationChanged(NewLocation)

    Dim ZOOM As Int
    If FIRST_ANIMATE Then
        FIRST_ANIMATE = False
        ZOOM = 15
    Else
        ZOOM = GMap.CameraPosition.Zoom
    End If

    Dim CP As CameraPosition
    CP.Initialize2(NewLocation.Latitude, NewLocation.Longitude, ZOOM, NewLocation.Bearing, 0)
    GMap.AnimateCamera(CP)
End Sub

Without fusedlocationprovider (a little bit tested, but seems to work fine)
B4X:
Sub Process_Globals
End Sub

Sub Globals
   Dim FIRST_ANIMATE As Boolean

   Dim GMap As GoogleMap
   Dim GMapEx As GoogleMapsExtras
   Dim LocationChange As OnMyLocationChangeListener
   Dim MFragment As MapFragment
   Dim MapPanel As Panel
   Dim PWS As PhoneWakeState
End Sub

Sub Activity_Create(FirstTime As Boolean)
   FIRST_ANIMATE = True

   MapPanel.Initialize("")
   Activity.AddView(MapPanel, 0, 0, 100%x, 100%y)
   If MFragment.IsGooglePlayServicesAvailable = False Then
     ToastMessageShow("Google Play services not available.", True)
   Else
     MFragment.Initialize("Map", MapPanel)
   End If
End Sub

Sub Activity_Resume
   PWS.KeepAlive(True)
   PWS.PartialLock
End Sub

Sub Activity_Pause (UserClosed As Boolean)
   PWS.ReleaseKeepAlive
   PWS.ReleasePartialLock
End Sub

Sub Map_Ready
   GMap = MFragment.GetMap
   If GMap.IsInitialized Then
     GMap.TrafficEnabled=True
     GMap.GetUiSettings.CompassEnabled = True
     GMap.GetUiSettings.MyLocationButtonEnabled = True
     GMap.GetUiSettings.ZoomControlsEnabled = True
     LocationChange.Initialize("LocationChange")
     GMapEx.SetOnMyLocationChangeListener(GMap, LocationChange)
     GMap.MyLocationEnabled=True
   Else
     ToastMessageShow("Error initializing map.", True)
   End If
End Sub

Sub LocationChange_MyLocationChange(NewLocation As Location)
   Dim ZOOM As Int

   If FIRST_ANIMATE Then
     FIRST_ANIMATE = False
     ZOOM = 15
   Else
     ZOOM = GMap.CameraPosition.Zoom
   End If

   Dim CP As CameraPosition
   CP.Initialize2(NewLocation.Latitude, NewLocation.Longitude, ZOOM, NewLocation.Bearing, 0)
   GMap.AnimateCamera(CP)
End Sub

Let me know if you find something strange, thank you
 
Last edited:

Massimiliano

Member
Licensed User
Longtime User
Martin,
I tried this morning the code #1 fusedlocation and I can confirm that the map doen't refresh correctly.
Could you give it a try? If you prefer I could upload the small apk, but it's 2Mb in size

Massimiliano
 

synapse

Member
Licensed User
Longtime User
I wondered if MapsForgeTileProvider has a problem with the most recent versions of Play Services, please? Despite having made the changes, specified elsewhere, that work with googlemaps I continue to get in the unfiltered log:

Authorization failure. Please see https://developers.google.com/maps/documentation/android/start for how to correctly set up the map.
In the Google Developer Console (https://console.developers.google.com)
Ensure that the "Google Maps Android API v2" is enabled.
Ensure that the following Android Key exists:
API Key:

Any advice would be greatly appreciated!
 
Last edited:

mkvidyashankar

Active Member
Licensed User
Longtime User
How to parse the markers created on the map. I want to parse the lat lon of all the markers and save it into a database. I did not find any methods. Please help.
 

warwound

Expert
Licensed User
Longtime User
I wondered if MapsForgeTileProvider has a problem with the most recent versions of Play Services, please? Despite having made the changes, specified elsewhere, that work with googlemaps I continue to get in the unfiltered log:

Authorization failure. Please see https://developers.google.com/maps/documentation/android/start for how to correctly set up the map.
In the Google Developer Console (https://console.developers.google.com)
Ensure that the "Google Maps Android API v2" is enabled.
Ensure that the following Android Key exists:
API Key:

Any advice would be greatly appreciated!

The mapsforge library just extends a GoogleMap class to provide tiles.
It won't have any effect on your api key not working - the problem must be elsewhere.
 

warwound

Expert
Licensed User
Longtime User
How to parse the markers created on the map. I want to parse the lat lon of all the markers and save it into a database. I did not find any methods. Please help.

There's no way to get markers from the map.
You add markers to the map so you have to keep references to your added markers so you can get their coordinates when required.
 

iCAB

Well-Known Member
Licensed User
Longtime User
Can anyone tell me why this code crashes
B4X:
Sub Activity_Create(FirstTime As Boolean)
   MapPanel.Initialize("")
   Activity.AddView(MapPanel, 0, 0, 100%x, 100%y)
   If mFragment.IsGooglePlayServicesAvailable = False Then
      ToastMessageShow("Google Play services not available.", True)
   Else
      mFragment.Initialize("Map", MapPanel)
   End If
  
    Timer1.Initialize("Timer1", 250)
  
End Sub


Sub Map_Ready
   Log("map ready")
   gmap = mFragment.GetMap
   If gmap.IsInitialized = False Then
      ToastMessageShow("Error initializing map.", True)
   Else
'      MyMarker = gmap.AddMarker(43.6953, -79.6152, "Hello!!!")
'      Dim cp As CameraPosition
'      cp.Initialize(36, 15, gmap.CameraPosition.Zoom)
'      gmap.AnimateCamera(cp)
'     
'    Timer1.Enabled = True
'     
        Dim MarkerOptions1 As MarkerOptions
        MarkerOptions1.Initialize
       
       
       
        'MarkerOptions1.Position2(52.75619, 0.3980).Snippet("Home is where the heart is").Title("Home Sweet Home").Visible(True)
        MarkerOptions1.Position2(36, 15).Snippet("Home is where the heart is").Title("Home Sweet Home").Visible(True)
       
        Dim BitmapDescriptor1 As BitmapDescriptor
        Dim BitmapDescriptorFactory1 As BitmapDescriptorFactory
       
        '    both of these lines load the person.png image as a custom icon
        BitmapDescriptor1=BitmapDescriptorFactory1.FromAsset("person.png")
        '    this method could be used to load a Bitmap that is located somewhere other than the assets folder
        '    BitmapDescriptor1=BitmapDescriptorFactory1.FromBitmap(LoadBitmap(File.DirAssets, "person.png"))
       
        MarkerOptions1.Icon(BitmapDescriptor1)
       
        Dim Marker1 As Marker=GoogleMapsExtras1.AddMarker(gmap, MarkerOptions1)
       
        Dim CameraPosition1 As CameraPosition
        CameraPosition1.Initialize(43.6953, -79.6152, 20)
        gmap.AnimateCamera(CameraPosition1)

     
   End If
End Sub

in particular at this line:
B4X:
Dim Marker1 As Marker=GoogleMapsExtras1.AddMarker(gmap, MarkerOptions1)

I am getting a java.lang.nullPointerException
 

Nostrildumbass

Member
Licensed User
Longtime User
Can anyone tell me why this code crashes

in particular at this line:
B4X:
Dim Marker1 As Marker=GoogleMapsExtras1.AddMarker(gmap, MarkerOptions1)

I am getting a java.lang.nullPointerException

It doesn't look like you ever declared/initialized GoogleMapsExtras1, so you're trying to declare Marker1 as a new marker with an object named GoogleMapsExtras1 (which doesn't exist).

I think you just need this, and I think it should work if you place it right before the line that it is crashing on.
B4X:
Dim GoogleMapsExtras1 As GoogleMapsExtras
 
Top