基站定位
因为公司的需要,在网上查基站定位,结果发现大部分都是无法实现的,不是代码有问题就是已经过期,只能自己研究,经过一天的努力,有了一些心得,首先基站定位需要这几个参数,不管你用的什么接口
lac //连接基站位置区域码
cellid //连接基站编码
mcc //MCC国家码
mnc //MNC网号
signalstrength//连接基站信号强度
然后在基站定位方面,有通过一个基站定位的,有通过几个基站定位的,一个基站定位就是通过查找这个基站的位置,然后将这个位置作为用户的位置,准确度不是很高,还有多基站定位,需要得到附近的所有基站数据和信号强度,通过一定的算法得到用户的位置,这个方法比单基站定位的准确度要高一些。我用的是多基站定位,下面介绍的也是这个方法。
在查资料时,看到聚合的官网有介绍关于获取基站数据的方法,网站如下,各位可以去看看
但是这个网站上面写的方法照着写的话会报错,经过查找,错误在这一行代码:
CellInfoCdma cellInfoCdma = (CellInfoCdma) info;
这个强制转换的方法是有问题,因为不同的手机返回的数据是不一样的,我去查了一下android的官方SDK
http://www.android-doc.com/reference/android/telephony/CellInfo.html
关于CellInfo对象的介绍,发现这个对象有四个子类,可以理解为代表不同基站的数据的类,分别是:
CellInfoCdma //电信3G的基站数据
CellInfoGsm //通用的移动联通电信2G的基站数据
CellInfoLte //4g网络的基站数据
CellInfoWcdma //联通3G的基站数据
我在网上查到移动的3G基站是scdma,但这个对象没有这个子类,原因不明。
到这一步已经可以知道正确的写法是怎么样的了,我直接列出我的代码:
/** 得到基站数据 */
@SuppressLint("NewApi")
public static void getBaseData(final Context mContext) {
// lac连接基站位置区域码 cellid连接基站编码 mcc MCC国家码 mnc MNC网号
// signalstrength连接基站信号强度
List<BaseDataBean> list = new ArrayList<BaseDataBean>();
BaseDataBean beans = new BaseDataBean();
TelephonyManager telephonyManager = (TelephonyManager) mContext
.getSystemService(Context.TELEPHONY_SERVICE);
String operator = telephonyManager.getNetworkOperator();
beans.setMcc(operator.substring(0, 3));
beans.setMnc(operator.substring(3));
if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {// 这是电信的
CdmaCellLocation cdmaCellLocation = (CdmaCellLocation) telephonyManager
.getCellLocation();
beans.setCell_id(cdmaCellLocation.getBaseStationId() + "");
beans.setLac(cdmaCellLocation.getNetworkId() + "");
} else {// 这是移动和联通的
GsmCellLocation gsmCellLocation = (GsmCellLocation) telephonyManager
.getCellLocation();
beans.setCell_id(gsmCellLocation.getCid() + "");
beans.setLac(gsmCellLocation.getLac() + "");
}
beans.setSignalstrength("0");
list.add(beans);
List<CellInfo> infoLists = telephonyManager.getAllCellInfo();
if (infoLists.size() != 0) {
for (CellInfo info : infoLists) {
/** 1、GSM是通用的移动联通电信2G的基站。
2、CDMA是3G的基站。
3、LTE,则证明支持4G的基站。*/
BaseDataBean bean = new BaseDataBean();
if (info.toString().contains("CellInfoLte")) {
CellInfoLte cellInfoLte = (CellInfoLte) info;
CellIdentityLte cellIdentityLte = cellInfoLte
.getCellIdentity();
CellSignalStrengthLte cellSignalStrengthLte = cellInfoLte
.getCellSignalStrength();
bean.setSignalstrength(cellSignalStrengthLte.getDbm() + "");
bean.setCell_id(cellIdentityLte.getCi() + "");
bean.setLac(cellIdentityLte.getTac() + "");
bean.setMcc(cellIdentityLte.getMcc() + "");
bean.setMnc(cellIdentityLte.getMnc() + "");
} else if (info.toString().contains("CellInfoGsm")) {
CellInfoGsm cellInfoGsm = (CellInfoGsm) info;
CellIdentityGsm cellIdentityGsm = cellInfoGsm
.getCellIdentity();
CellSignalStrengthGsm cellSignalStrengthGsm = cellInfoGsm
.getCellSignalStrength();
bean.setSignalstrength(cellSignalStrengthGsm.getDbm() + "");
bean.setCell_id(cellIdentityGsm.getCid() + "");
bean.setLac(cellIdentityGsm.getLac() + "");
bean.setMcc(cellIdentityGsm.getMcc() + "");
bean.setMnc(cellIdentityGsm.getMnc() + "");
} else if (info.toString().contains("CellInfoCdma")) {
CellInfoCdma cellInfoCdma = (CellInfoCdma) info;
CellIdentityCdma cellIdentityCdma = cellInfoCdma
.getCellIdentity();
CellSignalStrengthCdma cellSignalStrengthCdma = cellInfoCdma
.getCellSignalStrength();
bean.setCell_id(cellIdentityCdma.getBasestationId() + "");
bean.setSignalstrength(cellSignalStrengthCdma.getCdmaDbm()
+ "");
/**因为待会我要把这个list转成gson,所以这个对象的所有属性我都赋一下值,不必理会这里*/
bean.setLac("0");
bean.setMcc("0");
bean.setMnc("0");
}
list.add(bean);
}
}
/**到了这里这个list就是你得到的你附近的所有基站数据了。
现在可以调用你的通过基站数据定位的接口,我的接口是公司后台写给我的。*/
}
顺便把BaseDataBean这个bean也发出来吧
/**
* 基站数据
*/
public class BaseDataBean {
private String cell_id;// cellid连接基站编码
private String lac;// lac连接基站位置区域码
private String mcc;// mcc MCC国家码
private String mnc;// mnc MNC网号
private String signalstrength;// signalstrength连接基站信号强度
public String getCell_id() {
return cell_id;
}
public void setCell_id(String cell_id) {
this.cell_id = cell_id;
}
public String getLac() {
return lac;
}
public void setLac(String lac) {
this.lac = lac;
}
public String getMcc() {
return mcc;
}
public void setMcc(String mcc) {
this.mcc = mcc;
}
public String getMnc() {
return mnc;
}
public void setMnc(String mnc) {
this.mnc = mnc;
}
public String getSignalstrength() {
return signalstrength;
}
public void setSignalstrength(String signalstrength) {
this.signalstrength = signalstrength;
}
}
WIFI定位
同样的,wifi定位接口的话你们自己找,我的接口是公司后台提供的,wifi定位需要的数据如下
BSSID //wifi的Mac地址
level //wifi的强度,即信号的强弱
SSID //wifi的名字
获取的方法也很简单:
/** 得到Wifi数据 */
public static void getWifiData(final Context mContext) {
WifiManager wifiManager = (WifiManager) mContext
.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> list = wifiManager.getScanResults();
List<WifiDataBean> data = new ArrayList<WifiDataBean>();
for (int i = 0; i < list.size(); i++) {
WifiDataBean bean = new WifiDataBean();
bean.setMac_address(list.get(i).BSSID);
bean.setSignal_strength(list.get(i).level+"");
bean.setWifi_name(list.get(i).SSID);
data.add(bean);
}
/**到了这里这个data就是你得到的你附近的所有wifi数据了。*/
}
把WifiDataBean也发出来吧。
/**
* wifi数据
*/
public class WifiDataBean {
private String wifi_name;//wifi信息名字
private String mac_address;//wifi的MAC地址
private String signal_strength;//wifi信号强度
public String getWifi_name() {
return wifi_name;
}
public void setWifi_name(String wifi_name) {
this.wifi_name = wifi_name;
}
public String getMac_address() {
return mac_address;
}
public void setMac_address(String mac_address) {
this.mac_address = mac_address;
}
public String getSignal_strength() {
return signal_strength;
}
public void setSignal_strength(String signal_strength) {
this.signal_strength = signal_strength;
}
}
调用这俩个方法记得加以下权限(其实没这么多,但我懒得挑了):
<!-- 用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES" />
<!-- 用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 用于获取运营商信息,用于支持提供运营商信息相关的接口 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 用于访问网络,网络定位需要上网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 用于申请调用A-GPS模块 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
ps:我问了一下后台这俩个接口是哪找的,然后他表示这俩个接口都是收费的,所以咯,你们还是自己找吧。