Android Question Google Maps

DonManfred

Expert
Licensed User
Longtime User
Please help me indicate "My location" on Google Maps.
See the GoogleMaps Tutorial.
You need to request permission and when given you can set the MyLocationEnabled flag to true.

 
Last edited:
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
See the GoogleMaps Tutorial.
Here's my code
B4X:
Sub Process_Globals
    Private rp As RuntimePermissions
End Sub

Sub Globals
    Private gmap As GoogleMap, frag As MapFragment, marc As Marker, pos As CameraPosition
    Dim CenterLat, CenterLong As Float
    Dim pnlAB As Panel
    Dim Title As Label
    Dim Menu As ImageView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("gmap")
    Menu.Visible=False
End Sub

Sub ShowMap(coordinates() As Float, name As String)
    Title.Text=name
    Title.TextSize=Starter.TextSize
    CenterLat=coordinates(0)
    CenterLong=coordinates(1)
    If frag.IsGooglePlayServicesAvailable = False Then Return
'    For Each permission As String In Array(rp.PERMISSION_ACCESS_FINE_LOCATION)
'        rp.CheckAndRequest(permission)
'        Wait For Activity_PermissionResult (permission As String, Result As Boolean)
'        If Result = False Then
'            ToastMessageShow("No permission!", True)
'            Activity.Finish
'            Return
'        Else
'            gmap.MyLocationEnabled=True
'        End If
'    Next
End Sub

Sub frag_Ready
    gmap = frag.GetMap
    pos.Initialize(CenterLat, CenterLong, 10)
    gmap.MoveCamera(pos)
    If marc.IsInitialized Then marc.Remove
    marc = gmap.AddMarker2(pos.Target.Latitude, pos.Target.Longitude, Activity.Title, gmap.HUE_GREEN)
End Sub
Everything is working.
If you uncomment part of the code, an error occurs.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
If you uncomment part of the code, an error occurs.
Corrected the code
B4X:
Sub frag_Ready
    gmap = frag.GetMap
    pos.Initialize(CenterLat, CenterLong, 10)
    gmap.MoveCamera(pos)
    If marc.IsInitialized Then marc.Remove
    marc = gmap.AddMarker2(pos.Target.Latitude, pos.Target.Longitude, Activity.Title, gmap.HUE_GREEN)
    For Each permission As String In Array(rp.PERMISSION_ACCESS_FINE_LOCATION)
        rp.CheckAndRequest(permission)
        Wait For Activity_PermissionResult (permission As String, Result As Boolean)
        If Result = False Then
            ToastMessageShow("No permission!", True)
            Activity.Finish
            Return
        Else
            gmap.MyLocationEnabled=True
        End If
    Next
End Sub
The map shows my position.
Tell me how to set my own icon for my position and get its coordinates?
 
Last edited:
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
Use gmap.myLocation

1714162376846.png


You can create your own marker with gmap.addMarker3
1714162489279.png

You can do this in a timer loop

OR

you can use the GPS object and listen to the location changed event
1714162648466.png

which will do the same thing and then use AddMarker3 to display your own marker.

