本文是基利用Google提供play-services:9.8.0的Google 地图开发,适用于Activity、Fragment中添加google地图,并实现添加Marker和根据经纬度显示运动轨迹;
新版本的google地图开发,已经没有MapView和MapControler等实现地图的操作。
在Activity中的layout中xml是:
<fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.ilang.googlemaptest.MapsActivity" />
Activity中onResume,onPause,onDestroy等可以调用SupportMapFragment的onResume,onPause,onDestroy。
在Fragment中的layout中xml是:
<com.google.android.gms.maps.MapView android:id="@+id/mv_google" android:layout_width="match_parent" android:layout_height="match_parent" />
Fragment中onResume,onPause,onDestroy等可以调用MapView的onResume,onPause,onDestroy。
AndroidManifest.xml添加网络和位置权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.LOCATION_HARDWARE" /> <uses-feature android:name="android.hardware.Sensor" />
application中申明
<meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" />
利用自己编写的一个GoogleMap工具类实现根据经纬度,在Google Map显示图标和运动轨迹,调用接口为setMarkerOnPosition(LatLng latlng)和
showRouteOnMap(LatLng[] latLngs)。
该工具栏有三个initMap方法,前两个是用于Activity中调用,后一个是把MapView放到Fragment中使用时的初始化google地图方法。
下文是完整的GoogleMap工具类代码:
public class GoogleMapHelper implements OnMapReadyCallback { private final String TAG = this.getClass().getSimpleName(); private Context mContext = null; private GoogleMap map = null; private Location mLocation = null; private SupportMapFragment mapFragment = null; private Marker marker = null; private LatLng[] latLngs = null; /** * this method will be used in activity * * @param context * @param resId */ public void initMap(Context context, int resId) { if (context != null) { mapFragment = (SupportMapFragment) ((FragmentActivity) context) .getSupportFragmentManager() .findFragmentById(resId); mContext = context; if (mapFragment != null) { mapFragment.getMapAsync(this); } } } /** * this method will be used in activity * * @param fragment */ public void initMap(SupportMapFragment fragment) { if (fragment != null) { mapFragment = fragment; mapFragment.getMapAsync(this); } } /** * this method will be used in fragment * * @param mapView ,google MapView */ public void initMap(Context context, MapView mapView, Bundle savedInstanceState) { if (mapView != null) { mapView.onCreate(savedInstanceState); //mapView.onResume(); // It will get the map to display immediately try { MapsInitializer.initialize(context); } catch (Exception e) { e.printStackTrace(); } int errorCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context); if (ConnectionResult.SUCCESS != errorCode) { GooglePlayServicesUtil.getErrorDialog(errorCode, (Activity) context, 0) .show(); } else { mapView.getMapAsync(this); } //MapView support next method,it can be used in fragment life time. /*mapView.onCreate(savedInstanceState); mapView.onSaveInstanceState(savedInstanceState); mapView.onStart(); mapView.onResume(); mapView.onPause(); mapView.onStop(); mapView.onDestroy();*/ } } @Override public void onMapReady(GoogleMap googleMap) { map = googleMap; map.setMapType(GoogleMap.MAP_TYPE_NORMAL); map.setTrafficEnabled(true); if (mContext != null) { if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION)) { map.setMyLocationEnabled(true); } } map.setIndoorEnabled(true); if (mLocation != null) { LatLng me = new LatLng(mLocation.getLatitude(), mLocation.getLongitude()); map.addMarker(new MarkerOptions() .position(me) .title("Hello,Marker on my position.")); map.moveCamera(CameraUpdateFactory.newLatLng(me)); map.moveCamera(CameraUpdateFactory.zoomTo(16)); } } public GoogleMap getMap() { return map; } public void setMap(GoogleMap map) { this.map = map; } public Location getLocation() { return mLocation; } public void setLocation(Location mLocation) { this.mLocation = mLocation; } public SupportMapFragment getMapFragment() { return mapFragment; } public void setMapFragment(SupportMapFragment mapFragment) { this.mapFragment = mapFragment; } private double getMaxLatitude(LatLng[] latLngs) { double max = latLngs[0].latitude; for (LatLng latlng : latLngs) { if (max < latlng.latitude) { max = latlng.latitude; } } return max; } private double getMinLatitude(LatLng[] latLngs) { double min = latLngs[0].latitude; for (LatLng latlng : latLngs) { if (min > latlng.latitude) { min = latlng.latitude; } } return min; } private double getMaxLongitude(LatLng[] latLngs) { double max = latLngs[0].longitude; for (LatLng latlng : latLngs) { if (max < latlng.longitude) { max = latlng.longitude; } } return max; } private double getMinLongitude(LatLng[] latLngs) { double min = latLngs[0].longitude; for (LatLng latlng : latLngs) { if (min > latlng.longitude) { min = latlng.longitude; } } return min; } private LatLng getSouthWestLatLng(LatLng[] latLngs) { return new LatLng(getMinLatitude(latLngs), getMinLongitude(latLngs)); } private LatLng getNorthEastLatLng(LatLng[] latLngs) { return new LatLng(getMaxLatitude(latLngs), getMaxLongitude(latLngs)); } /** * realise to move the marker smoothly. * * @param marker, the marker to move * @param toLatLng, the LatLng, move to destination position */ private void moveMarkerSmooth(final Marker marker, LatLng toLatLng) { if (marker != null) { final List<LatLng> roads = new ArrayList<>(); LatLng fromLatLng = marker.getPosition(); //current position LatLng latLng_second = new LatLng((fromLatLng.latitude + toLatLng.latitude) / 2, (fromLatLng.longitude + toLatLng.longitude) / 2); LatLng latLng_first = new LatLng((fromLatLng.latitude + latLng_second.latitude) / 2, (fromLatLng.longitude + latLng_second.longitude) / 2); LatLng latLng_third = new LatLng((latLng_second.latitude + toLatLng.latitude) / 2, (latLng_second.longitude + toLatLng.longitude) / 2); roads.add(latLng_first); roads.add(latLng_second); roads.add(latLng_third); roads.add(toLatLng); Thread move = new Thread(new Runnable() { @Override public void run() { try { for (int i = 0; i < roads.size(); i++) { marker.setPosition(roads.get(i)); Thread.sleep(200); } } catch (Exception e) { e.printStackTrace(); } } }); move.start(); } } public void onResume() { if (mapFragment != null) { mapFragment.onResume(); } } public void onPause() { if (mapFragment != null) { mapFragment.onPause(); } } public void onStop() { if (mapFragment != null) { mapFragment.onStop(); } } /** * 这个方法谨慎使用,在activity的onDestroy()会有问题 */ public void onDestroy() { if (mapFragment != null) { mapFragment.onDestroy(); } } public void clearMap() { if (map != null) { map.clear(); } } public void setMarkerOnPosition(LatLng latLng) { //avoid adding the duplicate marker on map if (map != null) { if (marker != null) { //marker.remove(); //do not use marker.setPosition(latLng); //moveMarkerSmooth(marker, latLng); } else { marker = map.addMarker(new MarkerOptions().position(latLng)); //marker = map.addMarker(new MarkerOptions().position(latLng).icon()); //set marker icon } Log.d(TAG, "set marker on map"); } } public Polyline showRouteOnMap(LatLng[] latLngs) { PolylineOptions lineOptions = new PolylineOptions(); lineOptions.add(latLngs); lineOptions.color(Color.BLUE); lineOptions.geodesic(true); LatLngBounds bounds = new LatLngBounds.Builder() .include(getSouthWestLatLng(latLngs)) .include(getNorthEastLatLng(latLngs)) .build(); if (map != null) { clearMap(); Log.d(TAG, "show route on map"); Polyline line = map.addPolyline(lineOptions); map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); return line; } return null; } }