android端使用json解析调用Google Directions API返回结果的实例

在正在进行的项目中,需要找出地图中起点到终点的行车路线以及距离和相应的时间,这里我们用Google Directions API来实现。


Google Directions API 请求是以下形式的 HTTP 网址:http://maps.googleapis.com/maps/api/directions/output?parameters

其中,output 可能是以下任何一个值:
1、json(建议)表示以 JavaScript 对象表示法 (JSON) 的形式输出;
2、xml 表示以 XML 的形式输出;

具体参数参见https://developers.google.com/maps/documentation/directions/?hl=zh-CN


注意事项:由于我实在android4.0以上的版本上调用Http请求,出现了android.os.NetworkOnMainThreadException异常,所以采用了AsyncTask。

下面贴上具体的代码:

1、运行Http请求的容器,也就是自定义的继承AsyncTask的GetRouteTask类框架:

private class GetRouteTask extends AsyncTask<String, Void, JSONObject>{

@Override
protected void onPreExecute() {
}

@Override
protected JSONObject doInBackground(String... url) {
// TODO Auto-generated method stub
return getRouteFromURL(url[0]);
}

@Override
protected void onPostExecute(JSONObject result) {
}

   /*
    * 根据URL通过Http请求远程调用Google Directions API
    * 并将所要的数据封装到JSONObject中
    */
   private JSONObject getRouteFromURL(String url){
   }
    
   /**
    * 解析返回overview_polyline的路线编码
    * 
    * @param encoded
    * @return
    */ 
   private List<GeoPoint> decodePoly(String encoded) { 
    }
}

如上处理之后,可以在高版本的android上解决 NetworkOnMainThreadException异常了。然后只需在需要用到的地方调用new GetRouteTask().execute(url)即可。具体的AsyncTask类的使用请详见相应的API

2、下面进入正题,来看一下具体的getRouteFromURL方法的代码,如下:

HttpGet get = new HttpGet(url);

       String strResponse = null; 
       try { 
           HttpParams httpParameters = new BasicHttpParams(); 
           HttpConnectionParams.setConnectionTimeout(httpParameters, 8000); 
           HttpClient httpClient = new DefaultHttpClient(httpParameters);  
            
           HttpResponse httpResponse = httpClient.execute(get); 
           Log.e("tag1","tage1");
           if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ 
            strResponse = EntityUtils.toString(httpResponse.getEntity()); 
           } 
       } catch (Exception e) { 
         Log.e("tag3",e.toString());
           return null; 
       } 
       
       if(strResponse == null){
        return null;
       }
       
       try {
JSONObject jsonResponse = new JSONObject(strResponse);
JSONArray routes = jsonResponse.getJSONArray("routes");
Log.e("JSONArray", Integer.toString(routes.length()));
JSONObject route = routes.getJSONObject(0);

JSONArray legs = route.getJSONArray("legs");
JSONObject distance = legs.getJSONObject(0).getJSONObject("distance");
JSONObject duration = legs.getJSONObject(0).getJSONObject("duration");

JSONObject polyline = route.getJSONObject("overview_polyline");
List<GeoPoint> listOfGeoPoint = decodePoly(polyline.getString("points"));
JSONArray geoPoints = new JSONArray();
for(int i=0; i<listOfGeoPoint.size(); i++){
geoPoints.put(i, listOfGeoPoint.get(i));
}

JSONObject result = new JSONObject();
result.put("distance", distance.getString("text"));
result.put("duration", duration.getString("text"));
result.put("geoPoints", geoPoints);
           
Log.e("geoPoints", ((GeoPoint)geoPoints.get(0)).toString());

return result;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
       
       return null;

在JSON解析的过程中,需要了解JSON的格式,如JSONObject和JSONArray。 JSONObject格式如:{ "firstName": "Brett" },一般有{}包括着,然后是key和value。JSONArray格式如:

{ "people": [
  { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },
  { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb"},
  { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" }
  ]}

上面的例子是一个JSONObject包含着一个JSONArray,而JSONArray中包含着三个JSONObject,每个JSONObject中又有多个键值对。

详细请参考http://baike.baidu.com/view/136475.htm


在Google Directions API的返回结果中routes键所对应的JSONArray的下一级只有一个{},故只包含一个JSONObject,该JSONObject又包含了普通的键值对、JSONObject和JSONArray,笔者在开发的过程中疏忽了,花费了好长时间,这里请读者注意。

3、然后是对overview_polyline的路线编码的解码(这个是引用网上的资料,链接是http://blog.csdn.net/ccgang/article/details/6328671

                List<GeoPoint> poly = new ArrayList<GeoPoint>(); 
       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; 

           GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6), 
                (int) (((double) lng / 1E5) * 1E6)); 
           poly.add(p); 
       } 

       return poly; 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值