Blocking Call and SMS in Android

Block SMS in Android Programmatically

There are lots of application out there who has the functionality to block call and SMS. I assume, you also want to develop an application where you can block SMS in android as well as block call in android. It’s a common use cause. But most of the time it’s not that much easy as you are thinking. With the latest version upgrade and other policy implemented inside android operating system that requires you to tweak your code base if you have any SMS and Call Blocking Android app of your own. But I have already overcome that challenge. In addition, I have prepared all the scripts and process to block SMS on android as well as call. Today I am going to show you how to block call and SMS in Android including latest version (Kitkat, Lollipop, Marshmallow etc).

Be familiar with BroadcastReceiver class

To implement SMS and call blocking functionality most of our works will be done via BroadcastReceiver class. But what it is? Let’s talk about it first. A broadcast receiver (short receiver ) is an Android component which allows you to register for system or application events. All registered receivers for an event are notified by the Android runtime once this event happens. Read more about BroadcastReceiver.

How to block SMS and Call on Android

Prepare manifest.xml file

At first, we need to prepare our Manifest.xml file with a BroadcastReceiver and necessary permissions given below –

  • RECEIVE_SMS
    This permission is for allowing an application to receive SMS messages.
  • CALL_PHONE
    This is for making calls from Android phone
  • READ_PHONE_STATE
    This permission is to access the phone state including phone number, current network information, status of ongoing calls and registered PhoneAccounts

Here is code for the permission you need.

<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

And The BraodcastReceiver named PhoneStateReceiver for receiving call and  sms is –

<receiver
android:name="com.test.blocker.PhoneStateReceiver"
android:enabled="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="9999">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>

We registered a broadcast receiver “PnoheStateReceiver” by receiver node. And “intent-filter”  is used to filter the intent action which is being received. We provided two action here. These are –  Action “android.intent.action.PHONE_STATE” is used to  receive all phone state, including the phone number of the device, current cellular network information, the status of any ongoing calls. And action “android.provider.Telephony.SMS_RECEIVED” is used to receive sms messages.

In the priority of intent-filter, the value must be an integer, such as “10>”. Higher numbers have a higher priority of receiver to receive the intent . The default value is 0. The value must be greater than -1000 and less than 1000.

Implement PhoneStatereceiver.java class

Now its time to implement our PhoneStatereceiver.java class which is our broadcast receiver. Lets see the example .

public class PhoneStateReceiver extends BroadcastReceiver {

 private String blockingNumber = "XX-XXX-XXXXX";

 @Override
 public void onReceive(final Context context, final Intent intent) {

  //blocking sms for matched number

  if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
   Bundle bundle = intent.getExtras();
   Object messages[] = (Object[]) bundle.get("pdus");
   SmsMessage smsMessage[] = new SmsMessage[messages.length];

   for (int n = 0; n < messages.length; n++) {
    smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
   }

   final String numberSms = smsMessage[0].getOriginatingAddress();
   //final String messageSms = smsMessage[0].getDisplayMessageBody();
   //long dateTimeSms = smsMessage[0].getTimestampMillis();

   //block sms if number is matched to our blocking number 
   if (numberSms.equals(blockingNumber)) {
    abortBroadcast();
   }
  }
 }
}

Here “blockingNumber” is the number which will be blocked for call and sms. “onReceive(final Context context, final Intent intent)” method will be called each time when receiver is notified with context and intent data. All information of sms such as number, message body, time etc will be found from intent provided by onReceive method. We got the number/address of sms by calling  getOriginatingAddress() method from extracted pdus information from intent. Also we can get message body and time by calling getDisplayMessageBody() and getTimestampMillis() method from extracted pdus information. These are not related to block number. I just show you how to get message body and time also. It can be needed for further process. If this numberSms is matched with our blockingNumber then broadcast receiver will be aborted. And this is the mechanism for blocking sms.

Now lets see implementation of PhoneStateReceiver.java and how to block call in android phone for matched number. Follow the example

public class PhoneStateReceiver extends BroadcastReceiver {

 private String blockingNumber = "XX-XXX-XXXXX";

