Android Tutorial Google Maps

Status
Not open for further replies.
upload_2016-2-24_12-2-46.png



Installation instructions:

- Register your app in Google developer console: https://console.developers.google.com
You need to enable Google Maps Android API.
Then click on Credentials -> Create Credentials -> API Key -> Android Key.
You should get a key that looks like: AIzaSyCmFHamGE0O0BvxxxxxxxxXbTCSrjFVg-Q

- Copy the attached library and put it in the additional libraries folder. Add a reference to the GoogleMaps library.

- Add this to the manifest editor (replace the value with your key):
B4X:
CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)

AddApplicationText(
<meta-data
  android:name="com.google.android.geo.API_KEY"
  android:value="xxxxxxxxxxxxxx"/>
)

AddApplicationText(
<uses-library
      android:name="org.apache.http.legacy"
      android:required="false" />
)


Don't add #AdditionalRes or #ExcludeClasses.

- Set minSdkVersion to 14 (Android 4).

- Add a MapFragment with the visual designer. It will appear under the CustomView menu. If you don't see it then make sure that the GoogleMaps library is selected.
You can change the properties from the designer.
Set the anchors to BOTH so the map will fill the activity:

SS-2016-02-24_12.13.18.png



Implement the Ready event to get a reference to the GoogleMap object.
Complete code:
B4X:
Sub Process_Globals
   Private rp As RuntimePermissions
End Sub

Sub Globals
   Private gmap As GoogleMap
   Private MapFragment1 As MapFragment
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("1")
   Wait For MapFragment1_Ready
   gmap = MapFragment1.GetMap
   rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
   Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
   If Result Then
       gmap.MyLocationEnabled = True
   Else
       Log("No permission!")
   End If
End Sub

Notes


Updates

-
v2.50 - Required dependencies were added to the library.
My Location Enabled property was removed from the designer as it needs to be set after the permission is granted.
- v2.02 EXTERNAL_STORAGE permission removed. It is no longer required.
GetOpenSourceLicenseInfo returns an empty string.
Fixes an issue with the ready event being lost if the activity is paused before the map is ready.

Note that you will need to update the package name and api key in the attached example.
 

Attachments

  • GoogleMapsExample.zip
    8.4 KB · Views: 4,281
  • GoogleMaps.zip
    19.4 KB · Views: 4,620
Last edited:

scrat

Active Member
Licensed User
Longtime User
Thank you Erel.
mapfragment is not a view and a panel is automatically added by the designer. I'll have to think about it !

If it's not too much work, it's possible to update the lib without designer ?
 

uniplan

Active Member
Licensed User
Longtime User
I followed as described in the procedure, but when I compile I get this error:

B4A version: 6.30
Parsing code. (0.00s)
Compiling code. error
Error parsing google-services.json:
Index out of range. Requested non-negative value and less than the size of the collection.
Parameter name: index
 

mkvidyashankar

Active Member
Licensed User
Longtime User
Hii

I am getting this error I have tried all the procedure including firebase installation, updating SDK,

struck with this error,please help

B4A version: 6.30
Parsing code. (0.00s)
Compiling code. (0.07s)
Compiling layouts code. (0.00s)
Organizing libraries. Error
Maven artifact not found: com.google.android.gms/play-services-maps

posted many times, but didnt get solution.
 

mkvidyashankar

Active Member
Licensed User
Longtime User
Hi

I have done all the steps below


Open Android SDK Manager and install the latest versions of:

- Android Support Repository
- Google Repository........................................................... done

Register with Firebase and create a new project: https://firebase.google.com/docs/
Make sure that the package name matches your app's package name............................done

Download google-services.json and put it in the projects folder (folder of the b4a file).....done

Add the manifest snippets to the manifest editor based on the services that you need.

B4X:
This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
AddManifestText( <permission
          android:name="$PACKAGE$.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>
      <uses-feature android:glEsVersion="0x00020000" android:required="true"/>)
AddApplicationText(
   <activity android:name="com.google.android.gms.common.api.GoogleApiActivity"
  android:theme="@android:style/Theme.Translucent.NoTitleBar"
  android:exported="false"/>)
  '************ Firebase Base ************
