-
有关Sim卡状态
-
public static final int SIM_STATE_UNKNOWN = 0;//未知 public static final int SIM_STATE_ABSENT = 1;//拨卡、没有可用sim卡 public static final int SIM_STATE_PIN_REQUIRED = 2;//需要pin码解锁 public static final int SIM_STATE_PUK_REQUIRED = 3;//需要puk码解锁 public static final int SIM_STATE_NETWORK_LOCKED = 4; public static final int SIM_STATE_READY = 5;//验证成功 public static final int SIM_STATE_NOT_READY = 6;//SIM 卡未就绪
-
-
关于Sim卡数据,有几个比较重要属性
-
slotid、phoneid:是指卡槽,双卡机器的卡槽1值为0,卡槽2值为1,依次类推 -
subid:数据库中的一个主键,从1开始,每插入一个新卡,subId的值就会加1 -
simstate:表示卡状态
-
-
Sim卡底层和锁屏主要通过广播的方式进行数据通讯
Intent.ACTION_SIM_STATE_CHANGED-
protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (Intent.ACTION_SIM_STATE_CHANGED.equals(action)) { mSimLockManagerInner = getSimLockManager(); mIccLockViewCtrl = getIccLockViewController(); SimData args = SimData.fromIntent(intent); if (intent.getBooleanExtra(Intent.EXTRA_REBROADCAST_ON_UNLOCK, false)) { // Guarantee mTelephonyCapable state after SysUI crash and restart if (args.simState == TelephonyManager.SIM_STATE_ABSENT) { mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget(); } return; } mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState) .sendToTarget(); } } };
-
广播一般配合Handler进行处理,因为广播无法处理耗时操作
mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
.sendToTarget();
然后再通过观察者的方式,回调通知到各个地方
void handleSimStateChange(int subId, int slotId, int state) {
if ((changed || becameAbsent || becameNotReady)) {
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
cb.onSimStateChanged(subId, slotId, state);
}
}
}
}
-
插卡还没准备好
TelephonyManager.SIM_STATE_NOT_READY -
拨卡
TelephonyManager.*SIM_STATE_ABSENT*的时候,修改缓存数据状态-
if (state == TelephonyManager.SIM_STATE_ABSENT) { updateTelephonyCapable(true); // Even though the subscription is not valid anymore, we need to notify that the // SIM card was removed so we can update the UI. becameAbsent = true; for (SimData data : mSimDatas.values()) { // Set the SIM state of all SimData associated with that slot to ABSENT se we // do not move back into PIN/PUK locked and not detect the change below. if (data.slotId == slotId) { data.simState = TelephonyManager.SIM_STATE_ABSENT; } } }
-
-
Pin 码验证成功
TelephonyManager.SIM_STATE_READY-
@MainThread public void reportSimUnlocked(int subId) { mLogger.logSimUnlocked(subId); handleSimStateChange(subId, getSlotId(subId), TelephonyManager.SIM_STATE_READY); }
-
-
Pin 码验证,由于IPC可能会堵塞线程,所以需要放在独立线程执行
-
private abstract class CheckSimPin extends Thread { @Override public void run() { TelephonyManager telephonyManager = mTelephonyManager.createForSubscriptionId(mSubId); final PinResult result = telephonyManager.supplyIccLockPin(mPin); mView.post(() -> onSimCheckResponse(result,mSubId)); } }
-
-
验证卡槽是否有效
SubscriptionManager.isValidSlotIndex(slotId)
public static boolean isValidSlotIndex(int slotIndex) {
return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount();
}
- 验证subId是否有效
SubscriptionManager.isValidSubscriptionId(subId)
public static boolean isValidSubscriptionId(int subscriptionId) {
return subscriptionId > INVALID_SUBSCRIPTION_ID;
}
- 根据subId获取对应卡槽
int slotId = SubscriptionManager.getSlotIndex(subId);
-
根据卡状态查找下一个有效的sim卡,比如还有哪些sim pin码待验证
-
bestSlotId > slotId该逻辑主要是为了从小到大验证,比如0,1,2,3这样的顺序验证 -
public int getNextSubIdForState(int state) { List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */); int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first for (int i = 0; i < list.size(); i++) { final SubscriptionInfo info = list.get(i); final int id = info.getSubscriptionId(); int slotId = getSlotId(id); if (state == getSimState(id) && bestSlotId > slotId /* Unisoc: Add for Bug1153151 @{ */ && SubscriptionManager.isValidSlotIndex(slotId)/* @} */) { resultId = id; bestSlotId = slotId; } } return resultId; }
-