Android基站定位源代码

news/2025/2/22 22:37:29/

经过几天的调研以及测试,终于解决了联通2G、移动2G、电信3G的基站定位代码。团队里面只有这些机器的制式了。下面就由我来做一个详细的讲解吧。
1 相关技术内容
Google Android Api里面的TelephonyManager的管理。
联通、移动、电信不同制式在获取基站位置的代码区别。
通过基站的基本信息,通过Google Gears获取对应的GPS经纬度。
通过Google Map API根据GPS经纬度获取当前位置。

2 目前存在的几个问题
由于得到的GPS经纬度在Google Map上面显示需要偏移,这块暂时没有进行处理。
没有使用PhoneStateListener来对状态实时进行更新。
没有使用线程异步获取数据
没有使用服务的方式来实时获取数据
所以如果是商业使用的话,还需进一步修改。

3 当然本部分代码已经移植到我们的家庭卫士的项目中了,2提到的问题全部解决了。

下面我针对第一部分的四大内容进行代码注解。

1 Google Android Api里面的TelephonyManager的管理。

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 

通过这个方式就可以得到TelephonyManager接口。
这个接口的源代码可以通过设置在项目里面查看,这里不具体附上了。
得到TelephonyManager后,由于针对不同的运营商,代码有所不同,所以需要判断getNetworkType()
在源代码里面有如下的类型定义

    /** Network type is unknown */public static final int NETWORK_TYPE_UNKNOWN = 0;/** Current network is GPRS */public static final int NETWORK_TYPE_GPRS = 1;/** Current network is EDGE */public static final int NETWORK_TYPE_EDGE = 2;/** Current network is UMTS */public static final int NETWORK_TYPE_UMTS = 3;/** Current network is CDMA: Either IS95A or IS95B*/public static final int NETWORK_TYPE_CDMA = 4;/** Current network is EVDO revision 0*/public static final int NETWORK_TYPE_EVDO_0 = 5;/** Current network is EVDO revision A*/public static final int NETWORK_TYPE_EVDO_A = 6;/** Current network is 1xRTT*/public static final int NETWORK_TYPE_1xRTT = 7;/** Current network is HSDPA */public static final int NETWORK_TYPE_HSDPA = 8;/** Current network is HSUPA */public static final int NETWORK_TYPE_HSUPA = 9;/** Current network is HSPA */public static final int NETWORK_TYPE_HSPA = 10;

2 联通、移动、电信不同制式在获取基站位置的代码区别。

这部分是我实际测试出来的,经过无数次的拆机,放卡,才实现了不同制式的完美实现。
代码如下:

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
int type = tm.getNetworkType();
//中国电信为CTC
//NETWORK_TYPE_EVDO_A是中国电信3G的getNetworkType
//NETWORK_TYPE_CDMA电信2G是CDMA
if (type == TelephonyManager.NETWORK_TYPE_EVDO_A || type == TelephonyManager.NETWORK_TYPE_CDMA || type ==TelephonyManager.NETWORK_TYPE_1xRTT)
{
}
//移动2G卡 + CMCC + 2
//type = NETWORK_TYPE_EDGE
else if(type == TelephonyManager.NETWORK_TYPE_EDGE)
{
}
//联通的2G经过测试 China Unicom   1 NETWORK_TYPE_GPRS
else if(type == TelephonyManager.NETWORK_TYPE_GPRS)
{}
else
{
tv.setText("Current Not Support This Type.");
}

3 通过基站的基本信息,通过Google Gears获取对应的GPS经纬度。
这部分前面的两篇文章都有提到,代码参考了网友们的代码,感谢感谢。

private Location callGear(ArrayList cellID) {if (cellID == null) return null;DefaultHttpClient client = new DefaultHttpClient();HttpPost post = new HttpPost("http://www.google.com/loc/json");JSONObject holder = new JSONObject();try {holder.put("version", "1.1.0");holder.put("host", "maps.google.com");holder.put("home_mobile_country_code", cellID.get(0).mobileCountryCode);holder.put("home_mobile_network_code", cellID.get(0).mobileNetworkCode);holder.put("radio_type", cellID.get(0).radioType);holder.put("request_address", true);if ("460".equals(cellID.get(0).mobileCountryCode))holder.put("address_language", "zh_CN");elseholder.put("address_language", "en_US");JSONObject data,current_data;JSONArray array = new JSONArray();current_data = new JSONObject();current_data.put("cell_id", cellID.get(0).cellId);current_data.put("location_area_code", cellID.get(0).locationAreaCode);current_data.put("mobile_country_code", cellID.get(0).mobileCountryCode);current_data.put("mobile_network_code", cellID.get(0).mobileNetworkCode);current_data.put("age", 0);array.put(current_data);if (cellID.size() > 2) {for (int i = 1; i < cellID.size(); i++) {data = new JSONObject();data.put("cell_id", cellID.get(i).cellId);data.put("location_area_code", cellID.get(i).locationAreaCode);data.put("mobile_country_code", cellID.get(i).mobileCountryCode);data.put("mobile_network_code", cellID.get(i).mobileNetworkCode);data.put("age", 0);array.put(data);}}holder.put("cell_towers", array);StringEntity se = new StringEntity(holder.toString());Log.e("Location send", holder.toString());post.setEntity(se);HttpResponse resp = client.execute(post);HttpEntity entity = resp.getEntity();BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));StringBuffer sb = new StringBuffer();String result = br.readLine();while (result != null) {Log.e("Locaiton receive", result);sb.append(result);result = br.readLine();}if(sb.length()              return null;data = new JSONObject(sb.toString());data = (JSONObject) data.get("location");Location loc = new Location(LocationManager.NETWORK_PROVIDER);loc.setLatitude((Double) data.get("latitude"));loc.setLongitude((Double) data.get("longitude"));loc.setAccuracy(Float.parseFloat(data.get("accuracy").toString()));loc.setTime(GetUTCTime());return loc;} catch (JSONException e) {return null;} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}

