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,703
  • MapsForgeTileProvider_v1.01.zip
    173.1 KB · Views: 2,580
  • GoogleMapsExtras_v2_0_library_files.zip
    82.5 KB · Views: 3,002
Last edited:

msawada

Member
Licensed User
Longtime User
Hello Martin:
Regarding post #174, I have tried every way to get the groundoverlay to not crop the newark_nj_1922.jpg. I am wondering if there is a solution to get the ground overlay working correctly? Have you tried it and does it work? I've tried different sized images, loading bitmap from bitmapfactory and descriptor, different anchor points and height and widths etc... Always the images are cropped to 1/4 of the image. I've tried on Nexus 10 and nexus 4, in all debug and release compilations.

Any suggestions would be great or if anyone else has groundoverlay working help would be useful.

Thanks.
 

eurojam

Well-Known Member
Licensed User
Longtime User
Dear Martin,
I have a problem with the groundoverlay. Already the provided example did not show the entire image, only a part of it. The result is, that the overlay isn't placed correctly. Do you have any idea what to do?

Cheers
StefanView attachment 28599

Here is the solution to that (my) problem:
B4X:
        BitmapDescriptor1=BitmapDescriptorFactory1.FromPath(File.DirAssets & "/" & "newark_nj_1922.png")
        GroundOverlayOptions1.Image2(BitmapDescriptor1)
        'The following line will not work and produce the overlay like in the previous post....
        'GroundOverlayOptions1.Image(LoadBitmap(File.DirAssets, "newark_nj_1922.jpg"))
        SouthWest.Initialize(40.712216,-74.22655)
        NorthEast.Initialize(40.773941,-74.12544)
        LatLngBounds1.Initialize(SouthWest, NorthEast)   
        GroundOverlayOptions1.Image2(BitmapDescriptor1)
        GroundOverlayOptions1.PositionFromBounds(LatLngBounds1)
        GroundOverlay1=GoogleMapsExtras1.AddGroundOverlay(gmap, GroundOverlayOptions1)
so using a BitmapDescriptor with GroundOverlayOptions1.Image2 is the solution instead of loading the image directly with GroundOverlayOptions1.Image(LoadBitmap(File.DirAssets, "newark_nj_1922.jpg"))
 

Massimiliano

Member
Licensed User
Longtime User
Hi Martin, great library.
I'm using it with
GMap.MyLocationEnabled = True and
GMapOnMyLocationChange.Initialize("GMapOnMyLocationChange")
GMapEx.SetOnMyLocationChangeListener(GMap, GMapOnMyLocationChange)
inside sub GMapOnMyLocationChange_MyLocationChange(NewLocation As Location) I animate the camera to follow my location over the map

Hower it seems to fire the event every about 3 secs, so the map scrolls is not so fluid

Is it the right way to be followed by a camera view, or there is some better way?

Thank you
 

Massimiliano

Member
Licensed User
Longtime User
Are you saying that a new MyLocationChange event is raised before any previous animation has completed?
No, i'm saying that the MyLocationChange event is raised not so frequently, so if i'm on the road with the car, my location it's refreshed every 100/200 meters (it depends on the car speed). I hope I was clear :)

Thank you so much, Martin
 

Massimiliano

Member
Licensed User
Longtime User
Are you saying that a new MyLocationChange event is raised before any previous animation has completed?
if I'm not asking too much, you could post an example of "follow me over the map" so I can see if it works fine for me?
Many thanks
Massimiliano
 

warwound

Expert
Licensed User
Longtime User
The GoogleMap's built in MyLocation layer has no 'real' configuration options.
Look here: https://developers.google.com/maps/documentation/android/location
See how the MyLocation layer's accuracy is determined by the permission that you add to the manifest?
That's the only configuration option you have with the built in MyLocation layer.

The GoogleMap object does have a method:

setLocationSource(LocationSource source)

https://developer.android.com/refer...e(com.google.android.gms.maps.LocationSource)

Here you'd implement the LocationSource interface and pass an instance of your implementation to the setLocationSource method.
And in your implementation of the LocationSource you're free to get location updates as frequently as you desire.

