Google地图设置为免费驾驶模式

时间:2017-10-28 22:27:51

标签: java android google-maps location

我有一个Android应用程序,在xml文件中添加了SupportMapFragment。 在片段中,我按如下方式设置我的位置:mMap.setMyLocationEnabled(true);以显示我当前的位置

主要问题是步行模式默认启用[蓝点],我希望免费驾驶模式激活[蓝色箭头]

如何实现免费驾驶模式?将蓝色箭头作为我的位置而不是蓝点

enter image description here

1 个答案:

答案 0 :(得分:2)

SupportMapFragment没有驾驶模式,也无法更改默认My Location Marker,但您可以:

1)通过thisJason Maderski回答中的意图,在驾驶模式下启动Google Maps应用程序:

Intent intent = getPackageManager().getLaunchIntentForPackage("com.google.android.apps.maps");
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("google.navigation:/?free=1&mode=d&entry=fnls"));
startActivity(intent);

2)通过GoogleMap对象上的自定义标记更改自定义当前位置指示符,例如thatantonio回答。

由于unpredictability of LocationListener update我认为最好通过NMEARMC获取API> = 24)从GPS获取GpsStatus.NmeaListener数据(OnNmeaMessageListener句子)更新当前位置。在这种情况下,源代码可以是这样的:

<强> CustomNmeaListener.java:

public class CustomNmeaListener implements GpsStatus.NmeaListener{

    private GoogleMap mGoogleMap;
    private Marker mMarkerPosition = null;
    private BitmapDescriptor mMarkerMoveDescriptor;
    private BitmapDescriptor mMarkerStopDescriptor;

    public CustomNmeaListener(GoogleMap googleMap, int markerMoveResource, int markerStopResource){
        this.mGoogleMap = googleMap;

        mMarkerMoveDescriptor = BitmapDescriptorFactory.fromResource(markerMoveResource);
        mMarkerStopDescriptor = BitmapDescriptorFactory.fromResource(markerStopResource);
    }

    @Override
    public void onNmeaReceived(long timestamp, String nmea) {
        double latitude;
        double longitude;
        float speed;
        float angle;

        // parse NMEA RMC sentence
        // Example $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
        //   nmea    [0]   [1]  [2]  [3]   [4]   [5]   [6] [7]   [8]   [9]   [10]  [11]
        if (nmea.startsWith("$GPRMC")) {

            String[] nmeaParts = nmea.split(",");

            // if RMC data valid ("active")
            if (nmeaParts[2].equals("A")) {
                latitude = parseLatitude(nmeaParts[3], nmeaParts[4]);
                longitude = parseLongitude(nmeaParts[5], nmeaParts[6]);
                speed = parseSpeed(nmeaParts[7]);
                angle = parseAngle(nmeaParts[8]);

                // remove marker on "old" position
                if (mMarkerPosition != null) {
                    mMarkerPosition.remove();
                }

                MarkerOptions positionMarkerOptions;

                if (speed > 0) {
                    positionMarkerOptions = new MarkerOptions()
                            .position(new LatLng(latitude, longitude))
                            .icon(mMarkerMoveDescriptor)
                            .anchor(0.5f, 0.5f)
                            .rotation(angle);
                } else {
                    positionMarkerOptions = new MarkerOptions()
                            .position(new LatLng(latitude, longitude))
                            .icon(mMarkerStopDescriptor)
                            .anchor(0.5f, 0.5f)
                            .rotation(0);
                }
                mMarkerPosition = mGoogleMap.addMarker(positionMarkerOptions);
            }
        }

    }

    static float parseLatitude(String lat, String sign) {
        float latitude = Float.parseFloat(lat.substring(2)) / 60.0f;
        latitude +=  Float.parseFloat(lat.substring(0, 2));
        if(sign.startsWith("S")) {
            latitude = -latitude;
        }
        return latitude;
    }

    static float parseLongitude(String lon, String sign) {
        float longitude = Float.parseFloat(lon.substring(3)) / 60.0f;
        longitude +=  Float.parseFloat(lon.substring(0, 3));
        if(sign.startsWith("W")) {
            longitude = -longitude;
        }
        return longitude;
    }

    static float parseSpeed(String knots) {
        float speed;
        try {
            speed = Float.parseFloat(knots);
        } catch (Exception e) {
            speed = 0;
        }
        return speed;
    }

    static float parseAngle(String ang) {
        float angle;
        try {
            angle = Float.parseFloat(ang);
        } catch (Exception e) {
            angle = 0;
        }
        return angle;
    }
}

<强> MainActivity.java:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener {

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 101;

    private static final int LOCATION_INTERVAL = 1000;
    private static final float LOCATION_DISTANCE = 10f;

    private GoogleMap mGoogleMap;
    private MapFragment mMapFragment;

    private LocationManager mLocationManager = null;
    private CustomNmeaListener mNmeaListener = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map_fragment);
        mMapFragment.getMapAsync(this);

    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
            if (locationPermission != PackageManager.PERMISSION_GRANTED) {
                makeLocationPermissionRequest();
            } else {
                setCustomLocationListener();
            }
        } else {
            setCustomLocationListener();
        }
    }

    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case LOCATION_PERMISSION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    setCustomLocationListener();
                } else {
                }
                return;
            }
        }
    }

    private void makeLocationPermissionRequest() {
        ActivityCompat.requestPermissions(this,
                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
    }

    private void setCustomLocationListener() {
        // disable "standard" location marker
        mGoogleMap.setMyLocationEnabled(false);

        initializeLocationManager();
        mNmeaListener = new CustomNmeaListener(mGoogleMap, R.drawable.ic_marker_move, R.drawable.ic_marker_stop);
        mLocationManager.addNmeaListener(mNmeaListener);

        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    LOCATION_INTERVAL,
                    LOCATION_DISTANCE,
                    this
            );
        } catch (java.lang.SecurityException ex) {
            Log.d(TAG, "fail to request location update, ignore", ex);
        }
    }

    private void initializeLocationManager() {
        Log.d(TAG, "initializeLocationManager - LOCATION_INTERVAL: "+ LOCATION_INTERVAL + " LOCATION_DISTANCE: " + LOCATION_DISTANCE);
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        }
    }

}

R.drawable.ic_marker_move&amp; R.drawable.ic_marker_stop - 可绘制的资源,如:

Marker for movement (speed > 0)

(北向很重要)

Marker for movement (speed = 0)

分别

NB!这是一个快速而肮脏的示例,没有NMEA校验和测试,GPS data filtering,在活动可见/隐藏等方面保存和恢复标记位置