You will need to turn off MyLocationEnabled
#
 
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
B4X:
private sub timer_tick
private myLoc as Latlng = gmap.myLocation
if (myLoc <> Null) then
  if (theMarker <> null) then
    theMarker.remove
  end if
  theMarker = gmap.addMarker3(myLoc.latitude,myLoc.Longitude,"You are here",LoadBitmap(File.dirassets,"mypng.png")
end if

theMarker is a global marker variable.
 
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
Line 2 of the code provided gets myLocation.

If you want to use the GPS object alternative, there are plenty of examples on the forum showing how to use.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
I did this:
B4X:
Sub frag_Ready
    gmap = frag.GetMap
    pos.Initialize(CenterLat, CenterLong, 10)
    gmap.MoveCamera(pos)
    If marc.IsInitialized Then marc.Remove
    marc = gmap.AddMarker2(pos.Target.Latitude, pos.Target.Longitude, Title, gmap.HUE_GREEN)
    For Each permission As String In Array(rp.PERMISSION_ACCESS_FINE_LOCATION)
        rp.CheckAndRequest(permission)
        Wait For Activity_PermissionResult (permission As String, Result As Boolean)
        If Result = False Then
            ToastMessageShow("No permission!", True)
            Activity.Finish
            Return
        Else
            gmap.MyLocationEnabled=True
            Sleep(3000)
            Log(gmap.myLocation.Latitude)
        End If
    Next
End Sub
At the first launch, everything works without a delay, but upon repeated launches I had to introduce a delay of 3 seconds, otherwise an error occurs.
 
Last edited:
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
What error?

It is not clear why you would want to loop over only 1 permission

The code looks fine, but will only be executed once, when the map fragment is ready. You will need to post an the whole project.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
It is not clear why you would want to loop over only 1 permission
I’m checking one resolution, because that’s how it was in the example. I check the other ones I need in the main module B4A. This
B4X:
    For Each permission As String In Array(rp.PERMISSION_READ_CONTACTS, rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
        rp.CheckAndRequest(permission)
        Wait For Activity_PermissionResult (permission As String, Result As Boolean)
        If Result = False Then
            Activity.Finish
            Return
        End If
    Next
So wrong?
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
What was the error?
Error:
B4X:
mainmenu_setdata (java line: 722)
java.lang.NullPointerException: Attempt to invoke virtual method 'int anywheresoftware.b4a.objects.collections.Map.getSize()' on a null object reference
    at sv.bystrovzorov.mainmenu._setdata(mainmenu.java:722)
    at sv.bystrovzorov.mainmenu._activity_resume(mainmenu.java:486)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:221)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at sv.bystrovzorov.mainmenu.afterFirstLayout(mainmenu.java:111)
    at sv.bystrovzorov.mainmenu.access$000(mainmenu.java:17)
    at sv.bystrovzorov.mainmenu$WaitForLayout.run(mainmenu.java:83)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8919)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
*** Service (starter) Create ***
Using FileProvider? true
** Service (starter) Start **
** Activity (main) Create (first time) **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (loader) Create (first time) **
** Activity (loader) Resume **
** Activity (loader) Pause, UserClosed = false **
Sleep not resumed (context is paused): sv.bystrovzorov.circularprogressbar$ResumableSub_AnimateValueTo
** Activity (mainmenu) Create (first time) **
** Activity (mainmenu) Resume **
I'll try to track it in debug mode, if I can avoid stopping on bookmarks. When stopping, the error does not occur.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
I made an example.
It shows that without setting the delay, gmap.myLocation does not have time to initialize.
I'm asking for advice on how to improve the project.
 

Attachments

  • test.zip
    5.6 KB · Views: 15
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
The key problem is that you did not follow the example properly.

You manifest is missing the following lines
B4X:
AddApplicationText(
<uses-library
      android:name="org.apache.http.legacy"
      android:required="false" />
)

with that the code works for me.

Yes, it take a short while for the mobile app to get a lock on the GPS satellites and start reporting locations. This is perfectly normal.

Add a timer, and check MyLocation in the timer rather than in the initialisemap code.

There is a lot of extra code such as
#AdditionalJar: com.google.android.gms:play-services-maps

which is necessary now.

I also would not have an activity called GoogleMap.

Not sure why you are adding all those permissions in the Manifest, this is unnecessary also.
 
Upvote 0

Sergey_New

Well-Known Member
Licensed User
Longtime User
You manifest is missing the following lines
This is in the main program, I just carelessly transferred it to the example.
Not sure why you are adding all those permissions in the Manifest, this is unnecessary also.
For the same reason :)
Add a timer, and check MyLocation in the timer
Никогда не использовал его раньше. Подскажите пожалуйста, как это сделать правильно.
Спасибо за участие и советы!
 
Upvote 0
Top