Using a custom LocationSource is not currently supported in b4a - however i've updated GoogleMapsExtras...

We have 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.


Take a look at this (skeletal) code example:

B4X:
Sub Process_Globals

End Sub

Sub Globals
	Dim CustomLocationSourceOnLocationChangedListener As OnLocationChangedListener
	Dim GoogleMap1 As GoogleMap
	Dim MapFragment1 As MapFragment
	Dim MapPanel As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
	If MapFragment1.IsGooglePlayServicesAvailable Then
		MapPanel.Initialize("")
		Activity.AddView(MapPanel, 0, 0, 100%x, 100%y)
		MapFragment1.Initialize("MapFragment1", MapPanel)
	Else
		Log("Google Play Services is not available")
		ToastMessageShow("Google Play Services is not available", False)
	End If
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub CustomLocationSource1_Activate(OnLocationChangedListener1 As OnLocationChangedListener)
	Log("CustomLocationSource1_Activate")
	CustomLocationSourceOnLocationChangedListener=OnLocationChangedListener1
	'	TODO start listening for location updates
	'	each time a new location update is available you should call:
	
	'	CustomLocationSourceOnLocationChangedListener.OnLocationChanged(ANewLocationObject)
End Sub

Sub CustomLocationSource1_Deactivate
	Log("CustomLocationSource1_Deactivate")
	'	TODO stop listening for location updates
End Sub

Sub MapFragment1_Ready
	Log("MapFragment1_Ready")
	GoogleMap1=MapFragment1.GetMap
	If GoogleMap1.IsInitialized Then
		GoogleMap1.MyLocationEnabled=True
		GoogleMap1.GetUiSettings.MyLocationButtonEnabled=True
		
		Dim CustomLocationSource1 As CustomLocationSource
		CustomLocationSource1.Initialize("CustomLocationSource1")
		
		Dim GoogleMapsExtras1 As GoogleMapsExtras
		GoogleMapsExtras1.SetLocationSource(GoogleMap1, CustomLocationSource1)
		
		Dim CameraPosition1 As CameraPosition
		CameraPosition1.Initialize(52.7523, 0.4049, 10)
		GoogleMap1.AnimateCamera(CameraPosition1)
	Else
		Log("Error initializing GoogleMap")
		ToastMessageShow("Error initializing GoogleMap", False)
	End If
End Sub

Compile and run this code and then click the MyLocation button.
You'll see the CustomLocationSource1_Activate event is raised and passed an OnLocationChangedListener object.

You need to add code to now start listening for location updates, each time your new code gets a new location you pass it to the GoogleMap using the OnLocationChangedListener's OnLocationChanged(Location1 As Location) method.

The MyLocation layer will function as before but use the Locations you pass to it instead of the Locations it gets from it's default LocationSource.

I'd recommend you use the FusedLocationProvider to listen for location updates.
But you can use any library you want to listen for location updates.

I've attached the updated GoogleMapsExtras library files and the above example project.
Can you add code that listens for location updates and passes new Locations to the OnLocationChangedListener?
Test it out and post with your results.

If you can confirm it works as desired i'll update this thread and move the GoogleMapsExtras update to the first post.

Martin.
 

Attachments

  • CustomLocationSource_example.zip
    12.3 KB · Views: 223

warwound

Expert
Licensed User
Longtime User
if I'm not asking too much, you could post an example of "follow me over the map" so I can see if it works fine for me?
Many thanks
Massimiliano

The method you are using looks ok to me.
It's just that the default settings of the GoogleMap's built in LocationSource do not meet your requirements.
Try the update i just posted.
 

Massimiliano

Member
Licensed User
Longtime User
I'll try as soon as possible your code and the Alpha library (until going out with my car :) ).

do you see some strange permission inside me manifest attributes?
AddPermission(android.permission.ACCESS_COARSE_LOCATION)
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.ACCESS_NETWORK_STATE)
AddPermission(android.permission.INTERNET)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)

Massimiliano
 

Massimiliano

