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

warwound

Expert
Licensed User
Longtime User
Hi all,

Is there a way to access a "longClick" event on a googlemaps marker ?

Thanks

There is no long click event available on a Marker.
That's not because it's not supported in b4a, it's not supported in the underlying android GoogleMaps library :(.

Martin.
 

GMan

Well-Known Member
Licensed User
Longtime User
@GMan

Look in the logs, do you see a message that says 'OnInfoWindowClickListener not initialized as callback sub not found'?
If so then the OnInfoWindowClickListener is not being initialized as the library code cannot find the callback (listener) sub.

Martin.
Unfortunately i cant see logs, but the listener is initialized
 

Elziere_laurent

New Member
Licensed User
Longtime User
hi all,
2 questions :
1)
I'm actually developping an App with a google map, but I can't find all available declaration for Mapfragment Events. I've found :

Map_Ready
Map_MarkerClick (SelectedMarker As Marker) As Boolean
Map_CameraChange (Position As CameraPosition)

Where can I find all others (if exist of course...)

2)
In my map I put polygon (better than polyline because I need a fillcolor). can I link a click_event on those polygons ?

Thanks a lot from Monaco
Laurent
 

warwound

Expert
Licensed User
Longtime User
hi all,
2 questions :
1)
I'm actually developping an App with a google map, but I can't find all available declaration for Mapfragment Events. I've found :

Map_Ready
Map_MarkerClick (SelectedMarker As Marker) As Boolean
Map_CameraChange (Position As CameraPosition)

Where can I find all others (if exist of course...)

The events are listed here: http://www.b4x.com/android/help/googlemaps.html#mapfragment
  • Ready
  • CameraChange (Position As CameraPosition)
  • Click (Point As LatLng)
  • LongClick (Point As LatLng)
  • MarkerClick (SelectedMarker As Marker) As Boolean

2)
In my map I put polygon (better than polyline because I need a fillcolor). can I link a click_event on those polygons ?

Thanks a lot from Monaco
Laurent

There is no support for click events on either Polylines or Polygons.
Your only option is to write your own click detection code.

Martin.
 

warwound

Expert
Licensed User
Longtime User
Unfortunately i cant see logs, but the listener is initialized

I coded the OnInfoWindowClickListener Initialize event to check if the callback sub exists, if the Initialize method does not find the callback sub then it will not initialize the OnInfoWindowClickListener, it will simply log a warning message.
Is there a possibility that the EventName passed to the OnInfoWindowClickListener Initialize method does not match your callback sub's name and therefore the OnInfoWindowClickListener is not initialize even though you have called it's Initialize method?

Martin.
 

GMan

Well-Known Member
Licensed User
Longtime User
Hoi Martin,

the name is the same
 

Elziere_laurent

New Member
Licensed User
Longtime User
thanks for your prompt answer, Martin : excactly what I was looking for.

