At least on 6.0 and 7.0 the system app com.android.phone
is responsible for storing the messages sent by other apps. Unfortunately, this functionality is broken by some manufacturers and this is why we don't see sent messages.
It does work on AVD though. See the method persistSentMessageIfRequired() in com.android.internal.telephony.SMSDispatcher
.
Only this app or the selected default SMS app has a write permission to the SMS content provider. When you send it using the SMS app, it calls insert()
directly. When you use SmsManager
in your app, the system app com.android.phone
somehow gets notified, performs the sending and then stores the sent message. Here's the callstack (I didn't dig further):
at android.os.Handler.obtainMessage(Handler.java:293)
at com.android.internal.telephony.gsm.GsmSMSDispatcher.sendSmsByPstn(GsmSMSDispatcher.java:291)
at com.android.internal.telephony.gsm.GsmSMSDispatcher.sendSms(GsmSMSDispatcher.java:274)
at com.android.internal.telephony.SMSDispatcher.sendRawPdu(SMSDispatcher.java:999)
at com.android.internal.telephony.gsm.GsmSMSDispatcher.sendText(GsmSMSDispatcher.java:198)
at com.android.internal.telephony.ImsSMSDispatcher.sendText(ImsSMSDispatcher.java:206)
at com.android.internal.telephony.IccSmsInterfaceManager.sendTextInternal(IccSmsInterfaceManager.java:452)
at com.android.internal.telephony.IccSmsInterfaceManager.sendText(IccSmsInterfaceManager.java:393)
at com.android.internal.telephony.UiccSmsController.sendTextForSubscriber(UiccSmsController.java:136)
at com.android.internal.telephony.ISms$Stub.onTransact(ISms.java:201)
at android.os.Binder.execTransact(Binder.java:565)
After the SMS is sent, the app posts a Handler
message to itself:
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1343)
at com.android.providers.telephony.SmsProvider.insertInner(SmsProvider.java:618)
at com.android.providers.telephony.SmsProvider.insert(SmsProvider.java:442)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:264)
at android.content.ContentResolver.insert(ContentResolver.java:1274)
at com.android.internal.telephony.SMSDispatcher$SmsTracker.persistSentMessageIfRequired(SMSDispatcher.java:1445)
at com.android.internal.telephony.SMSDispatcher$SmsTracker.persistOrUpdateMessage(SMSDispatcher.java:1476)
at com.android.internal.telephony.SMSDispatcher$SmsTracker.onSent(SMSDispatcher.java:1537)
at com.android.internal.telephony.SMSDispatcher.handleSendComplete(SMSDispatcher.java:638)
at com.android.internal.telephony.SMSDispatcher.handleMessage(SMSDispatcher.java:274)
at com.android.internal.telephony.gsm.GsmSMSDispatcher.handleMessage(GsmSMSDispatcher.java:108)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)