当前位置:   article > 正文

【Android Q】Android Q SIM_STATE_CHANGED无法获取slotId或者phoneId

sim_state_changed

这几天调试适配NFC部分热插NFC SIM激活SWP时。

发现,

总是无法成功,经过调试原来根本原因是SIM_STATE_CHANGED广播的Extra数据已经不再具有slotId, 拿不到。

接下来的流程跑步下去了。

发现QCOM 和MediaTek 基线都是如此。

异常log如下:

  1. 08-02 00:04:08.168 2463 2463 D NfcSimStateObserver: onReceive: android.intent.action.SIM_STATE_CHANGED
  2. 08-02 00:04:08.168 2463 2463 D NfcSimStateObserver: ACTION_SIM_STATE_CHANGED receiver with iccState = LOADED, simId = -1
  3. 08-02 00:04:08.168 2463 2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId = -1 newPresenceState = 2 mUICC1State: Active mUICC2State: ? airplane: false
  4. 08-02 00:04:08.168 2463 2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId not supported -1
  5. 08-02 00:04:08.507 2463 2463 D NfcSimStateObserver: onReceive: android.intent.action.SIM_STATE_CHANGED
  6. 08-02 00:04:08.507 2463 2463 D NfcSimStateObserver: ACTION_SIM_STATE_CHANGED receiver with iccState = LOADED, simId = -1
  7. 08-02 00:04:08.507 2463 2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId = -1 newPresenceState = 2 mUICC1State: Active mUICC2State: ? airplane: false
  8. 08-02 00:04:08.507 2463 2463 D Nfc_SecureElementSelector: onSimStateChanged() - simId not supported -1

原来正常log如下:

  1. 08-09 06:49:57.206 4048 4048 D NfcSimStateObserver: onReceive: android.intent.action.SIM_STATE_CHANGED
  2. 08-09 06:49:57.206 4048 4048 D NfcSimStateObserver: ACTION_SIM_STATE_CHANGED receiver with iccState = LOADED, simId = 0
  3. 08-09 06:49:57.206 4048 4048 D Nfc_SecureElementSelector: onSimStateChanged() - simId = 0 newPresenceState = 2 mUICC1State: Available mUICC2State: ? airplane: false
  4. 08-09 06:49:57.206 4048 4048 D Nfc_SecureElementSelector: getIdofString() - str = SIM1 id = 81
  5. 08-09 06:49:57.206 4048 4048 D Nfc_SecureElementSelector: getUserDesiredSeId() - 0x81
  6. 08-09 06:49:57.207 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus(start, false) - nfceeid[0]: 0x81 conInfo[0]: 0x01, nfceeid[1]: 0x82 conInfo[1]: 0x01
  7. 08-09 06:49:57.207 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus() - not in Airplane mode, so using presence information SIM1=0x02, SIM2=0x00
  8. 08-09 06:49:57.207 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus() - mStActiveeSe = 0x00 mStActiveUicc = 0x00
  9. 08-09 06:49:57.207 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus(end) - mUICC1State: Available, mUICC2State: ?, meSEState: Available, mDHSEState: ?
  10. 08-09 06:49:57.207 4048 4048 D Nfc_SecureElementSelector: getActiveUiccValue() - mStActiveUicc= 0
  11. 08-09 06:49:58.235 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus(start, false) - nfceeid[0]: 0x81 conInfo[0]: 0x00, nfceeid[1]: 0x82 conInfo[1]: 0x01
  12. 08-09 06:49:58.236 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus() - not in Airplane mode, so using presence information SIM1=0x02, SIM2=0x00
  13. 08-09 06:49:58.236 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus() - mStActiveeSe = 0x00 mStActiveUicc = 0x81
  14. 08-09 06:49:58.236 4048 4048 D Nfc_SecureElementSelector: RefreshSeStatus(end) - mUICC1State: Active, mUICC2State: ?, meSEState: Available, mDHSEState: ?
  15. 08-09 06:49:58.237 4048 4048 D NfcService: setRoutingTableDirty()

