1 存储在SIM卡中的mcc/mnc
这个值是存储在SIM卡IMSI(国际移动用户识别码 International Mobile Subscriber Identification Number)中的固定值,不会被更改。有以下两种途径可以取得。
11 通过TelephonyManager获得
在TelephonyManager中有如下方法:
//TelephonyManagerjava
/
Returns the MCC+MNC (mobile country code + mobile network code) of the
provider of the SIM for a particular subscription 5 or 6 decimal digits
Availability: SIM state must be {@link #SIM_STATE_READY}
@see #getSimState
@param subId for which SimOperator is returned
@hide
/
public String getSimOperatorNumeric(int subId) {
int phoneId = SubscriptionManagergetPhoneId(subId);
return getSimOperatorNumericForPhone(phoneId);
}
/
Returns the MCC+MNC (mobile country code + mobile network code) of the
provider of the SIM for a particular subscription 5 or 6 decimal digits
@param phoneId for which SimOperator is returned
@hide
/
public String getSimOperatorNumericForPhone(int phoneId) {
return getTelephonyProperty(phoneId,
TelephonyPropertiesPROPERTY_ICC_OPERATOR_NUMERIC, "");
}
↓↓↓
由于subId并不固定,是根据放进sim卡槽时候的计数来统计的,但是如果相关类中有SubscriptionInfo对象的话,是可以直接取到的:
int subId = mSubscriptionInfogetSubscriptionId();
另一种phoneId则比较简单了,它与sim卡数量有关,单卡时为0,双卡时根据sim slot位置分别取0和1。
12 通过SubscriptionInfo获得
在有些特殊情况下,比如SIM卡处于PIN码LOCK状态时,11所提到的方法是取不到的,这个时候只能通过SubscriptionInfo来取。
// SubscriptionInfojava
/
@return the MCC
/
public int getMcc() {
return thismMcc;
}
/
@return the MNC
/
public int getMnc() {
return thismMnc;
}
注意,由于这个方法取到的mcc/mnc均为int值,比如中国联通的“46001”,则有mcc为“460”,mnc为“1”,与固定String字符串进行匹配比对的话,需要先将String拆分为两部分后分别强转成int型后才可进行比对。
2 SIM卡注册网络的mcc/mnc
非漫游情况下,注册网络的mcc/mnc就是SIM卡中存储的。但是如果你的SIM卡在其他国家并没有该运营商的基站,只能通过漫游到其他运营商的网络上维持服务时,注册网络的mcc/mnc对应的就是该运营商的值,与SIM卡无关了。
21 通过ServiceState获得
熟悉Android Telephony流程的朋友应该都知道,CS、PS域的注册状态,漫游状态,运营商名字的显示,网络模式等都是用模板类ServiceStatejava来保存的。
SystemUI中有不少类都注册了PhoneStateListener这个callback,用来时刻关注设备的一些telephony相关状态,当网络服务状态有变化时,会回调其onServiceStateChanged(ServiceState serviceState)方法,这样我们就可以直接从ServiceState里面取了。
// ServiceStatejava
/
Get current registered operator numeric id
In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
network code
@return numeric format of operator, null if unregistered or unknown
/
/
The country code can be decoded using
{@link comandroidinternaltelephonyMccTable#countryCodeForMcc(int)}
/
public String getOperatorNumeric() {
return mVoiceOperatorNumeric;
}
/
Get current registered voice network operator numeric id
@return numeric format of operator, null if unregistered or unknown
@hide
/
public String getVoiceOperatorNumeric() {
return mVoiceOperatorNumeric;
}
/
Get current registered data network operator numeric id
@return numeric format of operator, null if unregistered or unknown
@hide
/
public String getDataOperatorNumeric() {
return mDataOperatorNumeric;
}
一般来说,voice语音业务和data数据业务对应的OperatorNumeric是一样的,所以getOperatorNumeric()默认取了voice的。
22 通过监听Telephony广播获得
由于该Intent action为MTK新增的,故以下方法介绍均以MTK源码为基础。
上面的方法必须在voice与data均注册成功的前提下才能获得,但是在一些很特殊的环境下,比如SIM卡虽然漫游上了某个其他运营商的网络,但由于两家运营商之间并没有协议,导致无法注册上服务,此时voice和data取得的OperatorNumeric均为空的。
在MTK源码中,MtkServiceStateTracker在处理PLMN String即mcc/mnc时,会通过action为“TelephonyIntentsACTION_LOCATED_PLMN_CHANGED”的广播,把它作为extra参数传递出去。
// MtkServiceStateTrackerjava
private void updateLocatedPlmn(String plmn) {
if (((mLocatedPlmn == null) && (plmn != null)) ||
((mLocatedPlmn != null) && (plmn == null)) ||
((mLocatedPlmn != null) && (plmn != null) && !(mLocatedPlmnequals(plmn)))) {
log("updateLocatedPlmn(),previous plmn= " + mLocatedPlmn + " ,update to: " + plmn);
Intent intent = new Intent(TelephonyIntentsACTION_LOCATED_PLMN_CHANGED);
if (TelephonyManagergetDefault()getPhoneCount() == 1) {
intentaddFlags(IntentFLAG_RECEIVER_REPLACE_PENDING);
}
intentputExtra(TelephonyIntentsEXTRA_PLMN, plmn);
mPhonegetContext()sendStickyBroadcastAsUser(intent, UserHandleALL);
}
mLocatedPlmn = plmn;
}
由此可知,只要在需要取的类中,注册一个监听“ACTION_LOCATED_PLMN_CHANGED”的BroadcastReceiver就行了,在设备开机之后便可以第一时间拿到漫游网络的mcc/mnc值,具体如下:
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intentgetAction();
if (actionequals(TelephonyIntentsACTION_LOCATED_PLMN_CHANGED)) {
mLocatedPlmn = intentgetStringExtra(TelephonyIntentsEXTRA_PLMN);
// mLocatedPlmn即为漫游网络的mcc/mnc值,接下来用它 *** 作即可
目前Android上提供了一个API可以读取早期SIM卡上固化的号码
private String getPhoneNumber(){
TelephonyManager mTelephonyMgr;
mTelephonyMgr = (TelephonyManager)
getSystemService(ContextTELEPHONY_SERVICE);
return
mTelephonyMgrgetLine1Number();
}
上面的getPhoneNumber方法返回当前手机的电话号码,同时必须在androidmanifestxml中加入
androidpermissionREAD_PHONE_STATE
这个权限,但是Android123提示大家上面的方法只能获取很老SIM卡的手机号码,目前主流的获取用户手机号码一般采用用户主动发送短信到SP或接收手机来获取。
android 获取sim卡运营商信息
TelephonyManager tm = (TelephonyManager)ContextgetSystemService(ContextTELEPHONY_SERVICE); TelephonyManager 的使用 TelephonyManager 提供设备上获取通讯服务信息的入口,应用程序使用这个类的方法来获取电话的服务商或者状态。程序也可以注册一个监听器来监听电话状态的改变。 不需要直接实例化这个类,使用ContextgetSystemService(ContextTELEPHONY_SERVICE)来获取这个类的实例。
注意:一些电话信息需要相应的权限。 方法无效
getSimOperatorName() Returns the Service Provider Name (SPN) // 获取服务提供商名字,比如电信,联通,移动 用下面的方法 第一种方法: 获取手机的IMSI码,并判断是中国移动/中国联通/中国电信
TelephonyManager telManager = (TelephonyManager) getSystemService(ContextTELEPHONY_SERVICE);
/ 获取SIM卡的IMSI码 SIM卡唯一标识:IMSI 国际移动用户识别码(IMSI:International Mobile Subscriber Identification Number)是区别移动用户的标志, 储存在SIM卡中,可用于区别移动用户的有效信息。
IMSI由MCC、MNC、MSIN组成,其中MCC为移动国家号码,由3位数字组成, 唯一地识别移动客户所属的国家,我国为460;MNC为网络id,由2位数字组成, 用于识别移动客户所归属的移动网络,中国移动为00,中国联通为01,中国电信为03;
MSIN为移动客户识别码,采用等长11位数字构成。
唯一地识别国内GSM移动通信网中移动客户。所以要区分是移动还是联通,只需取得SIM卡中的MNC字段即可 /
String imsi = telManagergetSubscriberId();
if(imsi!=null){ if(imsistartsWith(“46000″) || imsistartsWith(“46002″))
{//因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号 //中国移动
}else if(imsistartsWith(“46001″)){
//中国联通
}else if(imsistartsWith(“46003″)){
//中国电信
} }
第二种方法 TelephonyManager telManager = (TelephonyManager) getSystemService(ContextTELEPHONY_SERVICE); String operator = telManagergetSimOperator();
if(operator!=null){ if(operatorequals(“46000″) || operatorequals(“46002″)|| operatorequals(“46007″)){
//中国移动
}else if(operatorequals(“46001″)){
//中国联通
}else if(operatorequals(“46003″)){
//中国电信
} }
在文件AndroidManifestxml中添加权限 其他方法具体使用方法请查看API 文档TelephonyManager中方法说明。
在文件 AndroidManifestxml 中添加权限 <uses-permission android:name="androidpermissionREAD_PHONE_STATE"/>
TelephonyManager tel = (TelephonyManager) context getSystemService(ContextTELEPHONY_SERVICE);
String simOperator = telgetSimOperator();
IMSI共有15位,其结构如下: MCC+MNC+MIN MCC:Mobile Country Code,移动国家码,共3位,中国为460; MNC:Mobile Network Code,移动网络码,共2位,电信03,移动02,联通GSM 01,一个典型的IMSI号码为460030912121001; MIN共有10位,其结构如下: 09+M0M1M2M3+ABCD 其中的M0M1M2M3和MDN号码中的H0H1H2H3可存在对应关系,ABCD四位为自由分配。 可以看出IMSI在MIN号码前加了MCC,可以区别出每个用户的来自的国家,因此可以实现国际漫游。在同一个国家内,如果有多个CDMA运营商,可以通过MNC来进行区别
功能 说明
getCellLocation() 返回的单元格位置的装置 ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION
getDeviceId() 返回的IMEI / MEID的设备。 如果该设备是GSM设备 然后IMEI号将被退回,如果该设备是一个CDMA设备然后MEID 将被退回 READ_PHONE_STATE
getLine1Number() 返回设备的电话号码(MSISDN号码) READ_PHONE_STATE
getNetworkOperatorName() 返回注册的网络运营商的名字
getNetworkOperator() 返回的MCC +跨国公司的注册网络运营商
getNetworkCountryIso() 返回注册的网络运营商的国家代码
getSimCountryIso() 返回SIM卡运营商的国家代码 READ_PHONE_STATE
getSimOperator() 返回SIM卡运营商的单个核细胞数+冶 READ_PHONE_STATE
getSimOperatorName() 返回SIM卡运营商的名字 READ_PHONE_STATE
getSimSerialNumber() 返回SIM卡的序列号 READ_PHONE_STATE
getNetworkType() 返回网络设备可用的类型。 这将是 下列其中一个值:
TelephonyManagerNETWORK_TYPE_UNKNOWN TelephonyManagerNETWORK_TYPE_GPRS TelephonyManagerNETWORK_TYPE_EDGE TelephonyManagerNETWORK_TYPE_UMTS READ_PHONE_STATE getPhoneType() 返回设备的类型。 这将是以下值之一: TelephonyManagerPHONE_TYPE_NONE TelephonyManagerPHONE_TYPE_GSM TelephonyManagerPHONE_TYPE_CDMA READ_PHONE_STATE getSubscriberId() 返回用户识别码(的IMSI)的设备 READ_PHONE_STATE
getNeighboringCellInfo() 返回NeighboringCellInfo类代表名单 相邻小区的信息,如果可用,否则将 返回null ACCESS_COARSE_UPDATES
Android怎么判断是双卡双待的具体方法为:
1、Android平台是一个多样型的平台,不同的手机获取ITelephony接口不同,用一种方法实现双卡双待管理是不可取的。只有针对不同的手机分析出一套管理的方案,该方案实现难度大,因为需要各个厂家的SDK的资料。为了实现该功能,需要整合各个厂家的SDK的资料。
2、为了更好的管理双卡双待的问题,新建一个双卡双待模块静态库,其它项目引用便是,项目如图:
3、AbsSim是抽象类,负责实现手机 *** 作的类。不同的厂家继承该类实现各自的接口。AbsSim信息如下:
public abstract class AbsSim implements IDualDetector { //抽象基类
protected final String TAG = getClass()getSimpleName();
protected ArrayList<SimSlot> mSimSlots = new ArrayList<SimSlot>();
protected boolean mIsDualSimPhone = false;
protected String mCallLogExtraField = "";
public abstract String getSimPhoneNumber(int paramInt); // 返回手机号码
public abstract int getDataState(int paramInt);// 返回数据状态
public abstract String getIMSI(int paramInt);// 返回手机标识
public abstract String getIMSI(int paramInt, Context paramContext);// 返回手机标识
public abstract int getPhoneState(int paramInt);// 返回手机状态
public abstract boolean isServiceAvaliable(int paramInt);// 服务是否可用
public abstract boolean isSimStateIsReady(int paramInt);// 卡是否在使用
public abstract int getSimOperator(int paramInt);// 服务商(电信、移动、联通)
protected abstract Object getITelephonyMSim(int paramInt);// 获取 *** 作接口
protected abstract Object getMSimTelephonyManager(int paramInt);// 获取 *** 作接口
}
4、这是利用java 反射机制 *** 作Android隐藏的类,很好的解决了双卡双待的问题。
源码配置双卡还是单卡的路径在msm8976_android8\device\qcom\common\bacemk
ifeq ($(TARGET_USES_QCOM_BSP_ATEL),true)
PRODUCT_PROPERTY_OVERRIDES += persistradiomultisimconfig=dsds
endif
DSDA:Dual SIM dual active,即双卡双通;
DSDS:Dual SIM dual standy,即双卡双待;
双卡双通就是可以2个号码同时拨通并可以同时通话的。
双卡双待双通是指一部手机同时接通来自两个通信网络的信号(通过放两张卡)。
您可尝试以下几种方式查询本机号码:
1本机拨打开通来电显示的电话,对方手机屏幕上会显示您的号码;
2若您的号码已停机,可本机拨打当地10010客服,由客服代表为您查询;
3一般手机在接收到sim后,会被写入本机号码,此方式视手机功能而定。
以上就是关于安卓双卡双待导致获取不到mcc全部的内容,包括:安卓双卡双待导致获取不到mcc、Android程序怎么获得本机的手机号码有哪些办法、如何在Android开发中获取SIM卡信息等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)