Android应用如何实现仅接收特定号码的SMS消息?
Alright, let's walk through how to tweak your Android Authority-based SMS app to only handle messages from that specific number (07911 127456). We'll focus on two core parts: filtering incoming SMS via the BroadcastReceiver, and ensuring only that target conversation displays in your inbox.
Your existing BroadcastReceiver is probably picking up all incoming SMS. We need to add a check to only process messages from your target number—and abort processing for everything else.
First, standardize the target number (remove spaces, hyphens, etc.) to avoid mismatches (since carriers might send sender numbers in different formats). Here's the adjusted receiver code:
public class SmsReceiver extends BroadcastReceiver { // Define your target number, cleaned of non-digit/non-+ characters private static final String TARGET_PHONE_NUMBER = "07911127456"; @Override public void onReceive(Context context, Intent intent) { if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) { Bundle bundle = intent.getExtras(); if (bundle == null) return; Object[] pdus = (Object[]) bundle.get("pdus"); if (pdus == null) return; for (Object pdu : pdus) { SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu); String senderNumber = smsMessage.getOriginatingAddress(); if (senderNumber == null) continue; // Clean both sender and target numbers to ensure consistent matching String cleanedSender = senderNumber.replaceAll("[^0-9+]", ""); String cleanedTarget = TARGET_PHONE_NUMBER.replaceAll("[^0-9+]", ""); // If this isn't our target number, stop processing right away if (!cleanedSender.equals(cleanedTarget)) { abortBroadcast(); return; } // Proceed with your existing logic to save/display the valid message String messageBody = smsMessage.getMessageBody(); // ... your original code to handle the SMS (e.g., insert into local DB, update UI) } } } }
Key Notes:
abortBroadcast()stops other components (including your own app's inbox) from processing non-target messages. Keep in mind that on Android 8.0+, statically registered receivers can't listen forSMS_RECEIVED_ACTION—you'll need to use dynamic registration (more on that below).- Always clean phone numbers before comparing to avoid issues with formatting differences (e.g.,
+447911127456vs07911 127456).
Next, you need to make sure your app's inbox only loads messages from the target number. Adjust your ContentResolver query to add a filter on the sender address:
// Clean the target number first for precise matching String cleanedTarget = TARGET_PHONE_NUMBER.replaceAll("[^0-9+]", ""); // Query only messages from the target number String selection = Telephony.Sms.ADDRESS + " LIKE ?"; // Use % wildcards if you want to match numbers with prefixes (e.g., international codes) String[] selectionArgs = new String[]{"%" + cleanedTarget + "%"}; Cursor cursor = getContentResolver().query( Telephony.Sms.CONTENT_URI, null, selection, selectionArgs, Telephony.Sms.DATE + " DESC" // Sort newest first ); // Load only these filtered messages into your RecyclerView/ListView
If you want an exact match (no wildcards), replace the selection with:
String selection = "REPLACE(" + Telephony.Sms.ADDRESS + ", '[^0-9+]', '') = ?"; String[] selectionArgs = new String[]{cleanedTarget};
This uses SQLite's REPLACE function to clean the stored address on the fly before comparing.
Dynamic Broadcast Registration (Android 8.0+)
Static BroadcastReceivers for SMS_RECEIVED_ACTION don't work on Android 8.0+. Instead, register the receiver dynamically in your main Activity or Service:
private SmsReceiver smsReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Register the receiver dynamically smsReceiver = new SmsReceiver(); IntentFilter smsFilter = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION); // Set high priority to intercept messages before other apps smsFilter.setPriority(1000); registerReceiver(smsReceiver, smsFilter); } @Override protected void onDestroy() { super.onDestroy(); // Unregister to avoid memory leaks unregisterReceiver(smsReceiver); }
Permissions
Ensure your app has the necessary permissions in AndroidManifest.xml, and request them at runtime for Android 6.0+:
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" />
- Test with different number formats (e.g.,
+447911127456,07911-127456) to confirm your cleaning logic works. - Send a message from a non-target number to verify it doesn't show up in your app.
- If your app is set as the default SMS app, you'll need to handle
SMS_DELIVER_ACTIONinstead ofSMS_RECEIVED_ACTION—adjust the intent filter accordingly.
内容的提问来源于stack exchange,提问作者Venda

