androidsmsandroid-4.4-kitkat

Sms doesn't save on Kitkat 4.4 <Already set as default messaging app>


My Sms app does not save the sms to the device even though I already set it as the default messaging. I need to support android pre-kitkat so I did a bit researching and had 2 BroadcastReceiver that have the same content but different name. The onReceive() method is working fine, but as soon as I quit the app and enter it the sms disappears. I checked in the stock messaging but there's no sms either. I cant figure out what the issue is

My Androidmanifest:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xml>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="16"
    android:targetSdkVersion="21" />

<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />

<application
    android:allowBackup="true"
    android:icon="@drawable/icon_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".SmsActivity"
        android:label="@string/app_name"
        android:uiOptions="splitActionBarWhenNarrow" >
        <meta-data
            android:name="android.support.UI_OPTIONS"
            android:value="splitActionBarWhenNarrow" />

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver
        android:name=".NewSmsBroadcastReceiver"
        android:permission="android.permission.BROADCAST_SMS" >
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_DELIVER" />
        </intent-filter>
    </receiver>
    <receiver android:name=".SmsBroadcastReceiver" >
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED"  />
        </intent-filter>
    </receiver>
    <receiver
        android:name=".MmsReceiver"
        android:permission="android.permission.BROADCAST_WAP_PUSH" >
        <intent-filter>
            <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />

            <data android:mimeType="application/vnd.wap.mms-message" />
        </intent-filter>
    </receiver>

    <activity android:name=".SendActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <action android:name="android.intent.action.SENDTO" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data android:scheme="sms" />
            <data android:scheme="smsto" />
            <data android:scheme="mms" />
            <data android:scheme="mmsto" />
        </intent-filter>
    </activity>

    <service
        android:name=".HeadlessSmsSendService"
        android:exported="true"
        android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE" >
        <intent-filter>
            <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />

            <category android:name="android.intent.category.DEFAULT" />

            <data android:scheme="sms" />
            <data android:scheme="smsto" />
            <data android:scheme="mms" />
            <data android:scheme="mmsto" />
        </intent-filter>
    </service>

    <activity
        android:name=".SendActivity"
        android:label="@string/app_name"
        android:parentActivityName=".SmsActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.wyrmise.melriss.SmsActivity" />
    </activity>
    <activity
        android:name=".ThreadActivity"
        android:label="@string/title_activity_thread" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.wyrmise.melriss.SmsActivity" />
    </activity>
</application>

</manifest>

BroadcastReceiver

public class SmsBroadcastReceiver extends BroadcastReceiver {

public static final String SMS_BUNDLE = "pdus";

public void onReceive(Context context, Intent intent) {
    Bundle intentExtras = intent.getExtras();
    if (intentExtras != null) {
        Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE);
        String address  = "";
        String smsBody = "";

        for (int i = 0; i < sms.length; ++i) {
            SmsMessage smsMessage = SmsMessage
                    .createFromPdu((byte[]) sms[i]);
            smsBody = smsMessage.getMessageBody().toString();
            address = smsMessage.getOriginatingAddress();
        }

        Message msg = new Message();
        msg.messageNumber=address;
        msg.messageContent=smsBody;
        SimpleDateFormat hours = new SimpleDateFormat("h:mm a",
                Locale.US);
        msg.messageDate=hours.format(new Date());

        SmsActivity inst = SmsActivity.instance();
        inst.pushNotification(msg);
        inst.updateList(msg);
    }
}
}

Solution

  • Even though you've got the Receivers set up to get the system broadcasts, you still need to store the messages retrieved from them; for example:

    ContentValues values = new ContentValues();
    values.put(Telephony.Sms.Inbox.ADDRESS, smsMessage.getDisplayOriginatingAddress());
    values.put(Telephony.Sms.Inbox.BODY, smsBody);
    values.put(Telephony.Sms.Inbox.DATE, System.currentTimeMillis());
    values.put(Telephony.Sms.Inbox.PROTOCOL, smsMessage.getProtocolIdentifier());
    values.put(Telephony.Sms.Inbox.READ, 0);
    values.put(Telephony.Sms.Inbox.SEEN, 0);
    values.put(Telephony.Sms.Inbox.SERVICE_CENTER, smsMessage.getServiceCenterAddress());
    values.put(Telephony.Sms.THREAD_ID, Telephony.Threads.getOrCreateThreadId(context, address));
    
    Uri insertUri = context.getContentResolver().insert(Telephony.Sms.Inbox.CONTENT_URI, values);
    

    Starting with KitKat, the default SMS app is responsible for writing all incoming messages to the Provider, so when your app is the default on those versions, you definitely need to save the messages from the SMS_DELIVER broadcasts.

    Pre-KitKat, there was no such thing as a default SMS app, so the user had to ensure to have at least one messaging app, often pre-installed, that would handle saving messages voluntarily, but it was kind of a free-for-all. If you're supporting those versions, you might need to handle inserting messages there too, if no other app is doing it.