接下来跟踪发送SIM_STATE_CHANGED广播的出处。

/frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java

  1. ///frameworks/opt/telephony/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
  2. @UnsupportedAppUsage
  3. private void broadcastSimStateChanged(int slotId, String state, String reason) {
  4. Intent i = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
  5. // TODO - we'd like this intent to have a single snapshot of all sim state,
  6. // but until then this should not use REPLACE_PENDING or we may lose
  7. // information
  8. // i.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
  9. // | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  10. i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  11. i.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
  12. i.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, state);
  13. i.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);
  14. SubscriptionManager.putPhoneIdAndSubIdExtra(i, slotId); //赋值SLOT ID的地方
  15. logd("Broadcasting intent ACTION_SIM_STATE_CHANGED " + state + " reason " + reason +
  16. " for phone: " + slotId);
  17. IntentBroadcaster.getInstance().broadcastStickyIntent(i, slotId);
  18. }

接着看SubsciptionManager的putPhoneIdAndSubIdExtra()方法。

 

  1. ///frameworks/base/telephony/java/android/telephony/SubscriptionManager.java
  2. /** @hide */
  3. @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
  4. public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
  5. int[] subIds = SubscriptionManager.getSubId(phoneId);
  6. if (subIds != null && subIds.length > 0) {
  7. putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]);
  8. } else {
  9. logd("putPhoneIdAndSubIdExtra: no valid subs");
  10. intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
  11. }
  12. }
  13. /** @hide */
  14. @UnsupportedAppUsage
  15. public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
  16. if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
  17. intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
  18. intent.putExtra(EXTRA_SUBSCRIPTION_INDEX, subId);
  19. intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
  20. }

经过对比,可以发现方法上多了个注释。

@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)

这个注释的意思是,Android P(API 28)之前(含P)才支持。

 

【解决方案】

直接从phoneid中拿,拿不到直接默认slotid=0.

  1. ///packages/apps/NfcSt/src/com/android/nfc/st/NfcSimStateObserver.java
  2. if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
  3. String iccState;
  4. int simId;
  5. iccState = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
  6. //[NFC] Begin modify by xxxie for T7753592 on 2019/08/02
  7. // because of SubscriptionManager send sticky broadcast SIM_STATE_CHANGED
  8. // UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) definition, so that
  9. // there are no more 'slot' value in ExtraData
  10. //simId = intent.getIntExtra(PhoneConstants.SLOT_KEY, -1);
  11. simId = intent.getIntExtra(PhoneConstants.PHONE_KEY, -1);
  12. //[NFC] End modify by xxxie for T7753592 on 2019/08/02
  13. if (iccState == null) {
  14. iccState = "NULL";
  15. }
  16. Log.d(TAG, "ACTION_SIM_STATE_CHANGED receiver with iccState = " + iccState +
  17. ", simId = " + simId);
  18. //[NFC] Begin modify by xxxie for T7753592 on 2019/08/02
  19. if (-1 == simId) {
  20. simId = 0;//拿不到默认给卡1
  21. }
  22. //[NFC] End modify by xxxie for T7753592 on 2019/08/02
  23. if (iccState.equals(IccCardConstants.INTENT_VALUE_ICC_LOADED)) {

这样就能暂时解决这个问题,但是倘若支持双NFC SIM的情况,单单热插slot2(SIM2),这将会是一个问题。

 

【Google解决方案】

经过当前最新的MTK baseline alps-trunk-q0.bsp-pre11.1查看,发现SubscriptionInfoUpdater已经更新,更新日期是2019/04/18。

这个提交的人是Jordan Liu(jminjie@google.com)。

发现自己又好像白干活了。。。

SubscriptionInfoUpdater add actual slotid int SIM_STATE_CHANGED extra by Jordan Liu

 

不知道为什么不干脆将SubscriptionManager.java中的接口开放,而是临时自己打个patch。

现在Android Q还尚不稳定,不知后边将如何变化。

静观其变吧。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/235632?site
推荐阅读
相关标签
  

闽ICP备14008679号