在googleAPI里提供了基站信息的获取类TelephonyManager,通过其方法getCellLocation得到CellLocation即可获取到基站相关信息

但CellLocation是个抽象类,所以在具体使用时需要判断接入的网络制式来用其子类CdmaCellLocation或GsmCellLocation来强转

CdmaCellLocation对应CDMA网,GsmCellLocation对应GSM网

三大网络运营商的网络制式对应如下:

移动2G 网 --> GSM

移动3G 网 --> TD-SCDMA

电信2G 网 --> CDMA

电信3G 网 --> CDMA2000

联通2G 网 --> GSM

联通3G 网 --> WCDMA

由此可见移动,联通2G 网都可使用GsmCellLocation

电信2G,3G网则使用CdmaCellLocation

那么移动3G和联通3G又当如何

其实经本人亲测,移动3G网也可使用GsmCellLocation,听说是TD-SCDMA衍生于GSM,具体原因咱也不用纠结了,反正能用就是了

而联通的WCDMA据说也可使用GsmCellLocation,那姑且就是这样吧,有条件的童鞋试一试吧。

对于网络制式的判断调用TelephonyManager.getNetworkType()可有多种情况,如下:

  • NETWORK_TYPE_UNKNOWN
  • NETWORK_TYPE_GPRS
  • NETWORK_TYPE_EDGE
  • NETWORK_TYPE_UMTS
  • NETWORK_TYPE_HSDPA
  • NETWORK_TYPE_HSUPA
  • NETWORK_TYPE_HSPA
  • NETWORK_TYPE_CDMA
  • NETWORK_TYPE_EVDO_0
  • NETWORK_TYPE_EVDO_A
  • NETWORK_TYPE_EVDO_B
  • NETWORK_TYPE_1xRTT
  • NETWORK_TYPE_IDEN
  • NETWORK_TYPE_LTE
  • NETWORK_TYPE_EHRPD

通过对网络类型判断后获取对应基站信息代码片段如下:

[html] view plain copy
  1. publicstaticArrayList<CellIDInfo>getCellIDInfo(Contextcontext)throwsException{
  2. TelephonyManagermanager=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
  3. ArrayList<CellIDInfo>CellID=newArrayList<CellIDInfo>();
  4. CellIDInfocurrentCell=newCellIDInfo();
  5. inttype=manager.getNetworkType();
  6. Log.d(TAG,"getCellIDInfo-->NetworkType="+type);
  7. intphoneType=manager.getPhoneType();
  8. Log.d(TAG,"getCellIDInfo-->phoneType="+phoneType);
  9. if(type==TelephonyManager.NETWORK_TYPE_GPRS//GSM网
  10. ||type==TelephonyManager.NETWORK_TYPE_EDGE
  11. ||type==TelephonyManager.NETWORK_TYPE_HSDPA)
  12. {
  13. GsmCellLocationgsm=((GsmCellLocation)manager.getCellLocation());
  14. if(gsm==null)
  15. {
  16. Log.e(TAG,"GsmCellLocationisnull!!!");
  17. returnnull;
  18. }
  19. intlac=gsm.getLac();
  20. Stringmcc=manager.getNetworkOperator().substring(0,3);
  21. Stringmnc=manager.getNetworkOperator().substring(3,5);
  22. intcid=gsm.getCid();
  23. currentCell.cellId=gsm.getCid();
  24. currentCell.mobileCountryCode=mcc;
  25. currentCell.mobileNetworkCode=mnc;
  26. currentCell.locationAreaCode=lac;
  27. currentCell.radioType="gsm";
  28. CellID.add(currentCell);
  29. //获得邻近基站信息
  30. List<NeighboringCellInfo>list=manager.getNeighboringCellInfo();
  31. intsize=list.size();
  32. for(inti=0;i<size;i++){
  33. CellIDInfoinfo=newCellIDInfo();
  34. info.cellId=list.get(i).getCid();
  35. info.mobileCountryCode=mcc;
  36. info.mobileNetworkCode=mnc;
  37. info.locationAreaCode=lac;
  38. CellID.add(info);
  39. }
  40. }elseif(type==TelephonyManager.NETWORK_TYPE_CDMA//电信cdma网
  41. ||type==TelephonyManager.NETWORK_TYPE_1xRTT
  42. ||type==TelephonyManager.NETWORK_TYPE_EVDO_0
  43. ||type==TelephonyManager.NETWORK_TYPE_EVDO_A)
  44. {
  45. CdmaCellLocationcdma=(CdmaCellLocation)manager.getCellLocation();
  46. if(cdma==null)
  47. {
  48. Log.e(TAG,"CdmaCellLocationisnull!!!");
  49. returnnull;
  50. }
  51. intlac=cdma.getNetworkId();
  52. Stringmcc=manager.getNetworkOperator().substring(0,3);
  53. Stringmnc=String.valueOf(cdma.getSystemId());
  54. intcid=cdma.getBaseStationId();
  55. currentCell.cellId=cid;
  56. currentCell.mobileCountryCode=mcc;
  57. currentCell.mobileNetworkCode=mnc;
  58. currentCell.locationAreaCode=lac;
  59. currentCell.radioType="cdma";
  60. CellID.add(currentCell);
  61. //获得邻近基站信息
  62. List<NeighboringCellInfo>list=manager.getNeighboringCellInfo();
  63. intsize=list.size();
  64. for(inti=0;i<size;i++){
  65. CellIDInfoinfo=newCellIDInfo();
  66. info.cellId=list.get(i).getCid();
  67. info.mobileCountryCode=mcc;
  68. info.mobileNetworkCode=mnc;
  69. info.locationAreaCode=lac;
  70. CellID.add(info);
  71. }
  72. }
  73. returnCellID;
  74. }


