最近写了个叫《行踪记录仪》的手机软件,用了百度云来记录每个用户的最近位置,以便各用户能在地图上找到附近的人,为此写了个类来读写数据,大致如下:
1 import java.util.ArrayList; 2 import java.util.HashMap; 3 import java.util.Iterator; 4 import java.util.List; 5 import java.util.Map; 6 7 import org.apache.http.HttpHost; 8 import org.apache.http.HttpResponse; 9 import org.apache.http.HttpStatus; 10 import org.apache.http.client.HttpClient; 11 import org.apache.http.client.entity.UrlEncodedFormEntity; 12 import org.apache.http.client.methods.HttpGet; 13 import org.apache.http.client.methods.HttpPost; 14 import org.apache.http.client.params.ClientPNames; 15 import org.apache.http.client.params.CookiePolicy; 16 import org.apache.http.conn.params.ConnRoutePNames; 17 import org.apache.http.impl.client.DefaultHttpClient; 18 import org.apache.http.message.BasicNameValuePair; 19 import org.apache.http.params.CoreConnectionPNames; 20 import org.apache.http.params.HttpProtocolParams; 21 import org.apache.http.util.EntityUtils; 22 import org.json.JSONObject; 23 24 import android.content.SharedPreferences; 25 import android.os.Handler; 26 import android.os.Message; 27 import android.util.Log; 28 29 import com.baidu.location.BDLocation; 30 import com.baidu.platform.comapi.basestruct.GeoPoint; 31 32 /** 33 * 百度云检索类 34 * 35 * @author Robert Tsing 36 */ 37 public class LBSCloud { 38 39 private static String mTAG = "NetWorkManager"; 40 41 // 百度云检索API URI 42 private static final String SEARCH_URI_NEARBY = "http://api.map.baidu.com/geosearch/v2/nearby?"; 43 private static final String SEARCH_URI_LOCAL = "http://api.map.baidu.com/geosearch/v2/local?"; 44 private static final String SEARCH_URI_BOUND = "http://api.map.baidu.com/geosearch/v2/bound?"; 45 private static final String SEARCH_URI_DETAIL = "http://api.map.baidu.com/geosearch/v2/detail?"; 46 private static final String SEARCH_URI_POI_LIST = "http://api.map.baidu.com/geodata/v2/poi/list?"; 47 48 private static final String POST_URI_CREATE = "http://api.map.baidu.com/geodata/v2/poi/create"; 49 private static final String POST_URI_UPDATE = "http://api.map.baidu.com/geodata/v2/poi/update"; 50 private static final String POST_URI_DELETE = "http://api.map.baidu.com/geodata/v2/poi/delete"; 51 52 public static final int SEARCH_TYPE_NEARBY = 1; 53 public static final int SEARCH_TYPE_LOCAL = 2; 54 public static final int SEARCH_TYPE_BOUND = 3; 55 public static final int SEARCH_TYPE_DETAIL = 4; 56 public static final int SEARCH_TYPE_POI_LIST = 5; 57 58 public static final int POST_TYPE_CREATE = 6; 59 public static final int POST_TYPE_UPDATE = 7; 60 public static final int POST_TYPE_DELETE = 8; 61 62 public static final int RESULT_GET = 0; 63 public static final int RESULT_POST = 1; 64 65 private static int currSearchType = 0; 66 67 // 云检索公钥 68 // private static String ak = "A321c32037052461d6958b34a3e?????"; 69 private static String ak = "E7d8211ca35fc64e838ee15b7d5?????"; 70 private static String geotable_id = "?????"; 71 private static String coord_type = "3"; 72 73 private static String CMWAP_HOST = "10.0.0.172"; 74 private static String CTWAP_HOST = "10.0.0.200"; 75 76 private static int TIME_OUT = 12000; 77 private static int retry = 3; 78 private static boolean Getting = false; 79 80 /** 81 * 云检索访问 82 * 83 * @param filterParams 84 * 访问参数,key为filter时特殊处理。 85 * @param handler 86 * 数据回调Handler 87 * @param networkType 88 * 手机联网类型 89 * @return 90 */ 91 92 //读取的 93 public static boolean request(final int searchType, 94 final HashMap<String, String> filterParams, final Handler handler) { 95 if (Getting || filterParams == null) 96 return false; 97 Getting = true; 98 99 new Thread() { 100 public void run() { 101 int count = retry; 102 while (count > 0) { 103 try { 104 // 根据过滤选项拼接请求URL 105 String requestURL = ""; 106 if (searchType > 0) { 107 currSearchType = searchType; 108 } 109 switch (currSearchType) { 110 case SEARCH_TYPE_NEARBY: 111 requestURL = SEARCH_URI_NEARBY; 112 break; 113 case SEARCH_TYPE_LOCAL: 114 requestURL = SEARCH_URI_LOCAL; 115 break; 116 case SEARCH_TYPE_BOUND: 117 requestURL = SEARCH_URI_BOUND; 118 break; 119 case SEARCH_TYPE_DETAIL: 120 requestURL = SEARCH_URI_DETAIL; 121 break; 122 case SEARCH_TYPE_POI_LIST: 123 requestURL = SEARCH_URI_POI_LIST; 124 break; 125 default: 126 return; 127 } 128 requestURL += "ak=" + ak + "&geotable_id=" 129 + geotable_id; 130 131 String filter = null; 132 Iterator iter = filterParams.entrySet().iterator(); 133 while (iter.hasNext()) { 134 Map.Entry entry = (Map.Entry) iter.next(); 135 String key = entry.getKey().toString(); 136 String value = entry.getValue().toString(); 137 138 if (key.equals("filter")) { 139 filter = value; 140 } else { 141 if (key.equals("region") 142 && currSearchType == SEARCH_TYPE_NEARBY) { 143 continue; 144 } 145 requestURL = requestURL + "&" + key + "=" 146 + value; 147 } 148 } 149 150 if (filter != null && !filter.equals("")) { 151 // substring(3) 为了去掉"|" 的encode "%7C" 152 requestURL = requestURL + "&filter=" 153 + filter.substring(3); 154 } 155 156 Log.d("request url:", requestURL); 157 158 HttpGet httpRequest = new HttpGet(requestURL); 159 HttpClient httpClient = new DefaultHttpClient(); 160 httpClient.getParams().setParameter( 161 CoreConnectionPNames.CONNECTION_TIMEOUT, 162 TIME_OUT); 163 httpClient.getParams().setParameter( 164 CoreConnectionPNames.SO_TIMEOUT, TIME_OUT); 165 166 HttpProtocolParams.setUseExpectContinue( 167 httpClient.getParams(), false); 168 169 String networkType = MapApplication.networkType; 170 if (networkType.equals("cmwap")) { 171 HttpHost proxy = new HttpHost(CMWAP_HOST, 80, 172 "http"); 173 httpClient.getParams().setParameter( 174 ConnRoutePNames.DEFAULT_PROXY, proxy); 175 } else if (networkType.equals("ctwap")) { 176 HttpHost proxy = new HttpHost(CTWAP_HOST, 80, 177 "http"); 178 httpClient.getParams().setParameter( 179 ConnRoutePNames.DEFAULT_PROXY, proxy); 180 } 181 182 // ((AbstractHttpClient) 183 // httpClient).getCookieSpecs().register("chinasource", 184 // new CookieSpecFactory() { 185 // public CookieSpec newInstance(HttpParams params) { 186 // return new LenientCookieSpec(); 187 // } 188 // }); 189 httpClient.getParams().setParameter( 190 ClientPNames.COOKIE_POLICY, 191 CookiePolicy.BROWSER_COMPATIBILITY); 192 193 HttpResponse httpResponse = httpClient 194 .execute(httpRequest); 195 int status = httpResponse.getStatusLine() 196 .getStatusCode(); 197 if (status == HttpStatus.SC_OK) { 198 String result = EntityUtils.toString( 199 httpResponse.getEntity(), "utf-8"); 200 // Header a = 201 // httpResponse.getEntity().getContentType(); 202 Message msgTmp = handler 203 .obtainMessage(MapActivity.MSG_NET_SUCC); 204 msgTmp.obj = result; 205 msgTmp.arg1 = RESULT_GET; 206 msgTmp.sendToTarget(); 207 208 break; 209 } else { 210 httpRequest.abort(); 211 Message msgTmp = handler 212 .obtainMessage(MapActivity.MSG_NET_STATUS_ERROR); 213 msgTmp.obj = "HttpStatus error"; 214 msgTmp.sendToTarget(); 215 } 216 } catch (Exception e) { 217 Log.e("request", "网络异常,请检查网络后重试!"); 218 e.printStackTrace(); 219 } 220 221 count--; 222 } 223 224 if (count <= 0 && handler != null) { 225 Message msgTmp = handler 226 .obtainMessage(MapActivity.MSG_NET_TIMEOUT); 227 msgTmp.sendToTarget(); 228 } 229 230 Getting = false; 231 232 } 233 }.start(); 234 235 return true; 236 } 237 238 public static boolean searchNear(GeoPoint point, Handler handler) { 239 return LBSCloud.request(LBSCloud.SEARCH_TYPE_NEARBY, 240 getRequestParams(point), handler); 241 } 242 243 private static HashMap<String, String> getRequestParams(GeoPoint point) { 244 HashMap<String, String> map = new HashMap<String, String>(); 245 LocationModel lm = new LocationModel(point); 246 map.put("q", ""); 247 map.put("location", lm.getLocation()); 248 map.put("radius", "100000"); 249 map.put("orderby", "create_date:-1"); 250 return map; 251 } 252 253 //写入的 254 public static boolean postData(final int postType, 255 final List<BasicNameValuePair> params) { 256 if (params == null) 257 return false; 258 try { 259 // 根据过滤选项拼接请求URL 260 String requestURL = ""; 261 switch (postType) { 262 case POST_TYPE_CREATE: 263 requestURL = POST_URI_CREATE; 264 break; 265 case POST_TYPE_UPDATE: 266 requestURL = POST_URI_UPDATE; 267 break; 268 case POST_TYPE_DELETE: 269 requestURL = POST_URI_DELETE; 270 break; 271 default: 272 return false; 273 } 274 275 Log.d("request url:", requestURL); 276 params.add(new BasicNameValuePair("geotable_id", geotable_id)); 277 params.add(new BasicNameValuePair("ak", ak)); 278 279 HttpPost httpPost = new HttpPost(requestURL); 280 httpPost.setEntity(new UrlEncodedFormEntity(params, "utf-8")); 281 282 HttpClient httpClient = new DefaultHttpClient(); 283 httpClient.getParams().setParameter( 284 CoreConnectionPNames.CONNECTION_TIMEOUT, TIME_OUT); 285 httpClient.getParams().setParameter( 286 CoreConnectionPNames.SO_TIMEOUT, TIME_OUT); 287 HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), 288 false); 289 290 String networkType = MapApplication.networkType; 291 if (networkType.equals("cmwap")) { 292 HttpHost proxy = new HttpHost(CMWAP_HOST, 80, "http"); 293 httpClient.getParams().setParameter( 294 ConnRoutePNames.DEFAULT_PROXY, proxy); 295 } else if (networkType.equals("ctwap")) { 296 HttpHost proxy = new HttpHost(CTWAP_HOST, 80, "http"); 297 httpClient.getParams().setParameter( 298 ConnRoutePNames.DEFAULT_PROXY, proxy); 299 } 300 httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, 301 CookiePolicy.BROWSER_COMPATIBILITY); 302 HttpResponse httpResponse = httpClient.execute(httpPost); 303 int status = httpResponse.getStatusLine().getStatusCode(); 304 if (status == HttpStatus.SC_OK) { 305 String resp = EntityUtils.toString(httpResponse.getEntity(), 306 "utf-8"); 307 Log.v("KKHP", resp); 308 JSONObject jsonObject = new JSONObject(resp); 309 String statuscode = jsonObject.getString("status"); 310 String statusmsg = jsonObject.getString("message"); 311 int liret = Integer.parseInt(statuscode); 312 // 0:成功 313 switch(liret){ 314 case 0: 315 case 21: 316 return true; 317 default: 318 Log.e("Post", statusmsg); 319 } 320 } else { 321 httpPost.abort(); 322 } 323 } catch (Exception e) { 324 Log.e("Post", "网络异常,请检查网络后重试!"); 325 e.printStackTrace(); 326 } 327 return false; 328 } 329 330 public static boolean deletePoi() { 331 List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>(); 332 //http://api.map.baidu.com/geodata/v2/column/update 333 //phone must be set is_index_field = 1 334 list.add(new BasicNameValuePair("phone", MapApplication.phoneNumber)); 335 336 return postData(POST_TYPE_DELETE, list); 337 } 338 339 public static boolean createPoi(BDLocation location) { 340 //delete first 341 deletePoi(); 342 343 return postData(POST_TYPE_CREATE, getPostParams(location)); 344 } 345 346 private static List<BasicNameValuePair> getPostParams(BDLocation location) { 347 List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>(); 348 349 list.add(new BasicNameValuePair("latitude", String.valueOf(location 350 .getLatitude()))); 351 list.add(new BasicNameValuePair("longitude", String.valueOf(location 352 .getLongitude()))); 353 //if (location.hasAddr()) { 354 list.add(new BasicNameValuePair("address", location.getAddrStr())); 355 //} 356 list.add(new BasicNameValuePair("phone", MapApplication.phoneNumber)); 357 list.add(new BasicNameValuePair("locate_date", MyDatabase 358 .getCurrentTime())); 359 360 list.add(new BasicNameValuePair("title", MapApplication.title)); 361 list.add(new BasicNameValuePair("sex", MapApplication.sex)); 362 list.add(new BasicNameValuePair("head", "")); 363 list.add(new BasicNameValuePair("coord_type", coord_type)); 364 365 return list; 366 } 367 } 368
主要是两个函数,一个读request,一个写postdata(包括保存、更新和删除),其中读操作参考了网上一些资料,写操作网上找不到合用的资料,主要是自己硺磨出来的
为了调用方便,另外写了一些函数,这样调用就简单了,比如:LBSCloud.createPoi(location)就保存一个位置到网上数据表中去了,LBSCloud.searchNear(myPoint, mHandler)就查找附近的人了,mHandler里处理结果,如:
private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_NET_TIMEOUT: break; case MSG_NET_STATUS_ERROR: break; case MSG_NET_SUCC: if(msg.arg1==LBSCloud.RESULT_GET){ String result = msg.obj.toString(); try { JSONObject json = new JSONObject(result); parse(json); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } break; } } };
/* * 解析返回数据 */ private void parse(JSONObject json) { List<String> list = new ArrayList<String>(); try { int status = json.getInt("status"); Log.d("Status", ""+status); if(status!=0){ return; } //int total = json.getInt("total"); JSONArray jsonArray; try{ jsonArray = json.getJSONArray("pois"); }catch(JSONException e){ jsonArray = json.getJSONArray("contents"); } if (jsonArray != null && jsonArray.length() <= 0) { Toast.makeText(this, R.string.msg_search_near, Toast.LENGTH_SHORT).show(); } else { points.clear(); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObj = (JSONObject) jsonArray.opt(i); String phone, address; try{ phone = jsonObj.getString("phone"); }catch(JSONException e){ Log.e("get phone error", e.getMessage()); continue; } //same body just show one time! if(list.contains(phone)) continue; //need not show myself! if(phone.equals(MapApplication.phoneNumber)) continue; list.add(phone); try{ address = jsonObj.getString("address"); } catch(JSONException e){ address = jsonObj.getString("province") + jsonObj.getString("city") + jsonObj.getString("district"); } JSONArray locArray = jsonObj.getJSONArray("location"); double longitude = locArray.getDouble(0); double latitude = locArray.getDouble(1); LocationModel lm = new LocationModel(longitude, latitude); lm.setPhone(phone); lm.setAddr(address); lm.setSex(jsonObj.getString("sex")); lm.setHead(jsonObj.getString("head")); lm.setName(jsonObj.getString("title")); lm.setLocateDate(jsonObj.getString("locate_date")); lm.setUpload(true); points.add(lm); } addItemizedOverlay(); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
软件大概是这个样子:
这个 功能还在改进中,有时间将整理出整个软件设计思路来公诸同好!