内容简介:父母已经上了岁数,有时给他们手机打电话总是一直没人接听,搞得我很担心,怕出现意外。于是决定自己开发一款定位用APP为他们保驾护航。考虑到耗电问题,放弃GPS定位,研究了下基站定位技术,虽然定位精度不及GPS,但对于我的需求是足够的。基站定位一般应用于手机用户,手机基站定位服务又叫做移动位置服务(LBS——Location Based Service),它是通过电信移动运营商的网络(如GSM网)获取移动终端用户的位置信息(经纬度坐标)。
父母已经上了岁数,有时给他们手机打电话总是一直没人接听,搞得我很担心,怕出现意外。于是决定自己开发一款定位用APP为他们保驾护航。考虑到耗电问题,放弃GPS定位,研究了下基站定位技术,虽然定位精度不及GPS,但对于我的需求是足够的。
PS:本文仅用于技术讨论与分享,严禁用于任何非法用途。
一、基站定位简介
基站定位一般应用于手机用户,手机基站定位服务又叫做移动位置服务(LBS——Location Based Service),它是通过电信移动运营商的网络(如GSM网)获取移动终端用户的位置信息(经纬度坐标)。
基站定位的原理为:移动电话测量不同基站的下行导频信号,得到不同基站下行导频的TOA(Time of Arrival,到达时刻)或TDOA(Time Difference of Arrival,到达时间差),根据该测量结果并结合基站的坐标,一般采用三角公式估计算法,就能够计算出移动电话的位置。实际的位置估计算法需要考虑多基站(3个或3个以上)定位的情况,因此算法要复杂很多。一般而言,移动台测量的基站数目越多,测量精度越高,定位性能改善越明显。
二、开发思路
由于本次需求对定位精度要求不是特别高,就不采用多基点定位法了,本次采用单基点定位就可以了。单基点定位就是把与手机最新的基站认为手机的当前位置。
整个定位系统可以分为两部分:APP部分和离线电子地图。
下面我就详细说明每部分的功能。
1.APP详解。
APP以1分钟为周期捕获当前基站情报并存储在文件中,在一天结束的时候将当日的统计结果文件发送到指定邮箱中。
2,离线地图详解。
用户手动从邮箱中下载当日的定位文件,并手动导入到离线地图中,在地图中标记出当日的行走轨迹。
三、开发过程
APP篇
APP界面如下。
APP机能中简单的部分我就不介绍了,难点是如何获得基站信息。
本次需要获得这些基站情报:网络类型、移动国家码、移动网络码、系统识别码、网络识别码、基站识别码。
下面是获得基站信息的代码。
private String ReadCellInfo() { TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); // 返回值MCC + MNC (注意:电信的mnc 对应的是 sid) String operator = mTelephonyManager.getNetworkOperator(); if(operator!=null&&operator.length()==0){ return "手机无网络!"; } int mcc = -1; int mnc = -1; if(operator!=null&&operator.length()>3){ mcc = Integer.parseInt(operator.substring(0, 3)); mnc = Integer.parseInt(operator.substring(3)); } StringBuffer cellinfo = new StringBuffer(); //时间戳 Calendar calendar = Calendar.getInstance(); long unixTime = calendar.getTimeInMillis(); int year = calendar.get(Calendar.YEAR) ; int month = calendar.get(Calendar.MONTH)+1; int day = calendar.get(Calendar.DAY_OF_MONTH); int hour = calendar.get(Calendar.HOUR_OF_DAY); // 0-23 int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); String mytime =""; mytime = String.format("%d%02d%02d %02d:%02d:%02d",year,month,day,hour,minute,second); cellinfo.append(mytime).append(","); //NetworkType int type = mTelephonyManager.getNetworkType(); cellinfo.append(type +","); //需要判断网络类型,因为获取数据的方法不一样, if(type == TelephonyManager.NETWORK_TYPE_CDMA // 电信cdma网 || type == TelephonyManager.NETWORK_TYPE_1xRTT || type == TelephonyManager.NETWORK_TYPE_EVDO_0 || type == TelephonyManager.NETWORK_TYPE_EVDO_A || type == TelephonyManager.NETWORK_TYPE_EVDO_B || type == TelephonyManager.NETWORK_TYPE_LTE){ // TIME,TYPE,MCC,MNC,SID,NID,BID CdmaCellLocation cdma = (CdmaCellLocation) mTelephonyManager.getCellLocation(); if(cdma!=null){ //Mobile country code:移动国家码 sb.append("MCC = " + mcc +"\n"); cellinfo.append(mcc +","); // Mobile Network Code:移动网络码 sb.append("MNC = " + mnc +"\n" ); cellinfo.append(mnc +","); //System ID:系统识别码 int sid = cdma.getSystemId(); sb.append("SID = " + sid +"\n"); cellinfo.append(sid +","); // Network ID:网络识别码 int nid = cdma.getNetworkId(); sb.append("NID = " + nid +"\n"); cellinfo.append(nid +","); // Base Station ID:基站识别码 int bid = cdma.getBaseStationId(); sb.append("BID = " + bid +"\n"); cellinfo.append(bid +","); }else{ sb.append("can not get the CDMA CellLocation"); cellinfo.append("can not get the CDMA CellLocation"); } }else if(type == TelephonyManager.NETWORK_TYPE_UNKNOWN){ cellinfo.append("电话卡不可用!"); } String result = new String(cellinfo); return result; }
每一分钟采集一次,并将统计的信息按【采样时间,网络类型、移动国家码、移动网络码、系统识别码、网络识别码、基站识别码】格式输出到文件中,其中一行为一条情报。
以下为某日生成的部分文件内容。
20180806 12:31:07,13,460,11,13858,13,8691, 20180806 12:32:07,13,460,11,13858,13,8691, 20180806 12:33:10,13,460,11,13858,13,8691, 20180806 12:34:22,13,460,11,13858,13,8691, 20180806 12:35:40,13,460,11,13858,13,8691, 20180806 12:36:40,13,460,11,13858,13,8691, 20180806 12:37:40,13,460,11,13858,13,8691, 20180806 12:38:41,13,460,11,13858,13,8691, 20180806 12:39:41,13,460,11,13858,13,8691, 20180806 12:40:41,13,460,11,13858,13,8691, 20180806 12:41:41,13,460,11,13858,13,8691, 20180806 12:42:41,13,460,11,13858,13,8691, 20180806 12:43:41,13,460,11,13858,13,8691, 20180806 12:44:41,13,460,11,13858,13,8691, 20180806 12:45:41,13,460,11,13858,13,8691, 20180806 12:46:42,13,460,11,13858,13,9000, 20180806 12:47:42,13,460,11,13858,13,9000, 20180806 12:48:42,13,460,11,13858,13,9000, 20180806 12:49:42,13,460,11,13858,13,9000, 20180806 12:50:42,13,460,11,13858,13,9000, 20180806 12:51:43,13,460,11,13858,13,9000, 20180806 12:52:43,13,460,11,13858,13,9000, 20180806 12:53:43,13,460,11,13858,13,9000, 20180806 12:54:43,13,460,11,13858,13,9000, 20180806 12:55:43,13,460,11,13858,13,9000, 20180806 12:56:43,13,460,11,13858,13,9000, 20180806 12:57:43,13,460,11,13858,13,9000, 20180806 12:58:43,13,460,11,13858,13,9000, 20180806 12:59:43,13,460,11,13858,13,8488, 20180806 13:00:44,13,460,11,13858,13,8488, 20180806 13:01:44,13,460,11,13858,13,8488, 20180806 13:02:44,13,460,11,13858,13,8488,
离线地图篇
本次离线地图是基于百度地图API实现的地图描画。
离线地图最核心内容将基站情报转换为基站的经纬度经度,再通过百度地图API进行轨迹点描画。
有很多网站会提供API可以获得基站的经纬度信息,但大部分都是收费的,好不容易找到了一家稳定且免费的API。
—————接口说明如下 —————
查询全国移动联通电信2G/3G/4G基站位置数据,收录数据总量1.2亿条
接口地址: http://api.cellocation.com:81/cell/
支持格式: CSV/JSON/XML
请求方式: GET
请求示例: http://api.cellocation.com:81/cell/?mcc=460&mnc=1&lac=4301&ci=20986&output=xml
请求参数:
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
mcc | int | 是 | mcc国家代码:中国代码 460 |
mnc | int | 是 | mnc网络类型:0移动,1联通(电信对应sid),十进制 |
lac | int | 是 | lac(电信对应nid),十进制 |
ci | int | 是 | cellid(电信对应bid),十进制 |
coord | string | 否 | 坐标类型(wgs84/gcj02/bd09),默认wgs84 |
output | string | 否 | 返回格式(csv/json/xml),默认csv |
返回数据格式:CSV
errcode,纬度,经度,精度半径,地址
errcode
0: 成功
10000: 参数错误
10001: 无查询结果
示例:
0,39.999024,116.476159,222,”北京市朝阳区望京街道北京市望京实验学校(宝星分校);阜安路与宏泰东街路口西231米”
————— 接口说明如下 结束 —————
最后,离线地图描画的最终效果如下图所示。
四、结束语
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 基于3G模块的树莓派基站定位
- SeaGlass:手工搭建伪基站监控系统
- 建一个 5G 基站,到底要花多少钱?
- 技术讨论 | 自动化Web渗透Payload提取技术
- Eero分布式组网路由器推2代产品 包括基站和Beacon
- 技术讨论 | 如何编写一段内存蠕虫?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。