从GOOGLE的API文档里总共有14钟网络类型,这里只罗列了其中7种,其他的主要是本人也不太清楚其对应到的网络制式是怎样的

所以部分童鞋的SIM卡网络制式不在这7种之内,自己根据实际情况看看它是归类于GSM还是CDMA在添进去就可以了


网络上多数教程是讲GSM网获取基站的,而忽略了C网的基站
这里我们可以比较一下GSM 和 CDMA 在获取基站信息时的不同之处



GSM:

int lac = gsm.getLac();
String mcc = manager.getNetworkOperator().substring(0, 3);
String mnc = manager.getNetworkOperator().substring(3, 5);
int cid = gsm.getCid();



CDMA:

int lac = cdma.getNetworkId();
String mcc = manager.getNetworkOperator().substring(0, 3);
String mnc = String.valueOf(cdma.getSystemId());
int cid = cdma.getBaseStationId();



在获取区域码LAC时GSM使用的是GsmCellLocation.getLac(),CDMA则用CdmaCellLocation.getNetworkId()来代替

在获取基站ID时GSM使用的是GsmCellLocation.getCid(),CDMA则用CdmaCellLocation.getBaseStationId()来代替





前面获取到的都是单个基站的信息,后面再获取周围邻近基站信息以辅助通过基站定位的精准性

TelephonyManager.getNeighboringCellInfo(),将其也放入基站信息LIST表中





最后通过google提供的gear接口获取经纬度,代码如下:

[html] view plain copy
  1. publicstaticLocationcallGear(List<CellIDInfo>cellID){
  2. if(cellID==null||cellID.size()==0)
  3. returnnull;
  4. DefaultHttpClientclient=newDefaultHttpClient();
  5. HttpPostpost=newHttpPost("http://www.google.com/loc/json");
  6. JSONObjectholder=newJSONObject();
  7. try{
  8. holder.put("version","1.1.0");
  9. holder.put("host","maps.google.com");
  10. holder.put("home_mobile_country_code",cellID.get(0).mobileCountryCode);
  11. holder.put("home_mobile_network_code",cellID.get(0).mobileNetworkCode);
  12. holder.put("radio_type",cellID.get(0).radioType);
  13. holder.put("request_address",true);
  14. if("460".equals(cellID.get(0).mobileCountryCode))
  15. holder.put("address_language","zh_CN");
  16. else
  17. holder.put("address_language","en_US");
  18. JSONObjectdata,current_data;
  19. JSONArrayarray=newJSONArray();
  20. current_data=newJSONObject();
  21. current_data.put("cell_id",cellID.get(0).cellId);
  22. current_data.put("location_area_code",cellID.get(0).locationAreaCode);
  23. current_data.put("mobile_country_code",cellID.get(0).mobileCountryCode);
  24. current_data.put("mobile_network_code",cellID.get(0).mobileNetworkCode);
  25. current_data.put("age",0);
  26. current_data.put("signal_strength",-60);
  27. current_data.put("timing_advance",5555);
  28. array.put(current_data);
  29. if(cellID.size()>2){
  30. for(inti=1;i<cellID.size();i++){
  31. data=newJSONObject();
  32. data.put("cell_id",cellID.get(i).cellId);
  33. data.put("location_area_code",cellID.get(i).locationAreaCode);
  34. data.put("mobile_country_code",cellID.get(i).mobileCountryCode);
  35. data.put("mobile_network_code",cellID.get(i).mobileNetworkCode);
  36. data.put("age",0);
  37. array.put(data);
  38. }
  39. }
  40. holder.put("cell_towers",array);
  41. StringEntityse=newStringEntity(holder.toString());
  42. Log.e("Locationsend",holder.toString());
  43. post.setEntity(se);
  44. HttpResponseresp=client.execute(post);
  45. HttpEntityentity=resp.getEntity();
  46. BufferedReaderbr=newBufferedReader(
  47. newInputStreamReader(entity.getContent()));
  48. StringBuffersb=newStringBuffer();
  49. Stringresult=br.readLine();
  50. while(result!=null){
  51. Log.e("Locaitonreseive-->",result);
  52. sb.append(result);
  53. result=br.readLine();
  54. }
  55. data=newJSONObject(sb.toString());
  56. data=(JSONObject)data.get("location");
  57. Locationloc=newLocation(LocationManager.NETWORK_PROVIDER);
  58. loc.setLatitude((Double)data.get("latitude"));
  59. loc.setLongitude((Double)data.get("longitude"));
  60. loc.setAccuracy(Float.parseFloat(data.get("accuracy").toString()));
  61. loc.setTime(System.currentTimeMillis());//AppUtil.getUTCTime());
  62. returnloc;
  63. }catch(JSONExceptione){
  64. e.printStackTrace();
  65. returnnull;
  66. }catch(UnsupportedEncodingExceptione){
  67. e.printStackTrace();
  68. }catch(ClientProtocolExceptione){
  69. e.printStackTrace();
  70. }catch(IOExceptione){
  71. e.printStackTrace();
  72. }
  73. returnnull;
  74. }


