Android Tutorial (old) Google Maps Android v2 tutorial

Status
Not open for further replies.
If you are using B4A v5.80+ then please follow this tutorial: https://www.b4x.com/android/forum/threads/google-maps.63930/#post-404386

GoogleMaps library requires v2.50 or above.

GoogleMaps library allows you to add Google maps to your application. This library requires Android 3+ and will only work on devices with Google Play service.

This tutorial will cover the configuration steps required for showing a map.

1. Download Google Play services - From the IDE choose Run AVD Manager and then choose Tools - SDK Manager. Select Google Play services under the Extras node and install it:

SS-2012-12-18_18.28.04.png


2. Copy google-play-services.jar to the libraries folder - This file is available under:
C:\<android sdk>\extras\google\google_play_services\libproject\google-play-services_lib\libs (ignore the extra space that the forum script insists on adding)
You should copy it to the libraries folder.

2.5. Download the attached library, unzip it and copy to the libraries folder.

3. Find the key signature - Your application must be signed with a private key other than the debug key. After you select a new or existing key file (Tools - Private Sign Key) you should reopen the private key dialog. The signature information will be displayed (increase the dialog size as needed).
The value after SHA1 is required for the next step:

SS-2012-12-18_18.11.34.png


4. Create an API project - Follow these steps and create an API project.
You should follow the steps under "Creating an API Project" and "Obtaining an API key".

Tips:
- Make sure to select "Google Maps Android API v2" in the services list and not one of the other similar services.
- Under "Simple API Access" you should select "Key for Android apps (with certificates".

5. Add the following code to the manifest editor:
B4X:
AddManifestText( <permission
          android:name="$PACKAGE$.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
      <uses-feature android:glEsVersion="0x00020000" android:required="true"/>)

AddApplicationText(<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyCzspmxxxxxxxxxxxxx"/>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"
    />)
AddPermission(android.permission.ACCESS_NETWORK_STATE)
You should replace the value after android:value with the key you received in the previous step.

6. Add an #AdditionalRes attribute to the main activity:

You should add a reference to Google play resources by adding the following line:
B4X:
#AdditionalRes: <google-play-services res folder>, com.google.android.gms
For example:

#AdditionalRes: C:\android-sdk-windows\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms

Run the following code:
B4X:
'Activity module
Sub Process_Globals

End Sub

Sub Globals
   Dim mFragment As MapFragment
   Dim gmap As GoogleMap
   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 Map_Ready
   Log("map ready")
   gmap = mFragment.GetMap
   If gmap.IsInitialized = False Then
      ToastMessageShow("Error initializing map.", True)
   Else
      gmap.AddMarker(36, 15, "Hello!!!")
      Dim cp As CameraPosition
      cp.Initialize(36, 15, gmap.CameraPosition.Zoom)
      gmap.AnimateCamera(cp)
   End If
End Sub

You should see:

SS-2012-12-18_18.25.14.png


If you see a "white map" then there is most probably a mismatch between the: package name, sign key and the API key (from the manifest editor).

Google documentation: https://developers.google.com/maps/documentation/android/intro
Note that there is a required attribution which you must include in your app (see above link). You can get the string by calling MapFragment.GetOpenSourceSoftwareLicenseInfo.

V1.01: Fixes a bug in AddMarker2.
 

Attachments

  • GoogleMaps.zip
    17.8 KB · Views: 11,422
Last edited:

ValDog

Active Member
Licensed User
Longtime User
Erel, thanks! I knew that... :)

So, let me ask you:

1) How to sense a zoom change event, and then how to read the new zoom level?

2) How to trigger a MapFragment CameraChange event? I can't seem to do it.

3) If I initialize my Camera with a location and zoom level (and AnimateCamera), and then try to read the zoom level with CameraPosition.Zoom it returns a value like 2 - very different than my initialization zoom level. Can you explain what is happening?

Update: CameraPosition.Zoom may be returning a value like 3 ...
 
Last edited:

warwound

Expert
Licensed User
Longtime User
1) How to sense a zoom change event, and then how to read the new zoom level?

You'll need to listen for the MapFragment CameraChange (Position As CameraPosition) event.
There's no specific 'ZoomChange' event just the CameraChange event.

2) How to trigger a MapFragment CameraChange event? I can't seem to do it.

Hmm not sure what you mean here - have you created a Sub to listen for the event but the Sub doesn't get called?

3) If I initialize my Camera with a location and zoom level (and AnimateCamera), and then try to read the zoom level with CameraPosition.Zoom it returns a value like 2 - very different than my initialization zoom level. Can you explain what is happening?

Update: CameraPosition.Zoom may be returning a value like 3 ...

Could it be that you setting the map position and then getting the map zoom level before the map has had time to adjust to the new map position?
GoogleMapsExtras has this method:
  • SetOnMapLoadedCallback (GoogleMap1 As GoogleMap, OnMapLoadedCallback1 As OnMapLoadedCallback)
    Sets a callback that's invoked when the map has finished rendering.
The OnMapLoadedCallback raises the MapLoaded event when:

