1

My actual code blocks calls perfectly but now I want to identify an incoming SMS number ID and do stuff, like mark as read or whatever ( like Medium and this one ).

I've read a couple articles and threads but it's not even getting the intent, note again that this code works perfectly blocking calls so I'll paste the SMS related information

Manifest.xml

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

<service android:name=".CallReceiverService" />

Service with Broadcast receiver

@Override
public void onCreate() {
    super.onCreate();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);

        Notification notification = new Notification.Builder(this, SERVICE_CHANNEL_ID)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentText(this.getResources().getString(R.string.stg_ServiceRunning))
                .setContentIntent(pendingIntent)
                .setCategory(Notification.CATEGORY_CALL)
                .build();

        startForeground(44332255, notification);
    }

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("android.intent.action.PHONE_STATE"); // related to call feature, ignore
    intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
    intentFilter.addAction("Telephony.Sms.Intents.SMS_RECEIVED_ACTION");
    intentFilter.setPriority(1000);
    registerReceiver(callCheckReceiver, intentFilter);
}


private BroadcastReceiver callCheckReceiver = new BroadcastReceiver() {

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

        try {
            if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
                Log.d("Call", "SMS received");
                String smsSender = "";
                if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
                    Log.d("Call", "SMS received");
                    String smsSender = "";
                    for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
                        smsSender = smsMessage.getDisplayOriginatingAddress();
                    }

                    if (!isValidPhoneNumber(smsSender)) {
                        Log.d("Call", "Invalid SMS detected: From " + smsSender);
                    }
                }
                if (!isValidPhoneNumber(smsSender)) {
                    Log.d("Call", "Invalid SMS detected: From " + smsSender);
                }
            }

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

};

public static boolean isValidPhoneNumber(String phoneNumber) {
    return android.util.Patterns.PHONE.matcher(phoneNumber).matches();
}

Basically I'm asking the permission in MainActivity, setting them in Manifest and passing the FilterIntent in the Service that IS properly called in Oreo or lower versions of Android. Target API >=19

I don't want to build an app to manage SMS, I just want to intercept the number ID and do things. Can someone advise?

FilipeOS
  • 801
  • 1
  • 11
  • 42

1 Answers1

0

What you need is SMS Retriever API

If you want to detect the SMS, you can simply use

    SmsRetrieverClient client = SmsRetriever.getClient(this /* context */);
    Task<Void> task = client.startSmsRetriever();
    task.addOnSuccessListener(new OnSuccessListener<Void>()
    {
        @Override
        public void onSuccess(Void aVoid)
        {
            // Successfully started retriever, expect broadcast intent
            // ...
        }
    });

    task.addOnFailureListener(new OnFailureListener()
    {
        @Override
        public void onFailure(@NonNull Exception e)
        {
            // Failed to start retriever, inspect Exception for more details
            // ...
        }
    });

In AndroidManifest.xml simply add receiver

    <receiver
        android:name=".custom.SMSBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
        </intent-filter>
    </receiver>

Within receiver you can do whatever you want with detected message

    public class SMSBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction()))
        {
            Bundle extras = intent.getExtras();
            Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
            switch (status.getStatusCode())
            {
                case CommonStatusCodes.SUCCESS:
                    // Get SMS message contents
                    String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
                    // Extract one-time code from the message and complete verification
                    // by sending the code back to your server for SMS authenticity.




                    break;
                case CommonStatusCodes.TIMEOUT:
                    // Waiting for SMS timed out (5 minutes)
                    // Handle the error ...
                    break;

            }
        }
    }
}

It should be noted that SMSRetrieverClient default timeout is 5 minutes.

For creating detectable SMS please follow SMS Creator for Google

Muhammad Umar
  • 11,391
  • 21
  • 91
  • 193
  • This is not what I'm looking for but thanks. I don't want to use any validation or whatever, I think you didn't read properly my question. – FilipeOS Jul 18 '18 at 14:59
  • I read it again now . I will check the code tomorrow. I hope I will be able to help – Muhammad Umar Jul 18 '18 at 17:02