CreateResourceFromFile("google-services", "google-services.json")
AddPermission(android.permission.ACCESS_NETWORK_STATE)
AddPermission(android.permission.INTERNET)
AddPermission(android.permission.WAKE_LOCK)
AddPermission(com.google.android.c2dm.permission.RECEIVE)
AddPermission(${applicationId}.permission.C2D_MESSAGE)
AddManifestText( <permission android:name="${applicationId}.permission.C2D_MESSAGE"
  android:protectionLevel="signature" />)
AddApplicationText(
<receiver
  android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
  android:enabled="true">
  <intent-filter>
  <action android:name="com.google.android.gms.measurement.UPLOAD"/>
  </intent-filter>
  </receiver>

  <service
  android:name="com.google.android.gms.measurement.AppMeasurementService"
  android:enabled="true"
  android:exported="false"/>
   <provider
  android:authorities="${applicationId}.firebaseinitprovider"
  android:name="com.google.firebase.provider.FirebaseInitProvider"
  android:exported="false"
  android:initOrder="100" />
    <receiver
  android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
  android:enabled="true">
  <intent-filter>
  <action android:name="com.google.android.gms.measurement.UPLOAD"/>
  </intent-filter>
  </receiver>

  <service
  android:name="com.google.android.gms.measurement.AppMeasurementService"
  android:enabled="true"
  android:exported="false"/>
   <receiver
  android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
  android:exported="true"
  android:permission="com.google.android.c2dm.permission.SEND" >
  <intent-filter>
  <action android:name="com.google.android.c2dm.intent.RECEIVE" />
  <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
  <category android:name="${applicationId}" />
  </intent-filter>
  </receiver>
    <receiver
  android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
  android:exported="false" />


  <service
  android:name="com.google.firebase.iid.FirebaseInstanceIdService"
  android:exported="true">
  <intent-filter android:priority="-500">
  <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
  </intent-filter>
  </service>
)
'************ Firebase Base (end) ************


AddApplicationText(<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyArj1Jvj-VfaGZLDg3TRE3yrdbfEI6AlZ8"/>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"
    />)
AddPermission(android.permission.ACCESS_NETWORK_STATE)
 
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.

......................................................................................................................................done

Note that a recent version of Google Play Services should be installed on the device.
The minimum version of most features is 2.3 (API 9).

Android Support Repository ............................Version 39 installed
Google Play Services .....................................Version 37 installed
Google Repository...........................................Version 37 installed


I have done all the above steps, but still getting the same error. Maven artifact not found: com.google.android.gms/play-services-maps.
I have also enclosed the code here, as i could not upload the zip file which is of size 5MB.

B4X:
#Region  Project Attributes
    #ApplicationLabel: pci
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: True
    '#AdditionalRes:H:\My Backup\ADT\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
#AdditionalRes:H:\My Backup\ADT\extras\google\google-play-services\libproject\google-play-services_lib\res,com.google.android,gms
#AdditionalJar: com.google.android.gms:play-services-maps

#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    'map key = 'AIzaSyArj1Jvj-VfaGZLDg3TRE3yrdbfEI6AlZ8'
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim spa As Spatialite_Database
    Dim spconstants As Spatialite_Constants
    Private ListView1 As ListView
    Private lbllat As Label
    Private lbllon As Label
    Private lblSatellites As Label
    Private WKBReader1 As JTS_WKBReader
    Private Panel1 As Panel
    Private Label_Details As Label
    Private Button_close As Button
    Private Map_panel As Panel
    Dim gmap As GoogleMap
    Dim mFragment As MapFragment
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
  
    '  Map_panel.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", Map_panel)
   End If
 
    If FirstTime Then
        spa.Initialize
        If File.ExternalWritable=True Then
      
                'If File.Exists(File.DirRootExternal, "veg1.db") = False  Then
                        File.Copy(File.DirAssets, "mm.sqlite", File.DirRootExternal, "mm.sqlite")
                'End If
                spa.Open(File.DirRootExternal, "mm.sqlite", spconstants.SQLITE_OPEN_READWRITE)  
        Else
              
                'If File.Exists(File.DirInternal, "veg1.db") = False  Then
                        File.Copy(File.DirAssets, "mm.sqlite", File.DirInternal, "mm.sqlite")
                'End If
                'sql1.Initialize(File.DirInternal, "veg1.db", True) 
                spa.Open(File.DirInternal, "mm.sqlite", spconstants.SQLITE_OPEN_READONLY)
        End If
        populate
      
      
    End If
  
    'spa.Open(File.DirAssets,"mm.sqlite",spconstants.SQLITE_OPEN_READONLY)
