如何在使用双SIM卡功能时获取PhoneStateListener

时间:2017-11-17 14:23:44

标签: android mobile kotlin dual-sim

所以我目前正在Android中实现双SIM卡设备的呼叫转移功能。为了读取SIM卡的呼叫转移(启用/禁用)的当前状态,我执行以下操作:

  1. 我创建了一个TelephonyManager对象:
  2. val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager

    1. 我创建了一个PhoneStateListener对象并覆盖了onCallForwardingIndicatorChanged方法:

      val myPhoneStateListener = object: PhoneStateListener() {
        override fun onCallForwardingIndicatorChanged(isCallForwardingEnabled: Boolean) {
          if(isCallForwardingEnabled) println("Call forwarding enabled!")
          else println("Call forwarding disabled!")
        }
      }
      
    2. 我注册了PhoneStateListener

    3. telephonyManager.listen(myPhoneStateListener, LISTEN_CALL_FORWARDING_INDICATOR)

      这适用于主要(第一张)SIM卡。

      但我在为第二张SIM卡做同样的事情时遇到了麻烦。以下是我尝试这样做的方法:

      1. 我使用SubscriptionManager对象检索第二张SIM卡的subscriptionId:

        val subscriptionManager = getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
        val subscriptionIdOfSimCard2 = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1).subscriptionId
        
      2. 我为第二张SIM卡创建了一个单独的TelephonyManager,并使用正确的subscriptionId:

        val secondTelephonyManager = (getSystemService(TELEPHONY_SERVICE) as TelephonyManager).createForSubscriptionId(subscriptionIdOfSimCard2)
        
      3. 我创建了第二个PhoneStateListener,就像第一张SIM卡一样,我们称之为mySecondPhoneStateListener并将其注册到第二张TelephonyManager

        secondTelephonyManager.listen(mySecondPhoneStateListener, LISTEN_CALL_FORWARDING_INDICATOR)
        
      4. 现在的问题是,在mySecondPhoneStateListener中,我没有获得第二张SIM卡的回调,但仍然是主要的第一张SIM卡。在深入了解Android源代码之后,我发现了原因:在listen(PhoneStateListener listener, int events)的{​​{1}}方法中使用了错误的subscriptionId,即不是TelephonyManager中设置的那个。 TelephonyManager对象中的一个,默认情况下是第一张SIM卡的subscriptionId:

        PhoneStateListener

        可以通过为public void listen(PhoneStateListener listener, int events) { if (mContext == null) return; try { Boolean notifyNow = (getITelephony() != null); sRegistry.listenForSubscriber(listener.mSubId, */ HERE: listener.mSubId is used instead of this.mSubId */ getOpPackageName(), listener.callback, events, notifyNow); } catch (RemoteException ex) { // system process dead } catch (NullPointerException ex) { // system process dead } } 对象设置正确的subscriptionId来解决此问题,但是隐藏了相应的构造函数:

        PhoneStateListener

        通过将/** * Create a PhoneStateListener for the Phone using the specified subscription. * This class requires Looper.myLooper() not return null. To supply your * own non-null Looper use PhoneStateListener(int subId, Looper looper) below. * @hide */<-- HIDDEN, NOT ACCESSIBLE*/ */ public PhoneStateListener(int subId) { this(subId, Looper.myLooper()); } 对象的mSubId字段设置为第二张SIM卡的相应subscriptionId,我能够通过反射“解决”这个问题。

        但必须有更好的方法来做到这一点,我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

我用监听器制作了一个简单的ArrayList,对我来说很好(这是Kotlin btw)

在我的活动中:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.sim_selector)
    checkForForwarding()
}

fun getSimsCount(): Int {
    val subscriptionManager = SubscriptionManager.from(this)
    val activeSubscriptionInfoList = subscriptionManager.activeSubscriptionInfoList
    return activeSubscriptionInfoList.size
}

class SimForwardListeners{
    var subscriptionId: Int = 0
    lateinit var manager: TelephonyManager
    lateinit var phoneStateListener: MyPhoneStateListener
}

private val simsForwardListeners: ArrayList<SimForwardListeners> = arrayListOf()

fun checkForForwarding() {
    val subscriptionManager = getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager

    for (slotIndex in 0 until getSimsCount()) {
        val z = SimForwardListeners()
        z.phoneStateListener = MyPhoneStateListener(slotIndex)
        z.phoneStateListener.setView(this)
        z.subscriptionId = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(slotIndex).subscriptionId
        z.manager = (getSystemService(TELEPHONY_SERVICE) as TelephonyManager).createForSubscriptionId(z.subscriptionId)
        z.manager.listen(z.phoneStateListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR)
        simsForwardListeners.add(z)
    }
}