...the map has finished rendering.
This occurs after all tiles required to render the map have been fetched, and all labelling is complete.
This event will not be raised if the map never loads due to connectivity issues, or if the map is continuously changing and never completes loading due to the user constantly interacting with the map.
This event will only be raised once.
You must request another callback if you want to be notified again.

Martin.
 

ValDog

Active Member
Licensed User
Longtime User
You'll need to listen for the MapFragment CameraChange (Position As CameraPosition) event.
There's no specific 'ZoomChange' event just the CameraChange event.



Hmm not sure what you mean here - have you created a Sub to listen for the event but the Sub doesn't get called?



Could it be that you setting the map position and then getting the map zoom level before the map has had time to adjust to the new map position?
GoogleMapsExtras has this method:
  • SetOnMapLoadedCallback (GoogleMap1 As GoogleMap, OnMapLoadedCallback1 As OnMapLoadedCallback)
    Sets a callback that's invoked when the map has finished rendering.
The OnMapLoadedCallback raises the MapLoaded event when:



Martin.


Martin,

Regarding Item 2, yes I have created a Sub to listen for the event, but the Sub does not get called. ???

As to Item 3, I think you are correct - I'll try the callback.

Thank you!
 

warwound

Expert
Licensed User
Longtime User
Regarding Item 2, yes I have created a Sub to listen for the event, but the Sub does not get called. ???

All i can suggest is to check that the MapFragment EventName parameter used in Initialize matches your Sub name prefix.
If that all looks OK then you'll have to upload your code or a non-working example and i'll try to debug it.

Martin.
 

Spinter

Active Member
Licensed User
Longtime User
sorry my eng im traslated by Google!
how can I create a marker placing it at the center of the screen without touching the screen?

I need this to perfectly position the marker where I want!
 

Spinter

Active Member
Licensed User
Longtime User
solved.

B4X:
Sub Map_CameraChange (Position As CameraPosition)
Dim latMark As String 
Dim lonMark As String
latMark =Position.Target.Latitude
lonMark =Position.Target.Longitude
gmap.AddMarker2( latMark,lonMark,"test",gmap.HUE_YELLOW)   
End Sub
 

ValDog

Active Member
Licensed User
Longtime User
All i can suggest is to check that the MapFragment EventName parameter used in Initialize matches your Sub name prefix.
If that all looks OK then you'll have to upload your code or a non-working example and i'll try to debug it.

Martin.

Thanks! The EventName parameter was exactly the problem...
 

fbritop

Active Member
Licensed User
Longtime User
Erel,
When I compile with:
#Region Project Attributes
#FullScreen: False
#IncludeTitle: False
#ApplicationLabel: Reservame.net
#VersionCode: 5
#VersionName: 2.0
#SupportedOrientations: portrait
#CanInstallToExternalStorage: True
#AdditionalRes C:\SDK\Android\extras\google\google_play_services\libproject\google-play-services_lib\res\, com.google.android.gms
#End Region

gets me an error with
Parsing code. Error
Error parsing program.
Error description: Error parsing attribute: #AdditionalRes C:\SDK\Android\extras\google\google_play_services\libproject\google-play-services_lib\res\, com.google.android.gms
Occurred on line: 9
#AdditionalRes C:\SDK\Android\extras\google\google_play_services\libproject\google-play-services_lib\res\, com.google.android.gms

I'm using version 3.2 now, Google Play Services is revison 14

GoogleMaps library requires v2.50 or above.

GoogleMaps library allows you to add Google maps to your application. This library requires Android 3+ and will only work on devices with Google Play service.

This tutorial will cover the configuration steps required for showing a map.

1. Download Google Play services - From the IDE choose Run AVD Manager and then choose Tools - SDK Manager. Select Google Play services under the Extras node and install it:

SS-2012-12-18_18.28.04.png


2. Copy google-play-services.jar to the libraries folder - This file is available under:

You should copy it to the libraries folder.

2.5. Download the attached library, unzip it and copy to the libraries folder.

3. Find the key signature - Your application must be signed with a private key other than the debug key. After you select a new or existing key file (Tools - Private Sign Key) you should reopen the private key dialog. The signature information will be displayed (increase the dialog size as needed).
The value after SHA1 is required for the next step:

SS-2012-12-18_18.11.34.png


4. Create an API project - Follow these steps and create an API project.
You should follow the steps under "Creating an API Project" and "Obtaining an API key".

Tips:
- Make sure to select "Google Maps Android API v2" in the services list and not one of the other similar services.
- Under "Simple API Access" you should select "Key for Android apps (with certificates".

5. Add the following code to the manifest editor:
B4X:
AddManifestText( <permission
          android:name="$PACKAGE$.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
      <uses-feature android:glEsVersion="0x00020000" android:required="true"/>)
  
AddApplicationText(<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyCzspmxxxxxxxxxxxxx"/>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"
    />)
AddPermission(android.permission.ACCESS_NETWORK_STATE)
)
You should replace the value after android:value with the key you received in the previous step.