Member
Licensed User
Longtime User
The method you are using looks ok to me.
It's just that the default settings of the GoogleMap's built in LocationSource do not meet your requirements.
Try the update i just posted.

I'm writing an app for fieldtest monitor e.g. netmonitor or gmon or gnettrack, but i'm trying to do it in a more simple way for the users. I know it's a bit difficult but i'm giving it a try. I'm using also your open Street map view (where google play services is not available)
 

warwound

Expert
Licensed User
Longtime User
I'll try as soon as possible your code and the Alpha library (until going out with my car :) ).

do you see some strange permission inside me manifest attributes?
AddPermission(android.permission.ACCESS_COARSE_LOCATION)
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.ACCESS_NETWORK_STATE)
AddPermission(android.permission.INTERNET)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)

Massimiliano

Compile your app and then look at the progress dialog box in the b4a IDE.
You should see a 'List Permissions' button.
Give the button a click and it'll tell you which libraries are adding which permissions.

Also an idea for your app...
Look at ActivityRecognition.

In your CustomLocationSource you could detect the user's current activity.
If they are driving then listen for location updates with a fast interval and high accuracy.
If the user is not moving or is walking then listen for location updates with a slower interval - maybe also use lower accuracy.

You'll save battery power by reducing the number of location updates you request when the user is not driving.
 

Massimiliano

Member
Licensed User
Longtime User
Compile your app and then look at the progress dialog box in the b4a IDE.
You should see a 'List Permissions' button.
Give the button a click and it'll tell you which libraries are adding which permissions.

Also an idea for your app...
Look at ActivityRecognition.

In your CustomLocationSource you could detect the user's current activity.
If they are driving then listen for location updates with a fast interval and high accuracy.
If the user is not moving or is walking then listen for location updates with a slower interval - maybe also use lower accuracy.

You'll save battery power by reducing the number of location updates you request when the user is not driving.

Battery it's what I have forever in mind! I like the green :)
i've found this formula, not very accurate (http://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters)
if Sqrt(Power(LAT - NewLocation.Latitude, 2) + Power(LNG - NewLocation.Longitude, 2)) / Globals.RAD > 10 (meters)
where Globals.RAD is
0.000008998719243599958
but seems to meets my needs (hope)
 

msawada

Member
Licensed User
Longtime User
Here is the solution to that (my) problem:
B4X:
        BitmapDescriptor1=BitmapDescriptorFactory1.FromPath(File.DirAssets & "/" & "newark_nj_1922.png")
        GroundOverlayOptions1.Image2(BitmapDescriptor1)
        'The following line will not work and produce the overlay like in the previous post....
        'GroundOverlayOptions1.Image(LoadBitmap(File.DirAssets, "newark_nj_1922.jpg"))
        SouthWest.Initialize(40.712216,-74.22655)
        NorthEast.Initialize(40.773941,-74.12544)
        LatLngBounds1.Initialize(SouthWest, NorthEast) 
        GroundOverlayOptions1.Image2(BitmapDescriptor1)
        GroundOverlayOptions1.PositionFromBounds(LatLngBounds1)
        GroundOverlay1=GoogleMapsExtras1.AddGroundOverlay(gmap, GroundOverlayOptions1)
so using a BitmapDescriptor with GroundOverlayOptions1.Image2 is the solution instead of loading the image directly with GroundOverlayOptions1.Image(LoadBitmap(File.DirAssets, "newark_nj_1922.jpg"))

Thanks Stephan/eurojam. I was able to follow your example and get it to work but only if I use:

B4X:
bitmapdesctiptor1=bitmapdescriptorfactory1.FromAsset("newark_nj_1922.jpg")

I should also mention that the above always gives a null pointer exception in the Rapid Debugger unless you add the following to the main activity:

B4X:
#DebuggerForceStandardAssets: true

using .FromPath(... & "/" & ...) gave a java.lang.NullPointerException because file was not found, no matter how I tried the path to the assets folder.

Now the groundoverlay scales properly.

Thanks again!
Mike
 
Last edited:

Massimiliano