大家注意看这行holder.put("radio_type", cellID.get(0).radioType);

GSM就用"gsm",CDMA就用"cdma"

这个千万别搞混了,不然就获取不到信息了

值得一提的是C网获取基站再定位那偏差不是一般的大,是恨大,将近1千米了,大概是C网基站较少的缘故吧

最后通过经纬度获取地理位置信息,代码如下:

[java] view plain copy
  1. publicstaticStringgetAddress(Locationitude)throwsException{
  2. StringresultString="";
  3. /**这里采用get方法,直接将参数加到URL上*/
  4. StringurlString=String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s",itude.getLatitude(),itude.getLongitude());
  5. Log.i("URL",urlString);
  6. /**新建HttpClient*/
  7. HttpClientclient=newDefaultHttpClient();
  8. /**采用GET方法*/
  9. HttpGetget=newHttpGet(urlString);
  10. try{
  11. /**发起GET请求并获得返回数据*/
  12. HttpResponseresponse=client.execute(get);
  13. HttpEntityentity=response.getEntity();
  14. BufferedReaderbuffReader=newBufferedReader(newInputStreamReader(entity.getContent()));
  15. StringBufferstrBuff=newStringBuffer();
  16. Stringresult=null;
  17. while((result=buffReader.readLine())!=null){
  18. strBuff.append(result);
  19. }
  20. resultString=strBuff.toString();
  21. Log.e("resultAdress--->",resultString);
  22. /**解析JSON数据,获得物理地址*/
  23. if(resultString!=null&&resultString.length()>0){
  24. JSONObjectjsonobject=newJSONObject(resultString);
  25. JSONArrayjsonArray=newJSONArray(jsonobject.get("Placemark").toString());
  26. resultString="";
  27. for(inti=0;i<jsonArray.length();i++){
  28. resultString=jsonArray.getJSONObject(i).getString("address");
  29. }
  30. }
  31. }catch(Exceptione){
  32. thrownewException("获取物理位置出现错误:"+e.getMessage());
  33. }finally{
  34. get.abort();
  35. client=null;
  36. }
  37. returnresultString;
  38. }

在获取地理位置的这个location事实上应该传入纠偏后的location,本文暂不做此处理,所以得到的地理信息位置是偶偏差的,大家注意

最后附上截图:

http://download.csdn.net/detail/geniuseoe2012/4340303

我的话费充值店-各种面额

电信100元仅售98.60
联通100仅售99.00
移动100仅售99.30

更多相关文章

  1. Android在任意位置获取应用程序Context
  2. 获得手机相关信息的实现方法
  3. 分享一个 Android(安卓)全局获取 Context 的类(无需配置 Applicat
  4. Android代码混淆与加固技术一
  5. Unity Android(安卓)Usb 通信
  6. Android网络数据JSON解析使用总结
  7. Android(安卓)log analysis
  8. Android如何在初始化的时候获取加载的布局的宽高
  9. 【Android源码】Intent 源码分析

随机推荐

  1. Android中的Broadcast Action大全
  2. android 和 java 调色板
  3. Testing和Instrumentation
  4. Android 3.0细节曝光:Google程序更耀眼
  5. OpenGL学习资料和记录
  6. Android Support 包:Android Support v4、
  7. Android文件系统的提取方法(一)
  8. 最常见的猜拳小游戏Android代码实现
  9. Android水波纹点击效果
  10. Android(安卓)Shape自定义纯色圆角按钮