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,430
Last edited:

gvoulg

Member
Licensed User
Longtime User
That should work with no problems.
You'd create the MapsForge and CustomTile TileOverlays and use the TileOverlay Visible property to control which are visible.

Martin.
Hi Martin
Using OSMDroid library its possible to use a large zip file to save all the structure of the offline tiles.
Do you think that the same technic can be used with Google Maps and CustomTile?
This could save a lot of space on the card and minimize the dowload time to.
George
 

warwound

Expert
Licensed User
Longtime User
Hi Martin
Using OSMDroid library its possible to use a large zip file to save all the structure of the offline tiles.
Do you think that the same technic can be used with Google Maps and CustomTile?

Look back at the example i posted for you here: http://www.b4x.com/android/forum/threads/google-maps-android-v2-tutorial.24415/page-21#post-228632.

If you can:
  • Open the zip file and retrieve the required tile image.
  • Create the Tile object from the required tile image - turn the tile image into a Byte array.

Then there's no reason why you can't do this.
I'd imagine just one possible problem - performance when opening and retrieving tile images from large zip files.

Do some research...
  • There's many different types of compressed archive - zip, rar, tar, tgz etc.
    You might find that android/b4a performs better when using a specific type of compressed archive.
  • Would it be more efficient or perform better to store your tile images as BLOBs in a database?
    Look at the MBTiles method to store tile images in an SQLite database.
    MBTiles is a 'tried and tested' solution that makes full use of SQLite's features.
    A nice feature is the way it can replace multiple identical tiles with a single tile.
    Imagine an area that contains a lot of sea - a single tile can be used instead of many tiles for many areas and many zoom levels.
    If you can select your tile data from the database as binary data you'll probably find it quicker to create the GoogleMap Tile object from that binary data rather than opening a tile image in a zip archive and converting it to a Byte array in order to create the GoogleMap Tile.

Martin.
 

gvoulg

Member
Licensed User
Longtime User

gvoulg

Member
Licensed User
Longtime User
I think that MBTiles is the best way to go .
I will give it a try and see how it goes.
Thanks.
George

Using MBtiles was easier than i thought.
You don't have to use the bitmaptobytearray sub .
that do the job
B4X:
Sub Get_Tile(TileX As Int, TileY As Int, Zoom As Int) As Tile
   Dim Cursor1 As Cursor
   Dim TileFileName As StringBuilder
    Dim Buffer() As Byte
   TileFileName.Initialize
   TileFileName.Append("Select tile_data from images where tile_id = '").Append(Zoom).Append("/").Append(TileX).Append("/").Append(TileY).Append("';")
   Cursor1=gSQL.ExecQuery(TileFileName)
   Cursor1.Position = 0
  Buffer = Cursor1.GetBlob("tile_data")
 
   If Buffer.Length>1 Then
    Dim Tile1 As Tile
    Tile1.Initialize(256,256,Buffer)
    Return Tile1
    Else
    Return CustomTileProvider2.NO_TILE
    End If
End Sub
George
 
Last edited:

dibesw

Active Member
Licensed User
Longtime User
HI,
is there a possibility for set zoom automatic in case of marker is too far away?
Example:
I have some marker:

B4X:
Sub Map_Ready
  Log("map ready")
  gmap = mFragment.GetMap
  If gmap.IsInitialized = False Then
      ToastMessageShow("Error initializing map.", True)
  Else
      Dim Coords() As Double=Array As Double(41.8767711, 12.5415491, 41.8783021, 12.507325, 41.8800497, 12.5115102, 41.8782539, 12.5107392)
      Dim i As Int
      For i=0 To Coords.Length-2 Step 2
        Dim Marker1 As Marker
        Marker1=gmap.AddMarker(Coords(i), Coords(i+1), "Marker #"&i)
        Marker1.Draggable=True
      Next
    
      Dim cp As CameraPosition
      cp.Initialize(41.8767711, 12.5415491, 15)
      gmap.AnimateCamera(cp)
  End If
End Sub

In advance I do not know how much should be set zoom parameters.
If parameters is 15 (as the example), map is:

map1.jpg


and I cannot see others markers

map2.jpg


Can I set zoom automatic depending all markers?

THANKS.
Amedeo
 
Last edited:

DanielShovelton

New Member
Licensed User
Longtime User
Hey im new to B4A and im just wondering if somebody could help me with setting my current location as the maps intialization point , ive tried MyCurrentLocation but it crops up some errors , an example with code would help a lot thank you
 

Pierneefie

Member
Licensed User
Longtime User
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+.
 

Pierneefie

Member
Licensed User
Longtime User
Get an error in :

Dim mFragment As MapFragment
MapFragment not referenced, tried to find the problem for a few days.
Downloaded and copied Google stuff a few times - no success.

How do we trouble shoot missing "references" in B4A ?
 

Pierneefie

Member
Licensed User
Longtime User
Ok, Got it.
The GoogleMaps.zip attached to the tutorial, actually contains the lib files that needs
to be copied to the b4a ../library directory!
 

freedom2000

Well-Known Member
Licensed User
Longtime User
Hi,

I wanted to be able to "redraw" the map and the markers when the app resumes.
I thus modified the sample code like this :

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

Sub Activity_Resume
  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
Sub Map_MarkerClick (SelectedMarker As Marker) As Boolean
      Log(SelectedMarker.Title)

  Return False
End Sub

This code is globally working, on a resume event the map is re initialized and the Map_ready event is triggered.

Everything looks fine but the Map_MarkerClick event never occurs
I mean it did occured on the first launch but after the "resume" it doesn't occur.

Where is my mistake please ?
I have spent hours to try to find it (and it should be obvious) but I must admit that I am lost !

thanks
 

freedom2000

Well-Known Member
Licensed User
Longtime User
You shouldn't initialize it in Activity_Resume. It should be initialized in Activity_Create. Otherwise it will be initialized multiple times.
Thank you erel,

Does this explain why the markers_click event is not triggered after resume ?

If I do not re initialize the map, does it exist a way to force redrawing of the map ?

thnaks
 

freedom2000

Well-Known Member
Licensed User
Longtime User
Thank you erel,

Does this explain why the markers_click event is not triggered after resume ?

Found this way --> works now :

B4X:
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 Activity_Resume

If gmap.IsInitialized Then
    gmap.Clear
    Map_Ready
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
Sub Map_MarkerClick (SelectedMarker As Marker) As Boolean
      Log(SelectedMarker.Title)
 
  Return False
End Sub
 
Status
Not open for further replies.
Top