Member
Licensed User
Longtime User
Compile your app and then look at the progress dialog box in the b4a IDE.
You should see a 'List Permissions' button.
Give the button a click and it'll tell you which libraries are adding which permissions.

Also an idea for your app...
Look at ActivityRecognition.

In your CustomLocationSource you could detect the user's current activity.
If they are driving then listen for location updates with a fast interval and high accuracy.
If the user is not moving or is walking then listen for location updates with a slower interval - maybe also use lower accuracy.

You'll save battery power by reducing the number of location updates you request when the user is not driving.

I've compiled the app with the new library, no errors at all.

this is my list permission:

AdView:
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
PhoneWakeState:
android.permission.WAKE_LOCK
PhoneStateListener:
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.CHANGE_NETWORK_STATE
android.permission.ACCESS_COARSE_UPDATES
android.permission.READ_PHONE_STATE
ABWifi:
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.INTERNET
GPS:
android.permission.ACCESS_FINE_LOCATION
TelephonyManager:
android.permission.ACCESS_COARSE_LOCATION
File.DirRootExternal / File.DirDefaultExternal:
android.permission.WRITE_EXTERNAL_STORAGE
MapFragment:
android.permission.INTERNET
android.permission.WRITE_EXTERNAL_STORAGE
com.google.android.providers.gsf.permission.READ_GSERVICES
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
$PACKAGE$.permission.MAPS_RECEIVE
MapView:
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.INTERNET
android.permission.WRITE_EXTERNAL_STORAGE
Manifest Editor:
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_NETWORK_STATE
android.permission.INTERNET
android.permission.WRITE_EXTERNAL_STORAGE

I think it's correct

Tomorrow (hope) i'll give it a test on the road, i nedd to go on a highway to see.
I'll post the results

Many thanks :)
 

Massimiliano

Member
Licensed User
Longtime User
Hello Martin,
sorry but probably I did not understand something.
Since I'm not waiting more for the MyLocationChange event,
but I've implemented the FusedLocation library for locations (very accurate it seems),
I couldn't animate the camera inside the FusedLocation LocationChanged event?
Or maybe I'm missing something?
 

warwound

Expert
Licensed User
Longtime User
Hello Martin,
sorry but probably I did not understand something.
Since I'm not waiting more for the MyLocationChange event,
but I've implemented the FusedLocation library for locations (very accurate it seems),
I couldn't animate the camera inside the FusedLocation LocationChanged event?
Or maybe I'm missing something?

There shouldn't be a problem animating the map in the LocationChanged event.
Can you post your code so i can see what the problem is?
 

Massimiliano

Member
Licensed User
Longtime User
As I sayd, your code (2.0 Alpha) compile and run fine with the old MyLocationChanged event (tested some minutes ago). But the events raised are like before.
I've done a road test with your FusedLocation and believe in me latitude and longitude goes in a magical way, very well

Tomorrow i'll clear my code for unnecessary things and i'll send you, because probably i'm doing something wrong
That's why I'm afraid I did not understand something
 

Massimiliano

Member
Licensed User
Longtime User
Hi Martin, this is the core of the Map Animation.
What about if I change GMapOnMyLocationChange_MyLocationChange with FusedLocationProvider LocationChange?

B4X:
Sub Process_Globals
End Sub

Sub Globals
    Dim FTime As Boolean = True

    Dim GMap As GoogleMap
    Dim GMapEx As GoogleMapsExtras
    Dim GMapOnMyLocationChange As OnMyLocationChangeListener
    Dim mFragment As MapFragment
    Dim MapPanel As Panel
End Sub

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
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub Map_Ready
    GMap = mFragment.GetMap
    If GMap.IsInitialized = False Then
        ToastMessageShow("Error initializing Google Maps", True)
    Else
        GMap.TrafficEnabled = True
        GMap.MyLocationEnabled = True
        GMap.GetUiSettings.AllGesturesEnabled = True
        GMap.GetUiSettings.CompassEnabled = True
        GMap.GetUiSettings.MyLocationButtonEnabled = True
        GMap.GetUiSettings.RotateGesturesEnabled = True
        GMap.GetUiSettings.TiltGesturesEnabled = True
        GMap.GetUiSettings.ZoomControlsEnabled = True
        GMap.GetUiSettings.ZoomGesturesEnabled = True

        GMapOnMyLocationChange.Initialize("GMapOnMyLocationChange")
        GMapEx.SetOnMyLocationChangeListener(GMap, GMapOnMyLocationChange)
        GMapEx.SetBuildingsEnabled(GMap, True)
        GMapEx.SetIndoorEnabled(GMap, True)
    End If
