Как получить PhoneStateListener при использовании функции Dual SIM
Поэтому в настоящее время я внедряю функцию переадресации вызовов в Android для устройств с двумя SIM-картами. Чтобы прочитать текущее состояние переадресации (включено / отключено) для SIM-карты, я делаю следующее:
- Я создаю
TelephonyManager
объект:
val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
Я создаю
PhoneStateListener
объект и переопределитьonCallForwardingIndicatorChanged
метод:val myPhoneStateListener = object: PhoneStateListener() { override fun onCallForwardingIndicatorChanged(isCallForwardingEnabled: Boolean) { if(isCallForwardingEnabled) println("Call forwarding enabled!") else println("Call forwarding disabled!") } }
Я зарегистрировал
PhoneStateListener
:
telephonyManager.listen(myPhoneStateListener, LISTEN_CALL_FORWARDING_INDICATOR)
Это прекрасно работает для основной (первой) SIM-карты.
Но у меня возникают проблемы с тем же самым для второй SIM-карты. Вот как я пытаюсь это сделать:
Я использую
SubscriptionManager
объект для получения subscriptionId второй SIM-карты:val subscriptionManager = getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager val subscriptionIdOfSimCard2 = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1).subscriptionId
Я создаю отдельный
TelephonyManager
для второй SIM-карты с правильным идентификатором подписки:val secondTelephonyManager = (getSystemService(TELEPHONY_SERVICE) as TelephonyManager).createForSubscriptionId(subscriptionIdOfSimCard2)
Я создаю второй
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)
}
}