一,首先普及一下手机基站信息中相关的专业词汇:
通过TelephonyManager 获取lac:mcc:mnc:cell-id(基站信息)的解释:
MCC,Mobile Country Code,移动国家代码(中国的为460);
MNC,Mobile Network Code,移动网络号码(中国移动为0,中国联通为1,中国电信为2);
LAC,Location Area Code,位置区域码;
CID,Cell Identity,基站编号;
BSSS,Base station signal strength,基站信号强度。
二,获取手机卡基站信息(前提需要有手机卡,模拟器无法实现):
/*** 获取手机基站信息* @throws JSONException */public void getGSMCellLocationInfo() throws JSONException{TelephonyManager manager = (TelephonyManager) mAppMain.getSystemService(Context.TELEPHONY_SERVICE);String operator = manager.getNetworkOperator();/**通过operator获取 MCC 和MNC */int mcc = Integer.parseInt(operator.substring(0, 3));int mnc = Integer.parseInt(operator.substring(3));GsmCellLocation location = (GsmCellLocation) manager.getCellLocation();/**通过GsmCellLocation获取中国移动和联通 LAC 和cellID */int lac = location.getLac();int cellid = location.getCid();/**通过CdmaCellLocation获取中国电信 LAC 和cellID */ /*CdmaCellLocation location1 = (CdmaCellLocation) mTelephonyManager.getCellLocation(); lac = location1.getNetworkId(); cellId = location1.getBaseStationId(); cellId /= 16;*/ int strength = 0;/**通过getNeighboringCellInfo获取BSSS */List<NeighboringCellInfo> infoLists = manager.getNeighboringCellInfo();System.out.println("infoLists:"+infoLists+"size:"+infoLists.size());for (NeighboringCellInfo info : infoLists) {strength+=(-133+2*info.getRssi());// 获取邻区基站信号强度 //info.getLac();// 取出当前邻区的LAC //info.getCid();// 取出当前邻区的CID System.out.println("rssi:"+info.getRssi()+" strength:"+strength);}//以下内容是把得到的信息组合成json体,然后发送给我的服务器,获取经纬度信息
//如果你没有服务器支持,可以发送给BaiduMap,GoogleMap等地图服务商,具体看定位相关的API格式要求JSONObject item = new JSONObject();item.put("cid", cellid);item.put("lac", lac);item.put("mnc", mnc);item.put("mcc", mcc);item.put("strength", strength);JSONArray cells = new JSONArray();cells.put(0, item);JSONObject json = new JSONObject();json.put("cells", cells);CellLocationTask task = new CellLocationTask(json);task.execute();}
三,通过基站信息,请求获取经纬度
CellLocationTask
/*** 异步请求,通过封装的手机基站信息json体* @author Administrator**/class CellLocationTask extends AsyncTask<String, Void, String>{private JSONObject mJson;private HttpClient mClient;private HttpResponse response;private String responseString;public CellLocationTask(JSONObject json) {this.mJson = json;}@Overrideprotected void onPreExecute() {super.onPreExecute();mClient = new DefaultHttpClient();mClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000);mClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 15000);}@Overrideprotected String doInBackground(String... params) {String url = "http://我的服务器地址";try {HttpPost post = new HttpPost(url);post.setEntity(new StringEntity(mJson.toString(), HTTP.UTF_8));post.addHeader("Content-Type", "application/json");response = mClient.execute(post);int statusCode = response.getStatusLine().getStatusCode();System.out.println("doinbackground:"+statusCode);if (statusCode == 200) {responseString = EntityUtils.toString(response.getEntity());System.out.println("返回结果:"+responseString);}} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return responseString;}@Overrideprotected void onPostExecute(String result) {super.onPostExecute(result);System.out.println("onPostExecute:"+result);JSONObject json;try {json = new JSONObject(result);JSONObject mresult = json.getJSONObject("result");JSONObject geo = mresult.getJSONObject("geo");double lat = geo.getDouble("lat");double lng = geo.getDouble("lng");mLocationGeoPoint = new GeoPoint((int)(lat*1E6), (int)(lng*1E6));CustomOverlay overlay = new CustomOverlay(mAppMain);mMapView.getOverlays().add(overlay);mMapController.animateTo(mLocationGeoPoint);} catch (JSONException e) {e.printStackTrace();}}}
四,地图显示当前位置
CustomOverlay
class CustomOverlay extends ItemizedOverlay<OverlayItem>{public CustomOverlay(Context context) throws NumberFormatException, JSONException {super(context.getResources().getDrawable(R.drawable.mylocation));populate();}
@Overrideprotected OverlayItem createItem(int arg0) {//mLocationGeoPoint为全局变量,CellLocationTask异步得到的经纬度OverlayItem overlayItem = new OverlayItem(mLocationGeoPoint,"", "");return overlayItem;}@Overridepublic int size() {return 1;}@Overridepublic boolean onTap(GeoPoint arg0, MapView arg1) {return super.onTap(arg0, arg1);}}
演示效果:
放到百度地图中,位置有些偏差,这个就需要纠偏了,因为通过基站信息请求到的位置数据并非是百度的数据。以上就是通过基站信息,进行基站定位的实现原理,就是通过MCC,MNC,LAC,CID等属性,请求位置数据,大致就是这个样子。