Reputation: 337
I'm developing a business SMS application. In this app, if an incoming message is from a particular number, say 999999999, it should go to the application's inbox and not to the default native inbox. All other messages should go to the phone's native inbox. How do I do this?
Upvotes: 17
Views: 17878
Reputation: 3029
When SMS is received by the Android system, it broadcasts an ordered broadcast Intent
with action "android.provider.Telephony.SMS_RECEIVED"
. All registered receivers, including the system default SMS application, receive this Intent
in order of priority
that was set in their intent-filter
. The order for broadcast receirers with the same priority is unspecified. Any BroadcastReceiver
could prevent any other registered broadcast receivers from receiving the broadcast using abortBroadcast()
.
So, everything you need is broadcast receiver like this:
public class SmsFilter extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Bundle extras = intent.getExtras();
if (extras != null) {
Object[] pdus = (Object[])extras.get("pdus");
if (pdus.length < 1) return; // Invalid SMS. Not sure that it's possible.
StringBuilder sb = new StringBuilder();
String sender = null;
for (int i = 0; i < pdus.length; i++) {
SmsMessage message = SmsMessage.createFromPdu((byte[]) pdus[i]);
if (sender == null) sender = message.getOriginatingAddress();
String text = message.getMessageBody();
if (text != null) sb.append(text);
}
if (sender != null && sender.equals("999999999")) {
// Process our sms...
abortBroadcast();
}
return;
}
}
// ...
}
}
Looks like the system default SMS processing application uses priority of 0
, so you could try 1
for your application to be before it. Add these lines to your AndroidManifest.xml
:
<receiver android:name=".SmsFilter">
<intent-filter android:priority="1">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Don't forget about necessary permissions:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
By the way, you can find all registered receivers and their priorities using this code:
Intent smsRecvIntent = new Intent("android.provider.Telephony.SMS_RECEIVED");
List<ResolveInfo> infos = context.getPackageManager().queryBroadcastReceivers(smsRecvIntent, 0);
for (ResolveInfo info : infos) {
System.out.println("Receiver: " + info.activityInfo.name + ", priority=" + info.priority);
}
Update: As FantasticJamieBurn said below, starting from Android 4.4 the only app that can intercept SMS (and block if it wish) is the default SMS app (selected by user). All other apps can only listen for incoming SMS if default SMS app not blocked it.
See also SMS Provider in the Android 4.4 APIs.
Upvotes: 31
Reputation: 3182
Check the sender number is equal to the mobile number of your sms sending phone.
replace the following code line of Mr "praetorian droid"
if (sender != null && sender.equals("999999999")) {
to
if (sender != null && sender.equals("YOUR SMS SENDING MOBILE NUMBER HERE")) {
further more you can give a setting to user to manually add sms sending number if he want to change it.
Upvotes: 1
Reputation: 3004
With the release of Android 4.4 KitKat (API level 19), the option to block an SMS message and prevent it from being delivered to the default SMS app has been removed. Non-default SMS app's may observe SMS messages as they are received, but any attempt to abort the broadcast will be ignored by Android 4.4+.
If you have an existing app which relies on aborting SMS message broadcasts then you may want to consider the impact this change in behaviour will have when your users upgrade to Android 4.4+.
http://android-developers.blogspot.co.uk/2013/10/getting-your-sms-apps-ready-for-kitkat.html
Upvotes: 13
Reputation: 349
Yes it can be DOne
public void onReceive(Context context, Intent intent)
{
Bundle bundle=intent.getExtras();
Object[] messages=(Object[])bundle.get("pdus");
SmsMessage[] sms=new SmsMessage[messages.length];
Toast.makeText(context, "Hello", 1).show();
for(int n=0;n<messages.length;n++){
sms[n]=SmsMessage.createFromPdu((byte[]) messages[n]);
}
for(SmsMessage msg:sms){
if(msg.getOriginatingAddress().endsWith(number))
{
SMS.updateMessageBox("\nFrom: "+msg.getOriginatingAddress()+"\n"+
"Message: "+msg.getMessageBody()+"\n");
/*((SMS) context).delete();*/
abortBroadcast();
}
}
}
just use abortbroadcast() after receiving in app
Upvotes: 2