android-multisim.md 4.2 KB

+++ title = "Android Multisim Pre-5.1" date = 2021-09-12T19:37:22+09:00 tags = [ "programming", "android" ] +++

NOTE if you're just looking for a library to use, there's MultiSim. I've never used this so I can't guarantee anything about it. It also only supports SIM information and not SMS.

Phones that can take multiple SIM cards are quite popular in the Philippines. The two major telecoms would have unlimited SMS packages for messages within their networks. It was quite common to have a SIM for each telco and use the appropriate one depending on who you were sending to.

Android's API only officially supported multiple SIM cards in 5.1 (API level 22) but Android phones with dual-SIM (and even triple-SIM) capabilities were already available at least as far back as 2.3 (API level 10) when I first needed to support it. Since there was no official API for this, the manufacturers just invented their own and of course each one implemented it in a different way.

Mediatek

The first phone we started working on was a Lenovo A60 which used a Mediatek SOC. We somehow got a library from the manufacturer that let us use the dual-SIM functionality, but it was quite a pain to get working as there was limited documentation and we were quite new to Android development at the time.

When we disassembled the library that they gave us, we noticed that the names they used for the additional functions were quite interesting. They were all the TelephonyManager and SmsManager methods with a Gemini suffix and they would take an additional int parameter in addition to the original.

It turned out that these were available on the standard TelephonyManager instance and could be accessed via reflection. The SmsManager was a bit trickier but we ended up figuring out that there was a android.telephony.gemini.GeminiSmsManager class that had the functionality.

In a different phone with a Mediatek SOC, this got renamed to com.mediatek.telephony.gemini.SmsManager for some reason and dropped the Gemini suffix only for the SmsManager.

Intel

It was also around this time that Intel started making SOCs for smartphones. We had an ASUS Fonepad 7. Unlike with the Mediatek device, we didn't have a library to use here and had to use reflection to find the hidden classes / methods.

What we found was that instead of having a single instance with every method taking a sim parameter, they instead had separate instances of TelephonyManager and SmsManager for each SIM. You would call TelephonyManager.get2ndTm() and SmsManager.get2ndSmsManager() to have access to the 2nd SIM.

Qualcomm

The last phone I looked at was a dual-SIM Moto G. What's interesting about this one is that the API completely changed in the upgrade from 4.4 to 5.0.

On Android 4.4, the API was pretty close to the Mediatek one. You had a single instance that could dispatch to other SIMs by having an extra parameter on all the methods. These were in android.telephony.MSimTelephonyManager and android.telephony.MSimSmsManager.

On Android 5.0, the API was a weird mix of all the above and also the introduction of android.telephony.SubscriptionManager which was quite close but not exactly the same as what ended up in the official API. Instead of getActiveSubscriptionInfoList there was getActiveSubIdList which only returned long[].

For the information that would normally exist in SubscriptionInfo, you had to query the main TelephonyManager instance which had methods with an extra long parameter for the subscription id. The SmsManager was simpler with just getSmsManagerForSubscriber.

With Android 5.1, I assume they just switched to using the official API so this phone would have gone through 3 different multi-SIM APIs over the course of it's life.

Epilogue

Around the release of Android 5.1, we stopped work on the app so I never actually got to use the official API myself ironically. We also never really got a big deployment so while I saw quite the variety of multi-SIM implementations, that's probably not all that's been out in the wild.