 @Override
 public void onReceive(final Context context, final Intent intent) {

  //blocking sms for matched number

  if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
   final String numberCall = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);;

   //reject call if number is matched to our blocking number 
   if (numberCall.equals(blockingNumber)) {
    disconnectPhoneItelephony(context);
   }
  }
 }

 // Keep this method as it is
 @SuppressWarnings({
  "rawtypes",
  "unchecked"
 })
 private void disconnectPhoneItelephony(Context context) {
  try {

   String serviceManagerName = "android.os.ServiceManager";
   String serviceManagerNativeName = "android.os.ServiceManagerNative";
   String telephonyName = "com.android.internal.telephony.ITelephony";
   Class < ? > telephonyClass;
   Class < ? > telephonyStubClass;
   Class < ? > serviceManagerClass;
   Class < ? > serviceManagerNativeClass;
   Method telephonyEndCall;
   Object telephonyObject;
   Object serviceManagerObject;
   telephonyClass = Class.forName(telephonyName);
   telephonyStubClass = telephonyClass.getClasses()[0];
   serviceManagerClass = Class.forName(serviceManagerName);
   serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
   Method getService = // getDefaults[29];
    serviceManagerClass.getMethod("getService", String.class);
   Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
   Binder tmpBinder = new Binder();
   tmpBinder.attachInterface(null, "fake");
   serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
   IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
   Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
   telephonyObject = serviceMethod.invoke(null, retbinder);
   telephonyEndCall = telephonyClass.getMethod("endCall");
   telephonyEndCall.invoke(telephonyObject);

  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

For making these code working to latest version android (Kitkat, Lollipop, Marshmallow etc) you need to set your app as default SMS app. To make default SMS App -add some features, like sending sms activity and service, mms receiver etc. Because Android changes the rules for receiving sms only. For blocking call on android it will working fine.

To make your app as default sms app follow these instructions given below –

Step-1 : At first, add these code on  Manifest.xml file.

<activity android:name="com.test.blocker.MessageActivity">
<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>

These code will simply add a activity on Manifest.xml file which has some action and data intent filter. These allows your app to receive intents from other apps that want to deliver a message by this activity.

Now create an activity with name MessageActivity.java which will be used for delivering sms.

public class MessageActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message);

        //code for sending sms and use ui 
    }
}

Step-2: Add another broadcast receiver for listening mms on Manifest.xml.

<!-- BroadcastReceiver that listens for incoming MMS messages -->
<receiver
android:name="com.test.blocker.MmsReceiver"
android:enabled="true"
android:exported="true"
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>

And create a broadcast receiver for this with file name MmsReceiver.java.

public class MmsReceiver extends BroadcastReceiver {
 public MmsReceiver() {}

 @Override
 public void onReceive(Context context, Intent intent) {
  // TODO: This method is called when the BroadcastReceiver is receiving
  // an Intent broadcast.
  throw new UnsupportedOperationException("Not yet implemented");
 }
}

Step-3 : Add a service with name SmsSendService on Manifest.xml file which will deliver sms.

<!-- Service that delivers messages from the phone "quick response" -->
<service
android:name="com.test.blocker.SmsSendService"
android:enabled="true"
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>

And create a service with file name SmsSendService.java.

public class SmsSendService extends Service {
    public SmsSendService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

Step-4: For making default sms app you need to add this code on your launcher activity or any other place.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                if(!Telephony.Sms.getDefaultSmsPackage(getApplicationContext()).equals(getApplicationContext().getPackageName())) {
                    //Store default sms package name
                    Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
                    intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,
                            getApplicationContext().getPackageName());
                    startActivity(intent);
                }
            }

It will show dialog to make your app default sms app and then press ok do it.

Full Source Code for block SMS in android

Here I am providing the full source code to block SMS in android as well as block call in android.

manifest.xml

