Как получить PhoneStateListener при использовании функции Dual SIM

Поэтому в настоящее время я внедряю функцию переадресации вызовов в Android для устройств с двумя SIM-картами. Чтобы прочитать текущее состояние переадресации (включено / отключено) для SIM-карты, я делаю следующее:

  1. Я создаю TelephonyManager объект:

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:

telephonyManager.listen(myPhoneStateListener, LISTEN_CALL_FORWARDING_INDICATOR)

Это прекрасно работает для основной (первой) SIM-карты.

Но у меня возникают проблемы с тем же самым для второй SIM-карты. Вот как я пытаюсь это сделать:

  1. Я использую SubscriptionManager объект для получения subscriptionId второй SIM-карты:

    val subscriptionManager = getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
    val subscriptionIdOfSimCard2 = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1).subscriptionId
    
  2. Я создаю отдельный TelephonyManager для второй SIM-карты с правильным идентификатором подписки:

    val secondTelephonyManager = (getSystemService(TELEPHONY_SERVICE) as TelephonyManager).createForSubscriptionId(subscriptionIdOfSimCard2)
    
  3. Я создаю второй PhoneStateListenerтак же, как и для первой SIM-карты, давайте назовем ее mySecondPhoneStateListener и зарегистрируйте его со вторым TelephonyManager:

    secondTelephonyManager.listen(mySecondPhoneStateListener, LISTEN_CALL_FORWARDING_INDICATOR)
    

Проблема теперь в том, что в mySecondPhoneStateListener я не получаю обратные вызовы для второй SIM-карты, но все еще основной, первой. Покопавшись в исходном коде Android, я выяснил, почему это так: listen(PhoneStateListener listener, int events) метод TelephonyManager используется неверный идентификатор подписки, т.е. не тот, который указан в TelephonyManager но тот в PhoneStateListener объект, который является subscriptionId первой SIM-карты, по умолчанию:

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 PhoneStateListener возражать против соответствующего subscriptionId второй SIM-карты.

Но должен быть лучший способ сделать это, я что-то упустил?

1 ответ

Я делаю простой ArrayList со Слушателями, и он отлично работает для меня (кстати, это Kotlin)

В моей деятельности:

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)
    }
}
Другие вопросы по тегам