一,首先普及一下手机基站信息中相关的专业词汇:

 通过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;
			
		}
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mClient = new DefaultHttpClient();
			mClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000);
			mClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 15000);
		}
		
		
		@Override
		protected 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;
		}
		
		@Override
		protected 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();
		}
		@Override
		protected OverlayItem createItem(int arg0) {
			//mLocationGeoPoint为全局变量,CellLocationTask异步得到的经纬度
			OverlayItem overlayItem = new OverlayItem(mLocationGeoPoint,
					"", "");
			return overlayItem;
		}

		@Override
		public int size() {
			return 1;
		}
		@Override
		public boolean onTap(GeoPoint arg0, MapView arg1) {
			return super.onTap(arg0, arg1);
		}
		
	}


演示效果:


放到百度地图中,位置有些偏差,这个就需要纠偏了,因为通过基站信息请求到的位置数据并非是百度的数据。以上就是通过基站信息,进行基站定位的实现原理,就是通过MCC,MNC,LAC,CID等属性,请求位置数据,大致就是这个样子。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