6. Add an #AdditionalRes attribute to the main activity:

You should add a reference to Google play resources by adding the following line:
B4X:
#AdditionalRes <google-play-services res folder>, com.google.android.gms
For example:

#AdditionalRes: C:\android-sdk-windows\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms

Run the following code:
B4X:
'Activity module
Sub Process_Globals

End Sub

Sub Globals
   Dim mFragment As MapFragment
   Dim gmap As GoogleMap
   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 Map_Ready
   Log("map ready")
   gmap = mFragment.GetMap
   If gmap.IsInitialized = False Then
      ToastMessageShow("Error initializing map.", True)
   Else
      gmap.AddMarker(36, 15, "Hello!!!")
      Dim cp As CameraPosition
      cp.Initialize(36, 15, gmap.CameraPosition.Zoom)
      gmap.AnimateCamera(cp)
   End If
End Sub

You should see:

SS-2012-12-18_18.25.14.png


If you see a "white map" then there is most probably a mismatch between the: package name, sign key and the API key (from the manifest editor).

Google documentation: https://developers.google.com/maps/documentation/android/intro
Note that there is a required attribution which you must include in your app (see above link). You can get the string by calling MapFragment.GetOpenSourceSoftwareLicenseInfo.

V1.01: Fixes a bug in AddMarker2.

If you are using a version prior to B4A v3.20 then you should follow these instructions:

1. Download an older version of google-play-services: www.b4x.com/android/files/google-play-services.jar

2. Add the following code to the manifest editor, instead of the code above:

B4X:
AddManifestText( <permission
          android:name="$PACKAGE$.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
      <uses-feature android:glEsVersion="0x00020000" android:required="true"/>)
  
AddApplicationText(<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyCzspmxxxxxxxxxxxxx"/>)
You should replace the value after android:value with the key you received in the previous step.

3. Make sure not to add the #AdditionalRes attribute as it is only supported by B4A 3.2+.
 

fbritop

Active Member
Licensed User
Longtime User
Thanks Erel,
I just copied your code which did not include the colon, maybe in can be edited to modify to:
#AdditionalRes: <google-play-services res folder>, com.google.android.gms

On the other hand, there is a marker click event, is there a way that we can intercep a click on en infowindow?

Thanks
FBP
You are missing a colon after #AdditionalRes.
 

warwound

Expert
Licensed User
Longtime User
Thanks Erel,
I just copied your code which did not include the colon, maybe in can be edited to modify to:
#AdditionalRes: <google-play-services res folder>, com.google.android.gms

+1
Get the first post in this thread updated so that the code snippet properly includes the colon in the #AdditionalRes attribute.

Martin.
 

fbritop

Active Member
Licensed User
Longtime User
Thanks Martin,
I was using GM Extras, but I get an error when I call SetOnInfoWindowClickListener:
Cannot get methods of class: uk.co.martinpearman.b4a.googlemapsextras.GoogleMapsExtras, disabling cache.
Error occurred on line: 208 (a3221_main)
java.lang.RuntimeException: Method: SetOnInfoWindowClickListener not found in: uk.co.martinpearman.b4a.googlemapsextras.GoogleMapsExtras
at anywheresoftware.b4a.shell.Shell$MethodCache.getMethod(Shell.java:734)

AdditionalRes is declared in the Main Project.
GoogleMapsExtras version 1.71
B4A version 3.2

Manifiest is:
B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>
<permission
          android:name="$PACKAGE$.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
      <uses-feature android:glEsVersion="0x00020000" android:required="true"/>   
    )
AddApplicationText(<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="*********************"/>
)
   
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")

AddPermission(android.permission.INTERNET)
AddPermission(android.permission.ACCESS_NETWORK_STATE)
AddPermission(com.google.android.providers.gsf.permission.READ_GSERVICES)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)

Any ideas?

+1
Get the first post in this thread updated so that the code snippet properly includes the colon in the #AdditionalRes attribute.

Martin.
 

warwound

Expert
Licensed User
Longtime User
@reservame Is this happening when compiling in 'rapid debug' mode?
There's been a few reports of similar errors when compiling in rapid debug mode.
Compiling in 'traditional debug' mode, release mode or obfuscated mode work with no problems.

Martin.
 

fbritop

Active Member
Licensed User
Longtime User
@reservame Is this happening when compiling in 'rapid debug' mode?
There's been a few reports of similar errors when compiling in rapid debug mode.
Compiling in 'traditional debug' mode, release mode or obfuscated mode work with no problems.

Martin.
Martin,
Indeed, that was the problem. Is there a time frame when this bug could be fixed as for Rapid Debug?

Cheers
FBP
 

warwound

Expert
Licensed User
Longtime User
To be honest i haven't even worked out how to use rapid debug mode in b4a yet, let alone understand why GoogleMapsExtras fails to work in rapid debug mode.
The weekend is just about over and i'll be working throughout the week so i can just say that i'll take a look at it next weekend if i don't have any time to look at it before then.

Martin.
 
Status
Not open for further replies.
Top