20

enter image description here

Is it possible to use a shining blue beam instead inconspicuous arrow in android google MapFragment? This new feature is available for Google Maps on Android. How to implement it in app?

sunil
  • 796
  • 1
  • 8
  • 28
  • any updates please? – AouledIssa Jul 03 '18 at 17:21
  • I've looked everywhere on the official documentation and also some crowd discussions, I guess there is not official way of getting the beam to appear on the map. I assume that you should implement your own solution using the compass sensor and render the heading direction continuously on the map using a custom marker with a beam. Please comment or post a solution if any. Thanks in advance. – AouledIssa Jul 03 '18 at 22:16

1 Answers1

0

I'm assuming you essentially want to replace the directional indicator with your own? If you're looking for full "lines to destination", there's already answers.

This answer suggests starting with a LocationListener override to set a custom icon (.icon(yourIcon) on MarkerOptions):

public class MyLocationLayer implements LocationListener {
    private GoogleMap map;

    private BitmapDescriptor markerDescriptor;
    private boolean drawAccuracy = true;
    private int accuracyStrokeColor = Color.argb(255, 130, 182, 228);
    private int accuracyFillColor = Color.argb(100, 130, 182, 228);

    private Marker positionMarker;
    private Circle accuracyCircle;

    public MyLocationLayer(GoogleMap map, int markerResource) {
        this.map = map;

        markerDescriptor = BitmapDescriptorFactory.fromResource(markerResource);
    }

    public void setDrawAccuracy(boolean drawAccuracy) {
        this.drawAccuracy = drawAccuracy;
    }

    public void setAccuracyStrokeColor(int color) {
        this.accuracyStrokeColor = color;
    }

    public void setAccuracyFillColor(int color) {
        this.accuracyFillColor = color;
    }

    @Override
    public void onLocationChanged(Location location) {
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        float accuracy = location.getAccuracy();

        if (positionMarker != null) {
            positionMarker.remove();
        }
        final MarkerOptions positionMarkerOptions = new MarkerOptions()
                .position(new LatLng(latitude, longitude))
                .icon(markerDescriptor)
                .anchor(0.5f, 0.5f);
        positionMarker = map.addMarker(positionMarkerOptions);

        if (accuracyCircle != null) {
            accuracyCircle.remove();
        }
        if (drawAccuracy) {
            final CircleOptions accuracyCircleOptions = new CircleOptions()
                    .center(new LatLng(latitude, longitude))
                    .radius(accuracy)
                    .fillColor(accuracyFillColor)
                    .strokeColor(accuracyStrokeColor)
                    .strokeWidth(2.0f);
            accuracyCircle = map.addCircle(accuracyCircleOptions);
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

From this you can then add .rotation() after new MarkerOptions() to set the device's current rotation. This could be done by having a parameter on your Fragment / Activity (e.g. private Int rotation = 0), and updating it.

This updating would be done by implementing SensorEventListener in your Fragment / Activity, and inside onSensorChanged(event: SensorEvent) updating your cache of the device's rotation.

A rather complicated way to get rotation (azimut) from the accelerometer and magnetic field is on this answer, as well as a few alternatives.

Make sure you unregister your listeners as appropriate!

Jake Lee
  • 7,549
  • 8
  • 45
  • 86