【问题标题】:What is the value of SIM state when "airplane mode" is turned on开启“飞行模式”时SIM状态的值是多少
【发布时间】:2011-12-12 13:08:07
【问题描述】:

我想知道“飞行模式”开启时TelephonyManager.getSimState()返回的SIM状态值是多少?这似乎没有在 SDK 规范的任何地方直接指定。

实际上我需要使用getSimOperator() 方法获取 SIM 运营商代码(即 MCC+MNC),但 JavaDoc 声明要使用该方法:

SIM 状态必须为SIM_STATE_READY

更新

我在模拟器下对其进行了测试,它在打开飞行模式后返回SIM_STATE_UNKNOWN(javadoc 将其描述为“状态之间的转换”)。但是我想知道这是否是 Android 手机上的常见行为?

【问题讨论】:

    标签: android telephony sim-card airplane


    【解决方案1】:

    是的,这是安卓手机上的常见行为。 查看 TelephonyManager 类中 getSimState() 方法的实现:

    public int getSimState() {
        String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE);
        if ("ABSENT".equals(prop)) {
            return SIM_STATE_ABSENT;
        }
        else if ("PIN_REQUIRED".equals(prop)) {
            return SIM_STATE_PIN_REQUIRED;
        }
        else if ("PUK_REQUIRED".equals(prop)) {
            return SIM_STATE_PUK_REQUIRED;
        }
        else if ("NETWORK_LOCKED".equals(prop)) {
            return SIM_STATE_NETWORK_LOCKED;
        }
        else if ("READY".equals(prop)) {
            return SIM_STATE_READY;
        }
        else {
            return SIM_STATE_UNKNOWN;
        }
    }
    

    【讨论】:

    • 这不是那么简单,因为TelephonyManager.getSimState 没有向我们展示手机和 sim 状态之间的映射(请参阅我自己的答案以了解负责该问题的代码)。无论如何都给你+1来查看源代码;)
    【解决方案2】:

    在搜索 Android 4.1 的源代码后,我在 com.android.internal.telephony.IccCard 的一个私有类中找到了以下代码:

    public State getState() {
      if (mState == null) {
          switch(mPhone.mCM.getRadioState()) {
              /* This switch block must not return anything in
               * State.isLocked() or State.ABSENT.
               * If it does, handleSimStatus() may break
               */
              case RADIO_OFF:
              case RADIO_UNAVAILABLE:
              case SIM_NOT_READY:
              case RUIM_NOT_READY:
                  return State.UNKNOWN;
              case SIM_LOCKED_OR_ABSENT:
              case RUIM_LOCKED_OR_ABSENT:
                  //this should be transient-only
                  return State.UNKNOWN;
              case SIM_READY:
              case RUIM_READY:
              case NV_READY:
                  return State.READY;
              case NV_NOT_READY:
                  return State.ABSENT;
          }
      } else {
          return mState;
      }
    
      Log.e(mLogTag, "IccCard.getState(): case should never be reached");
      return State.UNKNOWN;
    }  
    

    所以只要无线电状态是RADIO_OFFRADIO_UNAVAILABLE 之一,就会返回State.UNKNOWN。那么State.UNKNOWN会被TelephonyManager.getSimState()方法转换成SIM_STATE_UNKNOWN常量。

    结论:开启飞行模式时getSimState会返回SIM_STATE_UNKNOWN

    【讨论】:

    • 您能否修复指向 RADIO_OFF 和 RADIO_UNAVAILABLE 的链接?
    • @NiravZaveri 完成。请注意,从 Android 4.2 开始,IccCard 已转换为接口并已弃用。相关逻辑现在位于IccCardProxy 类。当无线电关闭时,内部使用State.NOT_READY。尽管如此,它在公共 API 中不可用,它在 getSimState() 方法中转换为 SIM_STATE_UNKNOWN
    • 谢谢。我通常发生的事情是即使在飞行模式打开时,即使在飞行模式下也会进入 Sim_State_Ready,但之后也会将 simSerialNumber 返回为 NULL。这就是我想查看源代码的原因。
    • @NiravZaveri 你有什么安卓版本?
    • 我正在测试代码的这款手机上安装了 Android 4.3。这是一部红米手机(MIUI 45 版)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 2011-12-03
    相关资源
    最近更新 更多