安卓双卡双待导致获取不到mcc

安卓双卡双待导致获取不到mcc,第1张

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卡信息等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9657925.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存