<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.blocker.blacklist">
   <uses-permission android:name="android.permission.RECEIVE_SMS" />
   <uses-permission android:name="android.permission.READ_PHONE_STATE" />
   <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar">
      <activity android:name="com.test.blocker.MessageActivity">
         <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>
      <receiver android:name="com.test.blocker.PhoneStateReceiver" android:enabled="true" android:permission="android.permission.BROADCAST_SMS">
         <intent-filter android:priority="9999">
            <action android:name="android.intent.action.PHONE_STATE" />
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
         </intent-filter>
      </receiver>
      <!-- BroadcastReceiver that listens for incoming MMS messages -->
      <receiver android:name="com.test.blocker.MmsReceiver" android:enabled="true" android:exported="true" 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>
      <!-- Service that delivers messages from the phone "quick response" -->
      <service android:name="com.test.blocker.SmsSendService" android:enabled="true" 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>
   </application>
</manifest>

MessageActivity.java

public class MessageActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message);

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                
              if(!Telephony.Sms.getDefaultSmsPackage(getApplicationContext()).equals(getApplicationContext().getPackageName())) {
                    //Store default sms package name
                    Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
                    intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,
                            getApplicationContext().getPackageName());
                    startActivity(intent);
                }
            }
//code for sending sms and use ui 
}

PhoneStateReceiver.java

public class PhoneStateReceiver extends BroadcastReceiver {

 private String blockingNumber = "XX-XXX-XXXXX";

 @Override
 public void onReceive(final Context context, final Intent intent) {

  //blocking sms for matched number

  if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
   final String numberCall = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);;

   //reject call if number is matched to our blocking number 
   if (numberCall.equals(blockingNumber)) {
    disconnectPhoneItelephony(context);
   }
  }

  //blocking sms for matched number

  if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
   Bundle bundle = intent.getExtras();
   Object messages[] = (Object[]) bundle.get("pdus");
   SmsMessage smsMessage[] = new SmsMessage[messages.length];

   for (int n = 0; n < messages.length; n++) {
    smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
   }

   final String numberSms = smsMessage[0].getOriginatingAddress();
   //final String messageSms = smsMessage[0].getDisplayMessageBody();
   //long dateTimeSms = smsMessage[0].getTimestampMillis();

   //block sms if number is matched to our blocking number 
   if (numberSms.equals(blockingNumber)) {
    abortBroadcast();
   }
  }
 }
}
}

// Keep this method as it is @SuppressWarnings({ "rawtypes", "unchecked" }) 
private void disconnectPhoneItelephony(Context context) {
 try {
  String serviceManagerName = "android.os.ServiceManager";
  String serviceManagerNativeName = "android.os.ServiceManagerNative";
  String telephonyName = "com.android.internal.telephony.ITelephony";
  Class < ? > telephonyClass;
  Class < ? > telephonyStubClass;
  Class < ? > serviceManagerClass;
  Class < ? > serviceManagerNativeClass;
  Method telephonyEndCall;
  Object telephonyObject;
  Object serviceManagerObject;
  telephonyClass = Class.forName(telephonyName);
  telephonyStubClass = telephonyClass.getClasses()[0];
  serviceManagerClass = Class.forName(serviceManagerName);
  serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
  Method getService = // getDefaults[29]; 
   serviceManagerClass.getMethod("getService", String.class);
  Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
  Binder tmpBinder = new Binder();
  tmpBinder.attachInterface(null, "fake");
  serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
  IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
  Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
  telephonyObject = serviceMethod.invoke(null, retbinder);
  telephonyEndCall = telephonyClass.getMethod("endCall");
  telephonyEndCall.invoke(telephonyObject);
 } catch (Exception e) {
  e.printStackTrace();
 }
}
}

That’s it. I can’t event imagine how large source codes I have prepared for this article. While writing this article, I just built another SMS and call blocking app for android. Hurray!

Conclusion

I used this same mechanism to develop an application to block SMS in android as well as blocking call on Android. Thanks for reading the article. If you face any problem. Just write on comment box. Share this article in your social network and I will feel appreciated and honored. Don’t forget to read more articles on android.

Read more articles on Android

Get OAuth 2.0 access token using Retrofit 2.x

Retrofit is an awesome and easy to use library. You can use Retrofit for any…

Block SMS in Android Programmatically

There are lots of application out there who has the functionality to block call and…

Shaharia is a professional software engineer with more than 10 years of experience in the relevant fields. Digital ad certified, cloud platform architect, Big data enthusiasts, tech early adopters.