首先要添加权限
<uses-permission android:name="android.permission.READ_PHONE_STATE"/> |
获取主卡的IMEI,IMSI,ICCID
- 如果一张手机卡那就是获取当前使用的手机卡的信息
- 如果2张手机卡,那就是获取的主卡信息,所谓主卡就是设置了默认打电话的卡
/** |
如果手机有多张卡
其实多卡情况下主要要获得的是两个地方:getSubscriberId和getSimSerialNumber,打开上面的的源码,搜索一下这两个方法,发现这两个方法都有一个带参数(subId)的重载方法,并且这两个方法都是@hide的,hide倒是无所谓,这个可以通过反射调用,主要的问题要弄清楚他的这个参数subId是个什么东西。代码片段如下:
/** |
从上面的注释来来,这个subId 是subscription id的简写,既然提到subscription id,那不得不说的就是SubscriptionManager.
Subscription和SubscriptionManager
一台设备可以有多张SIM卡,最典型的例子就是眼下流行的“双卡双待”。每一张SIM卡都对应一个Subscription,Subscription:谷歌翻译为“订阅”
订阅(Subscription):定义了请求者与业务或业务操作之间的关联关系。只有定义了订阅关系,才能通过业务策略,控制请求者对某个业务的访问行为。
我们用谁家的SIM卡就相当于订阅(Subscription)谁家的业务,对应的SIM卡的信息就是Subscription Information
,比如运营商名称、MNC、MCC等,多张SIM卡就有多个Subscription Information
。
在Android中,针对上述功能的实现、管理就是SubscriptionManager,表现到软件上就是:
各个类的实现比较简单自行参看源码。
SubscriptionManager作用有三个:
- 获取Subscription信息
- 更改Subscription某些信息
- 提供
OnSubscriptionsChangedListener
监听器,方便其他应用监听Subscription
的状态改变
Subscription内容:
/** |
看下对应的术语:
- ICCID:Integrate circuit card identity 集成电路卡识别码(固化在手机SIM卡中)。ICCID为IC卡的唯一识别号码,共有20位数字组成:
PLMN:Public Land Mobile Network 公共陆地移动网,一般某个国家的一个运营商对应一个PLMN
SPN:Service Provider Name 运营商名称
MCC:Mobile Country Code,移动国家码,MCC的资源由国际电联(ITU)统一分配和管理,唯一识别移动用户所属的国家,共3位,中国为460
MNC:Mobile Network Code 移动网络号码,用于识别移动用户所归属的移动通信网,2~3位数字组成,如中国移动系统使用00、02、04、07,中国联通GSM系统使用01、06、09
ISO country code: 国际上不同国家的ISO编码,比如我们国家:cn
对于SubscriptionController
来说,它是从数据库/data/data/com.android.providers.telephony/databases/telephony.db
的siminfo表中读取的数据.
只要知道一点,这个类就是为了5.0之后,为了配合TelephonyProvider操作和处理/data/data/com.android.providers.telephony/databases/telephony.db
这个数据库中的表的,就可以了。
siminfo表的创建: |
这些字段都表示了什么意思,其中最重要的是_id和sim_id:
- _id:从数据库的角度来说,做过sqlite开发的都知道,他是个从1开始自增的主键。但是他在这里还代表了程序中另一个东西subId也就是subscription id
- icc_id:不解释,上面说过了
- sim_id:这个字段有两层含义,在大于-1,的情况下他表示的是卡槽序号,比如sim_id为0表示卡1,取值为1的时候表示的是卡2,以此类推,但是一般手机不会超过两个卡槽吧?!如果取值为-1,表示这张SIM卡曾经被插入过,但是现在被移除了。
- display_name:顾名思义,显示名。这个一般可以改,但是默认的是读取的运营商的名字,比如:中国移动,中国联通,中国电信
- carrier_name :恩,运营商名字
- number:SIM卡对应的手机号,这个不一定能取到
- mcc:Mobile Country Code,移动国家码
- mnc:Mobile Network Code,移动网络码
获取subscription id
public static void getSimInfo() { |
如上代码,我在红米6的测试机上进行测试,插入过3张卡,两张移动,一张联通的,运行结果如下(因为是真是的SIM卡,隐藏了icc_id):
08-14 16:46:11.208 11583-11583/me.febsky.rootcheck D/Q_M: icc_id-->898600*************7 |