Reputation: 23787
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.
Upvotes: 27
Views: 45123
Reputation: 1
manifest file
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Send"
tools:targetApi="31">
<service
android:name=".ForegroundService"
android:enabled="true"
android:exported="true">
</service>
<receiver
android:name="com.customer.send.SmsReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Upvotes: 0
Reputation: 456
I have this solution worked for me perfectly by adding BROADCAST_SMS permission:
<receiver android:name="com.mohamedtest.sendandreceivesms_m.SMSReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Upvotes: 1
Reputation: 1
You can make the SmsReceiver separately from the Sevice using context from the onReceive method to star service. That lets you not to run service all the time. Or even not starting activity to register receiver. Though I can mistake.
Something like this:
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED)) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus.length == 0) {
return;
}
SmsMessage[] messages = new SmsMessage[pdus.length];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
sb.append(messages[i].getMessageBody());
}
String number = messages[0].getOriginatingAddress();
String messageText = sb.toString();
Intent intent1 = new Intent(context, SMSreceiver.class);
intent1.putExtra(PHONE_NUMBER, number);
intent1.putExtra(SMS_TEXT, messageText);
context.startService(intent1);
}
}
}
Upvotes: 0
Reputation: 23787
I found the solution. To have a Service receive SMS messages:
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.
Upvotes: 61