for polygon event, I will use the map_click(Point As LatLng) event to get LatLng, then look for the good polygon in my memorised polygon_List filled with polygon_List.add(my_GoogleMapsExtras.AddPolygon(gmap, my_PolygonOptions)

when code ready, I'll post it on this thread. Two way to find the good polygon : the "Is inside " method if no overlaped polygons and the "center of gravity" method
 

warwound

Expert
Licensed User
Longtime User
thanks for your prompt answer, Martin : excactly what I was looking for.

for polygon event, I will use the map_click(Point As LatLng) event to get LatLng, then look for the good polygon in my memorised polygon_List filled with polygon_List.add(my_GoogleMapsExtras.AddPolygon(gmap, my_PolygonOptions)

when code ready, I'll post it on this thread. Two way to find the good polygon : the "Is inside " method if no overlaped polygons and the "center of gravity" method

I think if i had to detect a click on a Polygon i'd use a Spatialite database.
Create a table with a row for each Polygon, store the Polygon as a 'Geometry' type and use Spatialite's built in geospatial features to determine whether a clicked map point is contained by any Polygons.

That could be overkill for a simple project and Spatialite will add a few MBs to the size of a compiled APK file, but it is a solution.

Martin.
 

gvoulg

Member
Licensed User
Longtime User
I think if i had to detect a click on a Polygon i'd use a Spatialite database

Martin.

This is the only solution if we have a lot of polygons and specially if some are inside others.In this case I add to calculations the area of the polygons like this
B4X:
  SpatialiteStatement=SpatialiteDatabase.Prepare("SELECT PK_UID,AsText(ExteriorRing(Geometry)),ST_AREA(Geometry) as AREA FROM " & TABLE_NAME & " WHERE ST_Within(MakePoint(?, ?, ?), Geometry) ORDER BY AREA ASC LIMIT 1;")
to get then smallest polygon around the selected point
 

mr23

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



...

I was missing the zipalign.exe, so I installed the build tools for 19.1.0 using SDK Manager. Erel, please consider updating the instructions above to show the need for the Android SDK Build-Tools.
http://forums.xamarin.com/discussion/comment/61621/#Comment_61621

Step 2 here http://www.b4x.com/android/downloads.html does say to install build-tools but the graphic shown doesn't have it checked, which is probably why I missed it. Also, I have 18.0.1's build-tools installed, but either it doesn't include zipalign.exe or something went wrong on the install (some time ago).

Hope this helps someone else.
 

Raul Cavaca

Member
Licensed User
Longtime User
Hi. I'm working with this library but I need to get the last fix time to check if I can this value to set a Client house location on a Database.
Why is MyLocation a LatLng and not a Location Object like in the GoogleMap API?

Thanks
 

Nerdworld

Member
Licensed User
Longtime User
Anyone having a hint?! I'm using the sample code and followed the install instructions.

Running the app in Debug (rapid): Nothing happens, screen stays black, no error message.
Running the app in Debug (legacy): App crashes, produces one of the following errors:

B4X:
java.lang.NoClassDefFoundError: anywheresoftware.b4a.objects.MapFragmentWrapper$MyMapFragment
  at anywheresoftware.b4a.objects.MapFragmentWrapper.Initialize(MapFragmentWrapper.java:115)
  at com.visitweb.inkmap.main._activity_create(main.java:310)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:515)
  at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
  at com.visitweb.inkmap.main.afterFirstLayout(main.java:98)
  at com.visitweb.inkmap.main.access$100(main.java:16)
  at com.visitweb.inkmap.main$WaitForLayout.run(main.java:76)
  at android.os.Handler.handleCallback(Handler.java:733)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:212)
  at android.app.ActivityThread.main(ActivityThread.java:5135)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:515)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
  at dalvik.system.NativeStart.main(Native Method)

B4X:
java.lang.NoClassDefFoundError: com.google.android.gms.common.GooglePlayServicesUtil
   at anywheresoftware.b4a.objects.MapFragmentWrapper.IsGooglePlayServicesAvailable(MapFragmentWrapper.java:101)
   at com.visitweb.inkmap.main._activity_create(main.java:307)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:174)
   at com.visitweb.inkmap.main.afterFirstLayout(main.java:98)
   at com.visitweb.inkmap.main.access$100(main.java:16)
   at com.visitweb.inkmap.main$WaitForLayout.run(main.java:76)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:212)
   at android.app.ActivityThread.main(ActivityThread.java:5135)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
   at dalvik.system.NativeStart.main(Native Method)
 

GMan

Well-Known Member
Licensed User
Longtime User
Both are
NoClassDefFoundError
errors.
Have you installed the Lib correctly (see error 2)
java.lang.NoClassDefFoundError: com.google.android.gms.common.GooglePlayServicesUtil
 

Nerdworld

Member
Licensed User
Longtime User
google-play-services.jar is located under C:\Program Files (x86)\Anywhere Software\Basic4android\addlib
This path is configured under "Configure paths > Additional libraries"

Moving it to the default libraries folder is not making a difference.
 
Status
Not open for further replies.
Top