2017-10-28 248 views
3

我有一個Android應用程序,它在xml文件上添加了SupportMapFragment。 在片段設置我的位置,如下所示:mMap.setMyLocationEnabled(true);顯示我的當前位置谷歌地圖設置爲免費駕駛模式

的主要問題是,步行模式啓用[藍點]默認情況下,我想自由駕駛模式激活[藍色箭頭]

我該如何實現免費駕駛模式?有藍色箭頭爲我的立場,而不是藍色圓點

enter image description here

回答

1

沒有駕駛模式SupportMapFragment並沒有機會來改變默認My Location Marker,但您可以:

1)推出Google Maps在駕駛應用通過意圖模式,如this答案Jason Maderski

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對象更改自定義當前位置指示器上的對象that答案antonio

因爲unpredictability of LocationListener update的我認爲更好經由GpsStatus.NmeaListenerOnNmeaMessageListener爲API> = 24),用於更新當前的位置使用來自GPS NMEA數據(RMC句)。在這種情況下,源代碼可以是類似的東西:

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 & R.drawable.ic_marker_stop - 繪圖資源,如:

Marker for movement (speed > 0)

(北方向是很重要)

分別

Marker for movement (speed = 0)

注意!這是一個沒有NMEA校驗和測試的快速和骯髒的例子,GPS data filtering,在活動可見/隱藏等處保存和恢復標記位置。