End Sub

Sub MapFragment1_Ready
   gmap = mFragment.GetMap
   Dim m1 As Marker = gmap.AddMarker(10, 30, "test")
   m1.Snippet = "This is the snippet"
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 populate
    'Dim sqlstring As String
'    sqlstring= "SELECT
    'Dim CountryNames As List
    Dim SpatialiteStatement As Spatialite_Stmt
  
    'CountryNames.Initialize
    SpatialiteStatement=spa.Prepare("SELECT ROAD_NAME, PKUID FROM DRRP_Roads where PCI is Null ORDER BY ROAD_NAME ASC")
    Do While SpatialiteStatement.Step
        ListView1.AddTwoLines2(SpatialiteStatement.ColumnString(0),SpatialiteStatement.ColumnInt(1),SpatialiteStatement.ColumnInt(1))
      
    Loop
    SpatialiteStatement.Close
'    Return CountryNames
  
End Sub

Sub Activity_Resume
    If Starter.GPS1.GPSEnabled = False Then
        ToastMessageShow("Please enable the GPS device.", True)
        StartActivity(Starter.GPS1.LocationSettingsIntent) 'Will open the relevant settings screen.
    Else
        Starter.rp.CheckAndRequest(Starter.rp.PERMISSION_ACCESS_FINE_LOCATION)
    End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
CallSub(Starter, "StopGPS")
End Sub

Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = Starter.rp.PERMISSION_ACCESS_FINE_LOCATION Then
        If Result Then CallSub(Starter, "StartGPS")
    End If
End Sub

Public Sub GpsStatus (Satellites As List)
    Dim sb As StringBuilder
    sb.Initialize
    sb.Append("Satellites:").Append(CRLF)
    For i = 0 To Satellites.Size - 1
        Dim Satellite As GPSSatellite = Satellites.Get(i)
        sb.Append(CRLF).Append(Satellite.Prn).Append($" $1.2{Satellite.Snr}"$).Append(" ").Append(Satellite.UsedInFix)
        sb.Append(" ").Append($" $1.2{Satellite.Azimuth}"$).Append($" $1.2{Satellite.Elevation}"$)
    Next
    lblSatellites.Text = sb.ToString
End Sub

Public Sub LocationChanged(Location1 As Location)
    lbllat.Text = "Lat = " & Location1.ConvertToMinutes(Location1.Latitude)
    lbllon.Text = "Lon = " & Location1.ConvertToMinutes(Location1.Longitude)
    'lblSpeed.Text = $"Speed = $1.2{Location1.Speed} m/s "$
End Sub

Public Sub Listview1_ItemClick (Position As Int, Value As Object)
    Dim id As Int=Value
    Dim txt As String = ""
    Dim SpatialiteStatement As Spatialite_Stmt
  
    'CountryNames.Initialize
    SpatialiteStatement=spa.Prepare("SELECT ROAD_NAME, ROAD_ID,RD_LENGTH, ASTEXT(Geometry) FROM DRRP_Roads where PKUID =" & id)
    Do While SpatialiteStatement.Step
        txt=SpatialiteStatement.ColumnString(0) & CRLF
        txt =txt & "Road ID:" & SpatialiteStatement.Columnint(1) & CRLF
        txt =txt & "Length(Km):" & SpatialiteStatement.ColumnDouble(2) & CRLF
        txt =txt & "Latlon:" & SpatialiteStatement.ColumnString(3) & CRLF
        Label_Details.Text=txt
    Loop
  
    SpatialiteStatement.Close
    Panel1.Visible=True
  
'    Dim pl As Polyline = gmap.AddPolyline
'      Dim l1, l2 As LatLng
'      l1.Initialize(30, 30)
'      l2.Initialize(40, 30)
'      Dim points As List
'      points.Initialize
'      points.Add(l1)
'      points.Add(l2)
'      pl.points = points
End Sub

Sub Button_close_Click
    Panel1.Visible=False
End Sub

need help urgently, Thanks in advance...............
 

mkvidyashankar

Active Member
Licensed User
Longtime User
:) yeah it works, it was pointing to old version, i changed and its working .... Thank you very much

Now getting this error, i am using Google maps version 2

