The "Navigation" and "GPS pointer" buttons are being shown at the right bottom of the component after clicking on a marker. The customer would like to prevent these buttons from being shown in their app.
The application is being build with Delphi 12.1 and the default TMapView component available in the FireMonkey Framework is being used.
Marker on Google maps clicked and buttons are being shown at the right bottom
We found that it is possible to disable this MapToolBar via map.getUiSettings().setMapToolbarEnabled(false);
Android google maps marker disable navigation option
But we could not find anyway to do this with the default TMapView.
After searching in the FireMonkey Framework code, we found the JGoogleMap interface in Androidapi.JNI.PlayServices.Maps unit. This interface has the required methods as described above. So next step is to find where this interface is being used. An instance of this interface is internally used in the TAndroidMapView implementation. We assume that an instance of this class is being used in the MapView component. But no possibility to access this instance from outside the class implementation.
We tried using Rtti to access this instance but that did not work
class function TFrameAndroidViewMap.DisableMapToolBarRtti(const MapView: TMapView): Boolean;
begin
Result := False;
var RttiContext := TRttiContext.Create;
try
var MapViewControlRttiType := RttiContext.GetType(MapView.ClassType);
var FieldMapView: TRttiField;
if not TryGetRttiFieldByName(MapViewControlRttiType, 'FMapView', FieldMapView) then
Exit;
var FieldMapViewValue := FieldMapView.GetValue(MapView);
var MapViewInstance: TMapViewBase;
if not FieldMapViewValue.TryAsType<TMapViewBase>(MapViewInstance) then
Exit;
var MapViewInstanceClassType := MapViewInstance.ClassType;
var MapViewInstanceClassName := MapViewInstance.ClassName;
var MapViewInstanceRttiType := RttiContext.GetType(MapViewInstanceClassType);
var FieldGoogleMap: TRttiField;
if not TryGetRttiFieldByName(MapViewInstanceRttiType, 'FGoogleMap', FieldGoogleMap) then
Exit;
var GoogleMapFieldValue := FieldGoogleMap.GetValue(MapViewInstance);
var GoogleMapField: JGoogleMap;
if GoogleMapFieldValue.TryAsType<JGoogleMap>(GoogleMapField) then
begin
GoogleMapField.getUiSettings().setMapToolbarEnabled(False);
Result := True;
end;
finally
RttiContext.Free;
end;
end;
You actually can access the underlying Android references, however not the JGoogleMap
reference, at least not directly. You can however access the JMapView
reference (actually, JMapViewWithGestures
, but it's just a descendant of JMapView
) by using the Supports
method on the TMapView
. From there, the getMapAsync
method can be called to obtain the JGoogleMap
reference. Long story short - here's an example:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Maps,
Androidapi.JNI.PlayServices.Maps;
type
TForm1 = class(TForm)
MapView1: TMapView;
procedure FormCreate(Sender: TObject);
private
FMap: JGoogleMap;
FMapReadyCallback: JOnMapReadyCallback;
procedure MapReady(AMap: JGoogleMap);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
uses
Androidapi.JNIBridge;
type
TMapReadyCallback = class(TJavaLocal, JOnMapReadyCallback)
private
FCallback: TProc<JGoogleMap>;
public
{ JOnMapReadyCallback }
procedure onMapReady(googleMap: JGoogleMap); cdecl;
public
constructor Create(const ACallback: TProc<JGoogleMap>);
end;
{ TMapReadyCallback }
constructor TMapReadyCallback.Create(const ACallback: TProc<JGoogleMap>);
begin
inherited Create;
FCallback := ACallback;
end;
procedure TMapReadyCallback.onMapReady(googleMap: JGoogleMap);
begin
FCallback(googleMap);
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
LMapView: JMapView;
begin
if Supports(MapView1, JMapView, LMapView) then
begin
FMapReadyCallback := TMapReadyCallback.Create(MapReady);
LMapView.getMapAsync(FMapReadyCallback);
end;
end;
procedure TForm1.MapReady(AMap: JGoogleMap);
begin
FMap := AMap;
FMap.getUiSettings.setMapToolbarEnabled(False);
end;
end.
Explanation:
getMapAsync
as the name implies, is an asynchronous call that takes a reference to a callback where the onMapReady
is called when the JGoogleMap
reference becomes available. The TMapReadyCallback
class implements JOnMapReadyCallback
that has this method. It in turn calls the callback method MapReady
which was passed to the class in the constructor.
In MapReady
you now have access to the JGoogleMap reference and can call the methods on it, as per the example.