Android M 判断手机是否有SIM卡的逆推
来源:互联网 发布:阿拉曼战役 知乎 编辑:程序博客网 时间:2024/05/22 15:49
一、一般的判断是从数据库中查找的:
先是:
Cursor cursor = mContext.getContentResolver().query(SubscriptionManager.CONTENT_URI,null, selection, selectionArgs, null);
然后:
SubscriptionInfo subInfo = getSubInfoRecord(cursor);
最后:循环 游标 添加到 subList 中:
if (subInfo != null) { if (subList == null) { subList = new ArrayList<SubscriptionInfo>(); } subList.add(subInfo); }
即:\frameworks\opt\telephony\src\java\com\android\internal\telephony\SubscriptionController.java
中的getSubInfo()的调用,这里会去查询数据库中存储的值。
二、直接从Modem中读取数据:
位置:\frameworks\base\telephony\java\android\telephony\TelephonyManager.java
流程如下:
2.1
telephonyManager.hasIccCard()
2.2
public boolean hasIccCard() { return hasIccCard(getDefaultSim());}
2.3
public boolean hasIccCard(int slotId) { try { ITelephony telephony = getITelephony(); if (telephony == null) return false; return telephony.hasIccCardUsingSlotId(slotId); } catch (RemoteException ex) { // Assume no ICC card if remote exception which shouldn't happen return false; } catch (NullPointerException ex) { // This could happen before phone restarts due to crashing return false; } }
2.4
位置:packages\services\Telephony\src\com\android\phone\PhoneInterfaceManager.java
PhoneInterfaceManager.java 继承了 ITelephony
所以 走到 PhoneInterfaceManager的hasIccCardUsingSlotId:
@Override public boolean hasIccCardUsingSlotId(int slotId) { int subId[] = mSubscriptionController.getSubIdUsingSlotId(slotId); final Phone phone = getPhone(subId[0]); if (subId != null && phone != null) { return phone.getIccCard().hasIccCard(); } else { return false; } }
2.5
位置:\frameworks\opt\telephony\src\java\com\android\internal\telephony\IccCard.java
在IccCard接口中:
public boolean hasIccCard();
位置:\frameworks\opt\telephony\src\java\com\android\internal\telephony\uicc\IccCardProxy.java
然后IccCardProxy中实现:
public class IccCardProxy extends Handler implements IccCard
最后hasIccCard实现如下:
public boolean hasIccCard() { synchronized (mLock) { if (mUiccCard != null && mUiccCard.getCardState() != CardState.CARDSTATE_ABSENT) { return true; } return false; }}
2.6
位置:\frameworks\opt\telephony\src\java\com\android\internal\telephony\uicc\UiccCard.java
UiccCard中:
public CardState getCardState() { synchronized (mLock) { return mCardState; }}
2.7
UiccCard的构造函数和update函数都有对 mCardState 的赋值,当iccCard状态改变之后我们要做的就是更新操作:
public void update(Context c, CommandsInterface ci, IccCardStatus ics){ mCardState = ics.mCardState; ... ...}
2.8
位置:\frameworks\opt\telephony\src\java\com\android\internal\telephony\uicc\UiccController.java
然后我们来看调用 update() 的地方,可以看到 UiccController的onGetIccCardStatusDone() 当中有调用:
private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) { if (ar.exception != null) { Rlog.e(LOG_TAG,"Error getting ICC status. " + "RIL_REQUEST_GET_ICC_STATUS should " + "never return an error", ar.exception); return; } if (!isValidCardIndex(index)) { Rlog.e(LOG_TAG,"onGetIccCardStatusDone: invalid index : " + index); return; } IccCardStatus status = (IccCardStatus)ar.result; if (mUiccCards[index] == null) { //Create new card mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index); } else { //Update already existing card mUiccCards[index].update(mContext, mCis[index] , status); } if (DBG) log("Notifying IccChangedRegistrants"); mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null)); }
2.9
在handleMessage中,我们看到起调用:
case EVENT_ICC_STATUS_CHANGED: mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index)); break;case EVENT_GET_ICC_STATUS_DONE: onGetIccCardStatusDone(ar, index); break;
从下 往上我们可知道,
当消息为EVENT_GET_ICC_STATUS_DONE时,调用onGetIccCardStatusDone;
当消息为EVENT_ICC_STATUS_CHANGED 时,获取EVENT_GET_ICC_STATUS_DONE 消息。
位置:\frameworks\opt\telephony\src\java\com\android\internal\telephony\RIL.java
通过调用RILJ的getIccCardStatus来获取 icc 的状态:
@Override public void getIccCardStatus(Message result) { //Note: This RIL request has not been renamed to ICC, // but this request is also valid for SIM and RUIM RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result); if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); send(rr); }
2.10
至于EVENT_ICC_STATUS_CHANGED 的消息,则是在UiccController的构造函数中 一开始的时候就注册了监听:
private UiccController(Context c, CommandsInterface []ci) { if (DBG) log("Creating UiccController"); mContext = c; mCis = ci; for (int i = 0; i < mCis.length; i++) { Integer index = new Integer(i); mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index); mCis[i].registerForAvailable(this, EVENT_ICC_STATUS_CHANGED, index); mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, index); mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, index); } }
三、总结
至此,转入 RILJ 处理(进入getIccCardStatus( ),之后再转入modem处理)。
注册情况可参考UICC架构中的UiccController的构造函数的说明。
- Android M 判断手机是否有SIM卡的逆推
- Android判断手机里是否有SIM卡
- android 判断手机是否插入SIM卡
- android 判断是否有sim卡
- 如何通过代码判断手机中是否有SIM卡
- iphone开发中判断手机是否有SIM 卡的示例代码
- Android之判断是否有SD卡、SIM卡
- ios系统 判断是否有sim卡
- 如何判断sim卡是否有插入
- 如何通过代码判断手机中是否有SIM卡及各种状态
- Android判断SIM卡是否存在
- android判断手机SIM状态
- 如何判断sim卡是否有插入mtk
- 判断Android手机是否有录音权限
- Android 判断手机是否有传感器
- Android 判断是否有外置SD卡(包含手机存储的情况下)
- android,sim卡,TelephonyManager,手机SIM卡状态的获取
- 判断是否包含SIM卡
- Spring JDBC-Spring对DAO的支持
- 【前端笔试】JS中字符串的截取
- Centos7安装RocketMQ及配置测试
- 移植QT5.6到嵌入式开发板JZ2440
- select,数据查询,排序,字段别名__mysql学习笔记
- Android M 判断手机是否有SIM卡的逆推
- springmvc的核心,请求流程,
- PAT 甲级1001. A+B Format (20)
- C++的基础知识(五)--Path类、Directory类与File类
- 排序算法(三):简单选择排序
- C++ — const volatile mutable的用法
- 总结一下平时常用的知识
- 【技能库】--批量任务多线程并发执行(324)
- 软件设计师算法之回溯法--全排列