4 通过Google Map API根据GPS经纬度获取当前位置。
本部分代码参考了 简单基站定位程序 ,感谢雷一兄这么好的文章。同时雷一兄的排版真的非常好看,清晰明了。

private String getLocation(Location itude) throws Exception {String resultString = "";/** 这里采用get方法,直接将参数加到URL上 */String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", itude.getLatitude(), itude.getLongitude());Log.i("URL", urlString);/** 新建HttpClient */HttpClient client = new DefaultHttpClient();/** 采用GET方法 */HttpGet get = new HttpGet(urlString);try {/** 发起GET请求并获得返回数据 */HttpResponse response = client.execute(get);HttpEntity entity = response.getEntity();BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent()));StringBuffer strBuff = new StringBuffer();String result = null;while ((result = buffReader.readLine()) != null) {strBuff.append(result);}resultString = strBuff.toString();/** 解析JSON数据,获得物理地址 */if (resultString != null && resultString.length() > 0) {JSONObject jsonobject = new JSONObject(resultString);JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString());resultString = "";for (int i = 0; i < jsonArray.length(); i++) {resultString = jsonArray.getJSONObject(i).getString("address");}}} catch (Exception e) {throw new Exception("获取物理位置出现错误:" + e.getMessage());} finally {get.abort();client = null;}return resultString;}


补充一下:
在AndroidMenifest.xml里面需要加上
android.permission.INTERNET、android.permission.ACCESS_COARSE_LOCATION、android.permission.READ_PHONE_STATE权限,否则会出错。
放在Application包前面。


http://www.ppmy.cn/news/205692.html

相关文章

使用Chat gpt提高Android开发效率

简介 在过去几周里&#xff0c;我进行了一项令人大开眼界的实验&#xff0c;将 Chat-GPT&#xff08;我使用的是 Bing Chat&#xff0c;它在后台使用了 GPT-4&#xff0c;并且可以免费使用&#xff09;融入到我的日常 Android 开发工作流程中&#xff0c;以探索它是否能够提高…

粉丝破千了,喊几个机器人跳个舞庆祝下

先看效果&#xff1a; 机器人跳舞 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>机器人跳舞</title><style>body, html {position: absolute;margin: 0;padding:…

MIT6.042学习笔记(一)——强归纳法,数论(1)

如果学生在学校里学习的结果是使自己什么也不会创造&#xff0c;那他的一生永远是模仿和抄袭。——列夫托尔斯泰 文章目录 引言强归纳法例题&#xff1a;拆积木游戏证明 数论&#xff08;第一节&#xff09;整除运算例题&#xff1a;取水证明 公约数例题证明 Eucild算法 引言 …

华为不提示连接计算机,求告知为什么现在华为用usb连电脑手机不显示

清野璇水 回答数&#xff1a;23107 | 被采纳数&#xff1a;3 2016-12-30 09:13:40 你好&#xff1a; 一&#xff0c;手机数据线连接电脑&#xff0c;手机上提示“主机无反应”&#xff0c;这是因为使用的是电脑连接出来的USB接口接线或者机箱前置的USB接口&#xff0c;试一试…

鸿蒙手机华为meta 30 第一次链接电脑下载驱动

第一步下载 华为手机助手HiSuite官方下载 | 华为官网 usb连接电脑后要手机要开启 USB调试模式&#xff0c;具体开启方式点击手机设置-》关于手机-》快速点击五次HarmonyOs版本 然后就进入了开发者模式 &#xff0c;点击返回-》系统和更新-》开发人员选项-》开启并开启usb调试 …

华为p20如何连接计算机,华为P20 USB调试和开发人员选项的打开方法(EMUI8.1)

华为P20打开USB调试和开发人员选项的方法要来分享一下了; 华为P20 USB调试模式和华为P20开发者选项这两个功能是我们平时经常要用到的&#xff0c;只要我们连接上电脑想操作一些东西时&#xff0c;打开这个功能必不可少&#xff0c;但是对于很多华为P20手机用户来说&#xff0c…

【已解决】华为手机USB调试和监控ADB安装应用的选项变成了灰色如何解决 | 华为荣耀9手机USB调试和监控ADB安装应用选项变成了灰色怎么办

华为手机USB调试和监控ADB安装应用的选项变成了灰色无法点击是由于开启了生产模式导致的&#xff0c;如果想恢复正常&#xff0c;则需要把生产模式调回Google模式&#xff08;如果调回Google模式之后还没有恢复&#xff0c;则有可能是驱动没有安装好&#xff0c;这时可以考虑把…

Android Studio连接华为手机

以下操作在华为P8、荣耀9和荣耀9i中试了&#xff0c;均可以。 1&#xff1a;准备 首先确认电脑是否安装了华为助手&#xff0c;如果安装了&#xff0c;必须卸载清理干净后再继续操作。 2&#xff1a;设置 打开SDK Manager&#xff1a; 在SDK Tools中选中USB驱动&#xff1a; …