End Sub

Sub GMapOnMyLocationChange_MyLocationChange(NewLocation As Location)
    Dim CP As CameraPosition
    If FTime Then
        FTime = False
        CP.Initialize(NewLocation.Latitude, NewLocation.Longitude, 15)
    Else
        CP.Initialize(NewLocation.Latitude, NewLocation.Longitude, GMap.CameraPosition.Zoom)
    End If
    GMap.AnimateCamera(CP)
End Sub
 

warwound

Expert
Licensed User
Longtime User
Look at this.
I've used FusedLocationProvider as a CustomLocationSource:

B4X:
Sub Process_Globals
	Private FusedLocationProvider1 As FusedLocationProvider
End Sub

Sub Globals
	Dim CustomLocationSourceOnLocationChangedListener As OnLocationChangedListener
	Dim GoogleMap1 As GoogleMap
	Dim MapFragment1 As MapFragment
	Dim MapPanel As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
	If FirstTime Then
		FusedLocationProvider1.Initialize("FusedLocationProvider1")
	End If
	
	If MapFragment1.IsGooglePlayServicesAvailable Then
		MapPanel.Initialize("")
		Activity.AddView(MapPanel, 0, 0, 100%x, 100%y)
		MapFragment1.Initialize("MapFragment1", MapPanel)
	Else
		Log("Google Play Services is not available")
		ToastMessageShow("Google Play Services is not available", False)
	End If
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)
	If FusedLocationProvider1.IsConnected OR FusedLocationProvider1.IsConnecting Then
		FusedLocationProvider1.Disconnect
	End If
End Sub

Sub CustomLocationSource1_Activate(OnLocationChangedListener1 As OnLocationChangedListener)
	Log("CustomLocationSource1_Activate")
	CustomLocationSourceOnLocationChangedListener=OnLocationChangedListener1
	'	start listening for location updates
	'	each time a new location update is available you should call:
	
	'	CustomLocationSourceOnLocationChangedListener.OnLocationChanged(ANewLocationObject)
	FusedLocationProvider1.Connect
End Sub

Sub CustomLocationSource1_Deactivate
	Log("CustomLocationSource1_Deactivate")
	'	stop listening for location updates
	FusedLocationProvider1.Disconnect
End Sub

Sub FusedLocationProvider1_ConnectionFailed(ConnectionResult1 As Int)
	Log("FusedLocationProvider1_ConnectionFailed")
	
	'	the FusedLocationProvider ConnectionResult object contains the various ConnectionResult constants
	
	Select ConnectionResult1
		Case FusedLocationProvider1.ConnectionResult.NETWORK_ERROR
			'	a network error has occurred, this is likely to be a recoverable error
			'	so try to connect again
			FusedLocationProvider1.Connect
		Case Else
			'	TODO handle other errors
	End Select
End Sub

Sub FusedLocationProvider1_ConnectionSuccess
	Log("FusedLocationProvider1_ConnectionSuccess")
	Dim LocationRequest1 As LocationRequest
	LocationRequest1.Initialize
	LocationRequest1.SetInterval(1000)	'	1000 milliseconds
	LocationRequest1.SetPriority(LocationRequest1.Priority.PRIORITY_HIGH_ACCURACY)
	LocationRequest1.SetSmallestDisplacement(1)	'	1 meter
	FusedLocationProvider1.RequestLocationUpdates(LocationRequest1)
End Sub

