How a Broken Feature Phone Led Me to Create a SIM Message Manager App

My old feature phone had been struggling with a dying battery for months, so I decided to switch to Android. But I have a lot of messages on the phone.
I was thinking how I could transfer them to the new phone. The only solution was to use the ‘Move to SIM’ option in the message menu. But the storage of a SIM card is quite low, typically it can store around 50 messages. Not a big deal I thought, I can simply do in batches.
SIM Card Messages: A Forgotten Feature
I slid my SIM card into the phone and was expect to get the messages. But when I opened the Google Messages App, the option “SIM card messages” was nowhere found.
A quick dive into various forums and articles revealed that SIM cards were never designed to be a storage system in the first place. This explains why the latest messages app abandoned the feature. SIM card was primarily intended to store only the carrier information. Yet, in early days of mobile phones with limited memory, it allowed to store few contacts and messages on it.
The Development Journey
Before writing a single line of code, I needed to answer a crucial question: how did Android used to read SIM messages?
Since I remembered the "SIM card messages" option from older versions of Google Messages, my first step was to track down an older version of the Messages app that still supported this feature and reverse engineer the app. After testing several APKs from archive, I found a version with build number 50058149 (released on October 4, 2019) having feature.
I started tracing the SIM Message part searching by the option name but I couldn’t find much useful information.
The option “SIM card messages” was in the screen “Advanced” so I thought of searching by screen title. And I found some interesting activities.
I took a note of “sub_id”. I also found an interesting word “SimMessages”. So I looked it up.
Things were getting more interesting at this point. I discovered a system API named getAllSimMessages
. The jqe
file contained more APIs like deleteMessageFromIcc
. At this stage, some words like subId
, icc
were repeatedly coming into my mind.
Spoiler: These system APIs don't work on normal apps on the latest Android version (15 as of writing) due to security reasons. (I spent a lot of time on this and later realized that Android actually blocks it, haha :3)
Giving Up?
The Messages app wasn't making any sense to me, and I tried to search more about the functionality of reading SMS but couldn't find anything useful. So, I began looking for alternative apps. I remembered that the OnePlus Messages App also had this feature. I started searching for a ported version, but there wasn't one available. While searching for more ported versions of the Messages App, I finally found an app that can read SIM messages. (Unfortunately, I forgot where I downloaded it from, sorry about that :3 Also, I'm not sure which Chinese mobile brand it belongs to.)
Here’s the preview of the ported app
As before, I was trying to trace where SIM messages were loading. This was the first time I learned that intents can be used to read messages. (The words icc
and sub_id
were still being questioned repeatedly in my mind) At this point, I got few keywords to learn more about loading messages.
While searching on Google, I found com/android/providers/telephony/SmsProvider.java
, which contains the string content://sms/icc
. I studied the source code and learned about the properties of a single SMS message. It was really interesting to me.
At this point, I started building my app and was able to successfully read messages from my SIM card! However, the problem arose when I realized I have dual SIM cards. How can I load messages specifically from one SIM?This is where the subId
comes in. The subId
, or subscription ID, is a unique identifier for a SIM card.
So, how can I use this number now to target specific SIM card?
There was an if-else statement to manage multiple SIM cards in a device. Yes, that's the intent I used for handling multiple subId
. Finally, I completed the core part of my app.
Export And Importing Messages
Now, the issue was how to import these messages into my phone's storage. None of the apps that can read messages from a SIM card can move the messages to the phone, unlike my feature phone, which can transfer messages from the SIM to the phone and vice-versa.
In this part, I handed off the responsibility of importing and exporting messages to two open-source apps: Fossify Messages and Quik. (Sometimes the best code is the code you don’t write :3)
Actually this part seemed a bit challenging to me, so instead of reinventing the wheel, I decided it would be better to use the FOSS apps to restore messages since they are well-tested. So, now I just needed to craft a JSON file that would be compatible with both apps. Easy-peasy.
Conclusion
Developing the App helped me learned a lot about the Android’s internal (Intent
, Telephony
, TelephonyManager
, SmsProvider
to name few APIs). It was both challenging and exciting to explore the source code of a massive project like Android. It also made me realize how much data apps can read, typically under guise of some innocent looking permissions. Though in recent versions, Google has implemented several security measures to enhance privacy. For example, apps can no longer read the IMEI number, which they could do in the early days.
Subscribe to my newsletter
Read articles from kurtnettle directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
