这就是我过去从 Google Direction API 获取行车路线的方式。这使用 JSON。可能这对你有帮助。
此类构造查询
public class DirectionAPI extends AbstractQuery {
private static final String URL = "http://maps.googleapis.com/maps/api/directions/";
private static final boolean USE_SENSOR = true;
/**
* Required parameters
*/
/**
* Specifies the start location from which to calculate directions
*/
private static final String PARAM_ORIGIN = "origin";
/**
* Specifies the end location to which to calculate directions.
*/
private static final String PARAM_DESTINATION = "destination";
/**
* Indicates whether or not the directions request comes from a device with a location sensor.
* This value must be either true or false
*/
private static final String PARAM_SENSOR = "sensor";
/**
* Optional parameters
*/
/**
* Specifies what mode of transport to use when calculating directions
*/
private static final String PARAM_TRAVEL_MODE = "mode";
/**
* Travel Modes
*/
public static final String TRAVEL_MODE_DRIVING = "driving";
public static final String TRAVEL_MODE_BICYCLING = "bicycling";
public static final String TRAVEL_MODE_TRANSIT = "transit";
public static final String TRAVEL_MODE_WALKING = "walking";
/**
* Specifies what unit system to use when displaying results
*/
private static final String PARAM_UNIT_SYSTEM = "units";
/**
* Unit systems
*/
public static final String UNIT_SYSTEM_METRIC = "metric";
public static final String UNIT_SYSTEM_IMPERIAL = "imperial";
/**
* Waypoints alter a route by routing it through the specified location(s)
*/
private static final String PARAM_WAYPOINTS = "waypoints";
/**
* Specifies that the route using the supplied waypoints may be optimized to provide the
* shortest possible route. If true, the Directions service will return the reordered
* waypoints in an waypoint_order field
*/
private static final String PARAM_OPTIMIZE_WAYPOINTS = "optimize";
/**
* When set to true specifies that the Directions service may provide more than one route
* alternative in the response. Note that providing route alternatives may increase the
* response time from the server
*/
private static final String PARAM_PROVIDE_ROUTE_ALTERNATIVES = "alternatives";
/**
* Indicates that the calculated route(s) should avoid the indicated features.
* Currently, this parameter supports the following two arguments:
* tolls indicates that the calculated route should avoid toll roads/bridges.
* highways indicates that the calculated route should avoid highways.
*/
private static final String PARAM_AVOID = "avoid";
private static final String AVOID_HIGHWAYS = "highways";
private static final String AVOID_TOLLS = "tolls";
/**
* Specifies the region code, specified as a ccTLD ("top-level domain") two-character value
* https://developers.google.com/maps/documentation/javascript/directions#DirectionsRegionBiasing
*/
private static final String PARAM_REGION = "region";
private LatLng origin;
private LatLng destination;
private Map<LatLng, Boolean> waypoints;
private Map<String, String> optionalParams;
public DirectionAPI(LatLng origin, LatLng destination) {
if (origin == null || destination == null){
throw new NullPointerException("Origin and destination should not be null");
}
this.origin = origin;
this.destination = destination;
optionalParams = new HashMap<String, String>();
waypoints = new HashMap<LatLng, Boolean>();
}
public void addWaypoint(LatLng waypoint, boolean stopOver){
waypoints.put(waypoint, stopOver);
}
public void removeWaypoint(LatLng waypoint){
waypoints.remove(waypoint);
}
public void setTravelMode(String mode){
optionalParams.put(PARAM_TRAVEL_MODE, mode);
}
public void setUnitSystem(String unitSystem){
put(PARAM_UNIT_SYSTEM, unitSystem);
}
public void optimizeWaypoints(boolean optimize){
put(PARAM_OPTIMIZE_WAYPOINTS, String.valueOf(optimize));
}
public void provideRouteAlternatives(boolean provide){
put(PARAM_PROVIDE_ROUTE_ALTERNATIVES, String.valueOf(provide));
}
public void avoid(boolean highways, boolean tolls){
if (!highways && !tolls){
put(PARAM_AVOID, null);
} else if (highways && !tolls){
put(PARAM_AVOID, AVOID_HIGHWAYS);
} else if (!highways){
put(PARAM_AVOID, AVOID_TOLLS);
} else {
put(PARAM_AVOID, AVOID_TOLLS + "|" + AVOID_HIGHWAYS);
}
}
public void setRegion(String region){
put(PARAM_REGION, region);
}
private void put(String key, String value){
if (value == null){
optionalParams.remove(key);
} else {
optionalParams.put(key, value);
}
}
public String constructQuery() {
StringBuilder query = new StringBuilder(URL);
query.append("json").append("?");
query.append(PARAM_ORIGIN).append("=").append(origin.latitude).append(",").append(origin.longitude);
query.append("&");
query.append(PARAM_DESTINATION).append("=").append(destination.latitude).append(",").append(destination.longitude);
query.append("&");
query.append(PARAM_SENSOR).append("=").append(USE_SENSOR);
for (Map.Entry<String, String> entry : optionalParams.entrySet()){
query.append("&");
query.append(entry.getKey()).append("=").append(entry.getValue());
}
if (waypoints.size() > 0){
query.append("&");
query.append(PARAM_WAYPOINTS);
for (Map.Entry<LatLng, Boolean> entry : waypoints.entrySet()){
if (!entry.getValue()){
query.append("via:");
}
LatLng value = entry.getKey();
query.append(value.latitude).append(",").append(value.longitude);
query.append("|");
}
query.deleteCharAt(query.length()-1);
}
return query.toString();
}
public GoogleResponse execute(){
GoogleResponse googleResponse;
try {
java.net.URL url = new URL(constructQuery());
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
if (httpURLConnection.getResponseCode() == 200){
JSONObject jsonObject = JSONParser.parse(httpURLConnection.getInputStream());
googleResponse = new GoogleResponse(jsonObject.getString("status"));
if (googleResponse.isOk()){
googleResponse.setJsonObject(jsonObject);
}
} else {
googleResponse = new GoogleResponse(httpURLConnection.getResponseCode());
}
} catch (MalformedURLException e) {
Log.e(Debug.TAG, e.getMessage(), e);
googleResponse = new GoogleResponse(e);
} catch (IOException e) {
Log.e(Debug.TAG, e.getMessage(), e);
googleResponse = new GoogleResponse(e);
} catch (JSONException e) {
Log.e(Debug.TAG, e.getMessage(), e);
googleResponse = new GoogleResponse(e);
}
return googleResponse;
}
}
此类创建 JSON 对象
public class JSONParser {
public static JSONObject parse(InputStream inputStream){
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(
inputStream, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
inputStream.close();
return new JSONObject(sb.toString());
} catch (UnsupportedEncodingException e) {
Log.e(Debug.TAG, e.getMessage(), e);
} catch (IOException e) {
Log.e(Debug.TAG, e.getMessage(), e);
} catch (JSONException e) {
Log.e(Debug.TAG, e.getMessage(), e);
}
return null;
}
}
该类读取响应状态并检查是否正常。
public class GoogleResponse {
private static final String RESPONSE_OK = "OK";
private static final String RESPONSE_ZERO_RESULT = "ZERO_RESULTS";
private static final String RESPONSE_OVER_QUERY_LIMIT = "OVER_QUERY_LIMIT";
private static final String RESPONSE_REQUEST_DENIED = "REQUEST_DENIED";
private static final String RESPONSE_INVALID_REQUEST = "INVALID_REQUEST";
public static final int OK = 0;
public static final int ERROR_ZERO_RESULT = 10;
public static final int ERROR_OVER_QUERY_LIMIT = 11;
public static final int ERROR_REQUEST_DENIED = 12;
public static final int ERROR_INVALID_REQUEST = 13;
public static final int ERROR_UNKNOWN_RESPONSE = 14;
public static final int ERROR_MALFORMED_URL = 15;
public static final int ERROR_IO = 16;
public static final int ERROR_JSON = 17;
private int response = -1;
private JSONObject jsonObject;
public GoogleResponse(String response) {
if (response.contentEquals(RESPONSE_OK)){
this.response = OK;
} else if (response.contentEquals(RESPONSE_ZERO_RESULT)){
this.response = ERROR_ZERO_RESULT;
} else if (response.contentEquals(RESPONSE_OVER_QUERY_LIMIT)){
this.response = ERROR_OVER_QUERY_LIMIT;
} else if (response.contentEquals(RESPONSE_REQUEST_DENIED)){
this.response = ERROR_REQUEST_DENIED;
} else if (response.contentEquals(RESPONSE_INVALID_REQUEST)){
this.response = ERROR_INVALID_REQUEST;
} else {
Log.e(Debug.TAG, "Unknown response : " + response);
this.response = ERROR_UNKNOWN_RESPONSE;
}
}
public GoogleResponse(Exception e) {
if (e instanceof MalformedURLException){
response = ERROR_MALFORMED_URL;
} else if (e instanceof IOException){
response = ERROR_IO;
} else if (e instanceof JSONException){
response = ERROR_JSON;
}
}
public GoogleResponse(int response) {
this.response = response;
}
public int getResponse() {
return response;
}
public boolean isOk(){
return response < 10;
}
public JSONObject getJsonObject() {
return jsonObject;
}
public void setJsonObject(JSONObject jsonObject) {
this.jsonObject = jsonObject;
}
}
此类解析 JSON 数据。
public class DrivingDirection {
private static final String TAG_ROUTES = "routes";
private static final String TAG_WAYPOINT_ORDER = "waypoint_order";
private static final String TAG_SUMMARY = "summary";
private static final String TAG_BOUNDS = "bounds";
private static final String TAG_LEGS = "legs";
private static final String TAG_WARNINGS = "warnings";
private static final String TAG_OVERVIEW_POLYLINE = "overview_polyline";
private static final String TAG_COPYRIGHTS = "copyrights";
private static final String TAG_BOUND_NORTH_EAST = "northeast";
private static final String TAG_BOUND_SOUTH_WEST = "southwest";
private String summary;
private String copyrights;
private ArrayList<LatLng> overviewPolyline;
private ArrayList<LatLng> smoothPolyline;
private JSONArray warnings;
private JSONArray waypointOrder;
private LatLng boundNorthEast;
private LatLng boundSouthWest;
private ArrayList<DirectionLeg> directionLegs;
private String json;
public DrivingDirection(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray(TAG_ROUTES);
JSONObject jsonObject = jsonArray.getJSONObject(0);
summary = jsonObject.getString(TAG_SUMMARY);
copyrights = jsonObject.getString(TAG_COPYRIGHTS);
overviewPolyline = decodePolyline(jsonObject.getJSONObject(TAG_OVERVIEW_POLYLINE).getString("points"));
warnings = jsonObject.getJSONArray(TAG_WARNINGS);
waypointOrder = jsonObject.getJSONArray(TAG_WAYPOINT_ORDER);
JSONObject bounds = jsonObject.getJSONObject(TAG_BOUNDS);
boundNorthEast = interpretLatLng(bounds.getJSONObject(TAG_BOUND_NORTH_EAST));
boundSouthWest = interpretLatLng(bounds.getJSONObject(TAG_BOUND_SOUTH_WEST));
JSONArray legs = jsonObject.getJSONArray(TAG_LEGS);
directionLegs = new ArrayList<DirectionLeg>(legs.length());
for (int i=0; i<legs.length(); i++){
directionLegs.add(new DirectionLeg(legs.getJSONObject(i)));
}
json = response.toString();
} catch (JSONException e) {
Log.e(Debug.TAG, e.getMessage(), e);
}
}
public String getSummary() {
return summary;
}
public String getCopyrights() {
return copyrights;
}
public ArrayList<LatLng> getOverviewPolyline() {
return overviewPolyline;
}
public ArrayList<LatLng> getTotalPolyline(){
if (smoothPolyline == null) {
smoothPolyline = new ArrayList<LatLng>();
for (DirectionLeg directionLeg : directionLegs){
for (DirectionStep directionStep : directionLeg.getDirectionSteps()){
smoothPolyline.addAll(directionStep.getPolyline());
}
}
}
return smoothPolyline;
}
public JSONArray getWarnings() {
return warnings;
}
public JSONArray getWaypointOrder() {
return waypointOrder;
}
public LatLng getBoundNorthEast() {
return boundNorthEast;
}
public LatLng getBoundSouthWest() {
return boundSouthWest;
}
public ArrayList<DirectionLeg> getDirectionLegs() {
return directionLegs;
}
public long getDistance(){
long distance = 0L;
for (DirectionLeg directionLeg : directionLegs){
distance += directionLeg.getDistance();
}
return distance;
}
public long getDuration(){
long duration = 0L;
for (DirectionLeg directionLeg : directionLegs){
duration += directionLeg.getDuration();
}
return duration;
}
public void addPolyline(Polyline polyline){
polyline.setPoints(this.overviewPolyline);
}
public static ArrayList<LatLng> decodePolyline(String encoded) {
ArrayList<LatLng> poly = new ArrayList<LatLng>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
private static LatLng interpretLatLng(JSONObject object){
try {
return new LatLng(object.getDouble("lat"), object.getDouble("lng"));
} catch (JSONException e) {
Log.e(Debug.TAG, e.getMessage(), e);
}
return null;
}
public String getJson() {
return json;
}
public static class DirectionLeg {
private long duration;
private long distance;
private LatLng startLocation;
private LatLng endLocation;
private String startAddress;
private String endAddress;
private JSONArray viaWaypoints;
private ArrayList<DirectionStep> directionSteps;
public DirectionLeg(JSONObject jsonObject) {
try {
distance = jsonObject.getJSONObject("distance").getLong("value");
duration = jsonObject.getJSONObject("duration").getLong("value");
startAddress = jsonObject.getString("start_address");
endAddress = jsonObject.getString("end_address");
viaWaypoints = jsonObject.getJSONArray("via_waypoint");
startLocation = DrivingDirection.interpretLatLng(jsonObject.getJSONObject("start_location"));
endLocation = DrivingDirection.interpretLatLng(jsonObject.getJSONObject("end_location"));
JSONArray steps = jsonObject.getJSONArray("steps");
directionSteps = new ArrayList<DirectionStep>(steps.length());
for (int i=0; i<steps.length(); i++){
directionSteps.add(new DirectionStep(steps.getJSONObject(i)));
}
} catch (JSONException e) {
Log.e(Debug.TAG, e.getMessage(), e);
}
}
public long getDuration() {
return duration;
}
public long getDistance() {
return distance;
}
public LatLng getStartLocation() {
return startLocation;
}
public LatLng getEndLocation() {
return endLocation;
}
public String getStartAddress() {
return startAddress;
}
public String getEndAddress() {
return endAddress;
}
public JSONArray getViaWaypoints() {
return viaWaypoints;
}
public ArrayList<DirectionStep> getDirectionSteps() {
return directionSteps;
}
}
public static class DirectionStep{
private String htmlInstruction;
private long duration;
private long distance;
private LatLng startLocation;
private LatLng endLocation;
private String travelMode;
private String polyline;
private ArrayList<LatLng> polylinePoints;
public DirectionStep(JSONObject jsonObject){
try {
htmlInstruction = jsonObject.getString("html_instructions");
duration = jsonObject.getJSONObject("duration").getLong("value");
distance = jsonObject.getJSONObject("distance").getLong("value");
JSONObject startLocation = jsonObject.getJSONObject("start_location");
this.startLocation = new LatLng(startLocation.getDouble("lat"), startLocation.getDouble("lng"));
JSONObject endLocation = jsonObject.getJSONObject("end_location");
this.endLocation = new LatLng(endLocation.getDouble("lat"), endLocation.getDouble("lng"));
travelMode = jsonObject.getString("travel_mode");
polyline = jsonObject.getJSONObject("polyline").getString("points");
} catch (JSONException e) {
Log.e(Debug.TAG, e.getMessage(), e);
}
}
public String getHtmlInstruction() {
return htmlInstruction;
}
public long getDuration() {
return duration;
}
public long getDistance() {
return distance;
}
public LatLng getStartLocation() {
return startLocation;
}
public LatLng getEndLocation() {
return endLocation;
}
public String getTravelMode() {
return travelMode;
}
public ArrayList<LatLng> getPolyline() {
if (polylinePoints == null){
polylinePoints = decodePolyline(polyline);
}
return polylinePoints;
}
}
}
典型用法。如果您愿意,您可以设置可选参数,如航点等。
LatLng start = new LatLng(1.11, 1.11);
LatLng end = new LatLng(2.22, 2.22);
DirectionAPI directionAPI = new DirectionAPI(start, end);
GoogleResponse googleResponse = directionAPI.execute();
if (googleResponse.isOk()){
DrivingDirection drivingDirection = new DrivingDirection(googleResponse.getJsonObject());
ArrayList<LatLng> polyline = drivingDirection.getTotalPolyline();
}