Sub FusedLocationProvider1_ConnectionSuspended(SuspendedCause1 As Int)
	Log("FusedLocationProvider1_ConnectionSuspended")
	
	'	the FusedLocationProvider SuspendedCause object contains the various SuspendedCause constants
	
	Select SuspendedCause1
		Case FusedLocationProvider1.SuspendedCause.CAUSE_NETWORK_LOST
			'	TODO take action
		Case FusedLocationProvider1.SuspendedCause.CAUSE_SERVICE_DISCONNECTED
			'	TODO take action
	End Select
End Sub

Sub FusedLocationProvider1_LocationChanged(Location1 As Location)
	Log("FusedLocationProvider1_LocationChanged")
	'	pass the new Location from the FusedLocationProvider to the CustomLocationSource using the OnLocationChangedListener
	'	the new Location will be displayed on the map along with an accuracy circle
	CustomLocationSourceOnLocationChangedListener.OnLocationChanged(Location1)
	
	'	animate the map center to the new Location keeping the existing zoom level
	Dim CameraPosition1 As CameraPosition
	CameraPosition1.Initialize(Location1.Latitude, Location1.Longitude, GoogleMap1.CameraPosition.Zoom)
	GoogleMap1.AnimateCamera(CameraPosition1)
End Sub

Sub MapFragment1_Ready
	Log("MapFragment1_Ready")
	GoogleMap1=MapFragment1.GetMap
	If GoogleMap1.IsInitialized Then
		GoogleMap1.GetUiSettings.MyLocationButtonEnabled=True
		
		Dim CameraPosition1 As CameraPosition
		CameraPosition1.Initialize(52.7523, 0.4049, 16)
		GoogleMap1.AnimateCamera(CameraPosition1)
		
		Dim CustomLocationSource1 As CustomLocationSource
		CustomLocationSource1.Initialize("CustomLocationSource1")
		Dim GoogleMapsExtras1 As GoogleMapsExtras
		GoogleMapsExtras1.SetLocationSource(GoogleMap1, CustomLocationSource1)
		
		GoogleMap1.MyLocationEnabled=True
	Else
		Log("Error initializing GoogleMap")
		ToastMessageShow("Error initializing GoogleMap", False)
	End If
End Sub
  • SetLocationSource is called and then MyLocation is enabled.
  • The CustomLocationSource Activated event is raised and passed an OnLocationChangedListener - a global reference is kept to the OnLocationChangedListener as we need to call it's OnLocationChanged method elsewhere in the activity.
  • The FusedLocationProvider Connect method is called.
  • The FusedLocationProvider ConnectionSuccess event is raised.
  • A LocationRequest is created and passed to the FusedLocationProvider RequestLocationUpdates method.
  • Each time the FusedLocationProvider LocationChanged event is raised it is passed a new Location.
    • The new Location is passed to the GoogleMap by calling the OnLocationChangedListener OnLocationChanged method.
      The GoogleMap is now using the Location provided by the CustomLocationSource.
      The Location will be displayed on the map along with an accuracy circle.
    • A new CameraPosition is initialized and passed to the GoogleMap AnimateCamera method.
      The map smoothly centers on the new Location.

Compile and run the example.
Now comment out this line, compile and run again:

B4X:
'	GoogleMapsExtras1.SetLocationSource(GoogleMap1, CustomLocationSource1)

You'll see the GoogleMap's default LocationSource in use - do you see slower updates?

Repeat the tests with different LocationRequest parameters - experiment with different Interval, Priority and SmallestDisplacement values - until you find parameters that suit your application.

Martin.
 

Attachments

  • CustomLocationSource_and_FusedLocationProvider.zip
    12.9 KB · Views: 225
Last edited:

Massimiliano

Member
Licensed User
Longtime User
Look at this.
I've used FusedLocationProvider as a CustomLocationSource:
Martin.

I just tried inside my app and it works fine. To give you an example, give a look at the exported kml
Tomorrow I'll tell you how it works with the removed line GoogleMapsExtras1.SetLocationSource(GoogleMap1, CustomLocationSource1)

Thank you Martin
I'va made a donation to you
 

Attachments

  • 2015-05-19_16.16.40.kml.zip
    2.7 KB · Views: 181
Top