** Service (starter) Start **
** Activity (main) Create, isFirst = true **
main_activity_create (B4A line: 32)
Activity.LoadLayout("Layout1")
java.lang.NoClassDefFoundError: com.google.android.gms.maps.MapFragment
at anywheresoftware.b4a.objects.MapFragmentWrapper.Initialize(MapFragmentWrapper.java:120)
at anywheresoftware.b4a.objects.MapFragmentWrapper.DesignerCreateView(MapFragmentWrapper.java:105)
at anywheresoftware.b4a.objects.CustomViewWrapper.AfterDesignerScript(CustomViewWrapper.java:70)
at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:158)
at anywheresoftware.b4a.objects.ActivityWrapper.LoadLayout(ActivityWrapper.java:209)
at com.pci.survey.main._activity_create(main.java:369)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
at com.pci.survey.main.afterFirstLayout(main.java:102)
at com.pci.survey.main.access$000(main.java:17)
at com.pci.survey.main$WaitForLayout.run(main.java:80)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
--------- beginning of /dev/log/system~i:** Service (starter) Create **


is there any updated version, i checked and found nothing?
 

Jimdriver2

Member
Licensed User
Longtime User
I'm getting the same White tile / no map problem.

I think I've followed the tutorial exactly as written however when I tried to put in the large Firebase Base code into the manifest editor although it compiles and installs fine when I run the app it just crashes straight away. Removing that code enables the app to start but then the white tile problem occurs.

I don't really understand all that code in the Firebase manifest code but I can see that's where there's references to google-services.json (which I've downloaded from my Firebase Console and put in the correct place).

The one thing I'm unsure about from the tutorials is if I need a google-play-services.jar file in either of my library folders? I don't currently because the tutorial, if followed as is currently written doesn't ask me to download that at any point. Do I need to download that SDK extra and then move it into one of my B4A library folders?

EDIT: Got it working!

Think what I missed was the crucial line in the tutorial that says: "You need to enable Google Maps Android API."

Enabled that and now the map appears.
 
Last edited:

cwt

Active Member
Licensed User
Longtime User
I have not used B4A for almost 5 years but have now renewed my license and am dusting off my skills and the apps I wrote years ago. Using B4A v6.31.

I have folowed the instructions for this tutorial to a tee and have Google Maps working fine in my app but at first I had a problem with the Firebase code that I added to the manifest as this tutorial instructed. With the Firebase base block of code added to the manifest the app compiled with no errors but the app crashed on the device as soon as the USB driver added the newly compiled app and tried to start it.

If I comment out the Firebase code in the manifest then my app works perfectly with Google Maps.

First, why do I need the Firebase code in my manifest at all and what in that code might be causing the app crash?
 

jccraig

Member
Licensed User
Longtime User
Well, I tried to follow each step above, but am not having any luck getting Google Maps up and running. I suspect I have several issues, but for now just one... I can't locate google-play-services.jar anywhere. I've updated to the latest SDK and suspect the .jar is no longer in use. That leaves me lost. Any advice? Is there an updated tutorial yet?
 

Jimdriver2

Member
Licensed User
Longtime User
Afraid I can't remember exactly, I got it done on my app back in Oct and have forgotten all the steps, but I think basically having/not having google-play-services.jar wasn't an issue.

What I eventually just did was completely remove the Android SDK and get the most up to date download of it and start fresh with that. That seemed to work. The tutorial does have everything you need to do but it is a little confusing due to the various links to different pages.
 
B4A version: 6.30
Parsing code. (0.00s)
Compiling code. (0.04s)
Compiling layouts code. (0.00s)
Organizing libraries. Error
Maven artifact not found: com.google.android.gms/play-services-maps

hi can you help me with this one? i've done everything in the instructions
 

DonManfred

Expert
Licensed User
Longtime User
hi can you help me with this one?
Make sure you follow the Guide https://www.b4x.com/b4a.html exactly.
Especially

2. Android SDK
  • Download Android SDK.
  • Install the SDK. The SDK doesn't work properly when it is installed in a path with spaces (like "Program Files").
    It is recommended to install it to a custom folder similar to C:\Android
    .
  • Install Android SDK Tools, Android SDK Platform-Tools, Android SDK Build-tools (v23.0.3 is recommended),
    Android Support Repository, Google Repository and at least one platform (see the image below). Use API 14 or above.
  • You can also install Google USB Driver if you need to connect a physical device with USB. A list of other drivers is available here.

 
Status
Not open for further replies.
Top