概述:
本篇主要介绍Android获取基站信息的方式,除此之外,还有SIM卡相关字段获取,先介绍一些缩写的概念,后续更新代码的写法。
前言:之前有碰到一个需求,需要获取SIM卡的相关属性:IMSI号、SIM卡序号、通话号码、SIM运营商国家代码、运营商名称、网络运营商等参数,然后是基站信息:mcc#mnc#lac#cellid#rss。也按照网上的方法踩过一些坑,这边就记录一下自己可行的方案。
基站信息的缩写概念:
LAC:Location Area Code,定位区域编码,2个字节长的十六进制BCD码(不包括0000和FFFE)
TAC:Tracking Area Code,追踪区域编码,
CID:Cell Identity,信元标识,2个字节
MCC:Mobile Country Code,移动国家代码,三位数,中国:460
MNC:Mobile Network Code,移动网络号,两位数(中国移动0,中国联通1,中国电信2)
BSSS:Base station signal strength,基站信号强度
网络类型:
1)NETOWRK_TYPE_GPRS 1-移动联通 2.5G
2)NETOWRK_TYPE_EDGE 2-移动 2.75G
3)NETOWRK_TYPE_UMTS 3-联通 WCDMA 46006
UMTS定义是一种3G移动电话技术,使用WCDMA作为底层标准,WCDMA向下兼容GSM网络。
4)NETOWRK_TYPE_CDMA 4-电信
5)NETOWRK_TYPE_1xRTT 7-电信
6)NETOWRK_TYPE_EVD0_0、NETOWRK_TYPE_EVD0_A、NETOWRK_TYPE_EVD0_B
5-6-12 - 电信
7)NETOWRK_TYPE_HSDPA 8-联通 46006 3.5G
8)NETOWRK_TYPE_LTE 13-移动、联通、电信 —— 4G 各个运营商都可能使用。
9)NETOWRK_TYPE_GSM 16
10)NETOWRK_TYPE_TD_SCDMA 17-移动 3G 的时候 使用
运营商代码460开头的整理:
46000 中国移动 (GSM)
46001 中国联通 (GSM)
46002 中国移动 (TD-S)
46003 中国电信(CDMA)
46004 空(似乎是专门用来做测试的)
46005 中国电信 (CDMA)
46006 中国联通 (WCDMA)
46007 中国移动 (TD-S)
46008
46009
46010
46011 中国电信 (FDD-LTE)
LTE CDMA GSM WCDMA
手机网络设置里面有个优先网络,里面有中国移动46000,46002,41004,是什么意思,有什么功能?
答案:46000,46002,41004是移动网络的ID号(PLMN标识),它们所支持的接入技术分别为:
46000是中国移动GSM网络的标识号(PLMN标识),所支持的接入技术为 GSM/TD-SCDMA。
46001是中国联通GSM网络的标识号(PLMN标识),所支持的接入技术为 GSM。
46002 是中国移动134/159的SIM卡的PLMN标识,所支持的接入技术为 GSM/TD-SCDMA。
46007是中国移动TD-SCDMA网的PLMN标识,所支持的接入技术为 TD-SCDMA。
41004是中国移动香港的PLMN标识
说明:
IMSI由三部分组成:
移动国家号码MCC: 由3个数字组成,唯一地识别移动用户所属的国家.中国为460.
移动网号MNC: 识别移动用户所归属的移动网.
移动用户识别码MSIN: 唯一地识别国内数字蜂窝移动通信网中的移动用户.
SIM卡信息(示例是一张电信卡信息):
(呃…基站信息的日志没拿到,尴尬,下次补上)
sim info[
simValue = -----,//这个字段客户自己订制还没给我,暂且为空
imsi = 460110421969346,
serialNumber = 89860315007690441866,
lineNumber = ,//现在手机号码不一定会存在SIM卡中,有的是在通信过程中才能拿到
countryIso = cn,
operatorName = 中国电信,
networkOperatorName = CHN-CT,
networkCountryIso = cn
先介绍几个简单的SIM卡属性字段获取方式,包括:
IMSI、SimSerialNumber、Line1Number、NetworkCountryIso、SimOperatorName、NetworkOperatorName、NetworkCountryIso
public static String getImsi(Context context, String imsi) {
String ret = null;
try {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
ret = telephonyManager.getSubscriberId();
} catch (Exception e) {
LoggerUtils.e("---------" + e.getMessage());
}
if (!TextUtils.isEmpty(ret)){
return ret;
} else {
return imsi;
}
}
先拿到系统服务,然后取到Context.TELEPHONY_SERVICE,然后通过telephonyManager取到相关属性。
这部分介绍基站信息的获取
拿到所有的基站信息List<CellInfo>,遍历之后,每一项分别判断实例比如info instanceof CellInfoCdma,然后分别拿到基站信息单位的各条属性。代码不难,只是要看过知道怎么玩就OK。
//获取基站信息
public static List<String> getTowerInfo(Context context) {
int mcc = -1;
int mnc = -1;
int lac = -1;
int cellId = -1;
int rssi = -1;
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String operator = tm.getNetworkOperator();
mcc = Integer.parseInt(operator.substring(0, 3));
List<String> list = new ArrayList<String>();
List<CellInfo> infos = tm.getAllCellInfo();
for (CellInfo info : infos){
if (info instanceof CellInfoCdma){
CellInfoCdma cellInfoCdma = (CellInfoCdma) info;
CellIdentityCdma cellIdentityCdma = cellInfoCdma.getCellIdentity();
mnc = cellIdentityCdma.getSystemId();
lac = cellIdentityCdma.getNetworkId();
cellId = cellIdentityCdma.getBasestationId();
CellSignalStrengthCdma cellSignalStrengthCdma = cellInfoCdma.getCellSignalStrength();
rssi = cellSignalStrengthCdma.getCdmaDbm();
}else if (info instanceof CellInfoGsm){
CellInfoGsm cellInfoGsm = (CellInfoGsm) info;
CellIdentityGsm cellIdentityGsm = cellInfoGsm.getCellIdentity();
mnc = cellIdentityGsm.getMnc();
lac = cellIdentityGsm.getLac();
cellId = cellIdentityGsm.getCid();
CellSignalStrengthGsm cellSignalStrengthGsm = cellInfoGsm.getCellSignalStrength();
rssi = cellSignalStrengthGsm.getDbm();
}else if (info instanceof CellInfoLte){
CellInfoLte cellInfoLte = (CellInfoLte) info;
CellIdentityLte cellIdentityLte = cellInfoLte.getCellIdentity();
mnc = cellIdentityLte.getMnc();
lac = cellIdentityLte.getTac();
cellId = cellIdentityLte.getCi();
CellSignalStrengthLte cellSignalStrengthLte = cellInfoLte.getCellSignalStrength();
rssi = cellSignalStrengthLte.getDbm();
}else if (info instanceof CellInfoWcdma){
CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) info;
CellIdentityWcdma cellIdentityWcdma = null;
CellSignalStrengthWcdma cellSignalStrengthWcdma = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
cellIdentityWcdma = cellInfoWcdma.getCellIdentity();
mnc = cellIdentityWcdma.getMnc();
lac = cellIdentityWcdma.getLac();
cellId = cellIdentityWcdma.getCid();
cellSignalStrengthWcdma = cellInfoWcdma.getCellSignalStrength();
rssi = cellSignalStrengthWcdma.getDbm();
}
}else {
LoggerUtils.e("get CellInfo error");
return null;
}
String tower = String.valueOf(mcc) + "#" + String.valueOf(mnc) + "#" + String.valueOf(lac)
+ "#" + String.valueOf(cellId) + "#" + String.valueOf(rssi);
list.add(tower);
}
if (list.size() > 6){
list = list.subList(0, 5);
}else if (list.size() < 3){
int need = 3 - list.size();
for (int i = 0; i < need; i++) {
list.add("");
}
}
return list;
}
虽然代码不难,但是之前由于网上的方法实在是……不太好用,不知道是方法老了还是什么原因。不过东扯西扯,算是这个方法最好用了,也比较全面。