Having a Service receive SMS messages

android

Solution

I found the solution. To have a Service receive SMS messages:

- Update the manifest to give your app the permissions to receive SMS (WRITE_SMS, READ_SMS, RECEIVE_SMS)

- DO NOT update the manifest with the receiver intent filter ! (which every sample code online seems to do)

In your Service, create a nested BroadcastReceiver class within your Service class

private class SMSreceiver extends BroadcastReceiver
{
    private final String TAG = this.getClass().getSimpleName();

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Bundle extras = intent.getExtras();

        String strMessage = "";

        if ( extras != null )
        {
            Object[] smsextras = (Object[]) extras.get( "pdus" );

            for ( int i = 0; i < smsextras.length; i++ )
            {
                SmsMessage smsmsg = SmsMessage.createFromPdu((byte[])smsextras[i]);

                String strMsgBody = smsmsg.getMessageBody().toString();
                String strMsgSrc = smsmsg.getOriginatingAddress();

                strMessage += "SMS from " + strMsgSrc + " : " + strMsgBody;                    

                Log.i(TAG, strMessage);
            }

        }

    }

}

In your Service class, register to receive the `android.provider.Telephony.SMS_RECEIVED` intent filter :

public class ServiceCommunicator extends Service
{
    private SMSreceiver mSMSreceiver;
    private IntentFilter mIntentFilter;

    @Override
    public void onCreate()
    {
        super.onCreate();

        //SMS event receiver
        mSMSreceiver = new SMSreceiver();
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        registerReceiver(mSMSreceiver, mIntentFilter);
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();

        // Unregister the SMS receiver
        unregisterReceiver(mSMSreceiver);
    }
}

That's it !

note: encase you're wondering why I didn't bind to my service from within a separate BroadcastReceiver class - it doesn't work because `bindService()` isn't available.

Problem

I've looked at a few SMS message examples and Activities are typically used to receive an SMS. However, what I'd like to do is have my background service receive the SMS (the service will process the message and decide whether it is applicable to the app - then inform the user) In my Manifest, the service is defined as follows: ``` <service android:name=".service.myService" android:enabled="true"> <intent-filter> <action android:name="package.com.service.myService"/> </intent-filter> </service> ``` to have the service receive the SMS, will this work ? ``` <receiver android:name=".service.myService" android:exported="true" > <intent-filter android:priority="999"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> ``` The sample code I studied came from: http://www.apriorit.com/our-company/dev-blog/227-handle-sms-on-android I can't test it yet because my development module doesn't have a phone number to send an SMS to.

Original source