How to intercepting SMS on Android when the application Samsung ChatON is installed?
Categories:
Intercepting SMS on Android with Samsung ChatON Installed

Discover how to effectively intercept SMS messages on Android devices, even when applications like Samsung ChatON might interfere with standard BroadcastReceiver behavior.
Intercepting SMS messages on Android is a common requirement for many applications, such as parental control apps, security tools, or custom messaging clients. Traditionally, this is achieved using a BroadcastReceiver
that listens for the android.provider.Telephony.SMS_RECEIVED
action. However, certain pre-installed applications, like Samsung ChatON (now discontinued but representative of similar system-level apps), can alter this behavior, making standard interception methods unreliable. This article will explore the challenges posed by such applications and provide robust solutions to ensure your app can reliably intercept SMS messages.
Understanding SMS Broadcasts and Priority
When an SMS message is received, the Android system broadcasts an intent with the action android.provider.Telephony.SMS_RECEIVED
. Multiple BroadcastReceiver
components can register to listen for this intent. The order in which these receivers process the broadcast is determined by their android:priority
attribute defined in the AndroidManifest.xml
. A higher priority value means the receiver will be invoked earlier. Crucially, a receiver can consume the broadcast, preventing subsequent receivers from receiving it, by calling abortBroadcast()
.
flowchart TD A[SMS Received by Device] --> B{System Broadcasts SMS_RECEIVED Intent} B --> C{Receiver 1 (Highest Priority)} C -->|Calls abortBroadcast()| D[Other Receivers Blocked] C -->|Does NOT call abortBroadcast()| E{Receiver 2 (Next Priority)} E -->|Calls abortBroadcast()| D E -->|Does NOT call abortBroadcast()| F[...] F --> G[Default SMS App (Lowest Priority)] G --> H[SMS Stored in Inbox]
SMS Broadcast Flow and Priority Mechanism
Applications like Samsung ChatON often register a BroadcastReceiver
with a very high priority (e.g., android:priority="999"
) and might call abortBroadcast()
if they deem the message relevant to their functionality. This effectively 'steals' the SMS, preventing other applications, including your own, from receiving the broadcast. To overcome this, your application's receiver must have an even higher priority.
Implementing a High-Priority SMS Receiver
To ensure your application intercepts SMS messages before other high-priority apps, you need to declare your BroadcastReceiver
with a priority value greater than theirs. The maximum priority value allowed is 2147483647
(Integer.MAX_VALUE), but a value like 1000
is usually sufficient to override most pre-installed apps. After processing the SMS, you can choose to either consume it (preventing other apps from seeing it) or allow it to propagate to lower-priority receivers.
<receiver android:name=".SmsReceiver" android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
public class SmsReceiver extends BroadcastReceiver {
private static final String TAG = "SmsReceiver";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus != null) {
for (Object pdu : pdus) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
String sender = smsMessage.getDisplayOriginatingAddress();
String messageBody = smsMessage.getMessageBody();
Log.d(TAG, "SMS from: " + sender + ", Body: " + messageBody);
// IMPORTANT: Decide whether to abort the broadcast
// If you want to consume the SMS and prevent other apps from seeing it:
// this.abortBroadcast();
// If you want other apps (like the default SMS app) to also receive it:
// Do NOT call abortBroadcast();
}
}
}
}
}
}
android:priority
values above 999
is generally discouraged by Google, as it can lead to unexpected behavior and interfere with the user's default messaging experience. Use this approach judiciously and only when absolutely necessary, providing clear user consent and explanation.Required Permissions
For your application to receive SMS broadcasts, you must declare the RECEIVE_SMS
permission in your AndroidManifest.xml
. Additionally, if you intend to send SMS messages, you'll need SEND_SMS
. For Android 6.0 (API level 23) and higher, RECEIVE_SMS
is a dangerous permission, meaning users must explicitly grant it at runtime.
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
Runtime Permission Request Example
Here's a basic example of how to request the RECEIVE_SMS
permission at runtime in an Activity.
import android.Manifest;
import android.content.pm.PackageManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int SMS_PERMISSION_CODE = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkSmsPermission();
}
private void checkSmsPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECEIVE_SMS}, SMS_PERMISSION_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == SMS_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "SMS permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "SMS permission denied", Toast.LENGTH_SHORT).show();
}
}
}
}
By combining a high-priority BroadcastReceiver
with proper runtime permission handling, your application can reliably intercept SMS messages on Android, even when other system-level applications are present. Remember to always prioritize user experience and transparency when implementing such features.