关于监听SIM卡状态变化广播判断SIM卡当前状态的方法
一、问题:
终端启动后,APP层检测SIM卡的注册状态,连续收到4个ACTION_SIM_STATE_CHANGED广播,获取其系统的SIM state 状态时发现都是处于 TelephonyManager.SIM_STATE_READY 状态,如图:
需要找到为何在 TelephonyManager.SIM_STATE_READY 之后连续发送4次ACTION_SIM_STATE_CHANGED广播,SIM卡状态监听代码如图:
二、代码跟踪:
跟踪Logcat发现开机时可以监听到如下4次ACTION_SIM_STATE_CHANGED广播,如下图:
系统确实发出了4次ACTION_SIM_STATE_CHANGED广播,但是SIM卡状态的变化如下:
NOT_READY --> READY --> IMSI --> LOAD
并且从Logcat日志打印的时间,跟客户给出的时间间隔相比较,比较吻合。找到该日志打印的地方( SimStateReceiver.java 源码文件中),添加日志以作判断
// An highlighted block
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
mContext = context;
if (DBG)
log("received broadcast " + action);
if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
final int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY,
SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId()));
final String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
final int simState;
TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE); //_lcg_++ 添加用于打印SIM状态日志的代码
int state = tm.getSimState(); //_lcg_++ 添加用于打印SIM状态日志的代码
if (DBG)
log("ACTION_SIM_STATE_CHANGED intent received on sub = " + slotId
+ " SIM STATE IS " + stateExtra + ", state = " + state); //_lcg_++ 添加用于打印SIM状态日志的代码
if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
|| IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)
|| IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
simState = SimContactsConstants.SIM_STATE_READY;
}
else if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)
|| IccCardConstants.INTENT_VALUE_ICC_UNKNOWN.equals(stateExtra)
|| IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
simState = SimContactsConstants.SIM_STATE_ERROR;
} else {
simState = SimContactsConstants.SIM_STATE_NOT_READY;
}
log("ACTION_SIM_STATE_CHANGED intent on slotId = " + slotId + " simState = " + simState);
sendSimState(slotId, simState);
跟踪日志发现,此处所获取的SIM的状态均为state = 5也即state = TelephonyManager.SIM_STATE_READY,说明使用这个状态作为判断的依据有所不妥。
三、问题解决:
修改SIM卡是否初始化就绪的判断,更正为接收到系统ACTION_SIM_STATE_CHANGED广播的时后,获取该广播所携带的参数 IccCardConstants.INTENT_KEY_ICC_STATE的值作为判断依据,并根据获取的状态参数,判断此时广播参数值为 IccCardConstants.INTENT_VALUE_ICC_LOADED才会判断为SIM卡完全初始化完成,状态就绪。