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);
}
=================================================================
For prevent SMS going to inbox in Android Kitkat
A change was introduced in KitKat that only allows one application at a time (the default SMS app) to have write permissions on the SMS DB and to be able to consume it.
You have 2 ways of solving your problem:
- Follow Google advice on how to request the user to switch the default SMS application to your application during the time when you need to perform your changes (and once you finish doing it, allow the user to switch back to the original default SMS app).
- Find a temporary hacky way to do what you need to do. As a hint, there is a hidden API:
[AppOpsManager][1] that you could potentially exploit in order to give your application write permissions (OP_WRITE_SMS), head over to this XDA page to learn more about it:
[How to write to SMS Content Provider in Android KitKat WITHOUT being default SMS app][2]
Reply if you have any query...
**UPDATE**
Starting from Android 4.4 Kitkat, it is not possible to perform any kind of SMS related operations without being the default SMS app. Restore and Backup apps cannot do it either. Most of them have updated their app to support this functionality and now ask the user to select them as the default SMS app.
Android KitKat update stopped supporting writing the SMS with other apps. You can only listen but cannot write. If you want to send sms, you have to send it to default SMS intent and the user has to approve and click SEND before sending SMS.
For your ref :[SMS provider][3]
[3]: http://developer.android.com/about/versions/kitkat.html#44-sms-provider
[1]: http://developer.android.com/reference/android/app/AppOpsManager.html
[2]: http://forum.xda-developers.com/showthread.php?t=2551072
When SMS is received by the Android system, it broadcasts an [ordered broadcast](http://developer.android.com/reference/android/content/BroadcastReceiver.html) `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](https://stackoverflow.com/a/19882453/566344), 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](https://developer.android.com/about/versions/android-4.4.html#SMS) in the Android 4.4 APIs.