Before I began coding Android apps, I was amazed how verification processes go like this: The Android app tells you they’ll send you an SMS containing verification code, and that you need to enter such code into a text field on the Android app. But when you receive the SMS, the verification code appears on the text field before you even type! I was like, whoa, how do they do that?
Now that I am able to develop simple Android apps, I already have an idea how it’s done.
We extend a class called BroadcastReceiver
and implement its onReceive()
method. This receiver is then registered either in the AndroidManifest.xml
file, or registered as needed in a .java
file (e.g., Activity
)
I’m registering mine in my MainActivity
file. I’ll provide the link to my project files on Github later on this page, but for now here’s what it looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
public class MainActivity extends AppCompatActivity { private SmsReceiver receiver; private TextView tv_sms_from; private TextView tv_sms_message; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_sms_from = (TextView) findViewById(R.id.tv_sms_from); tv_sms_message = (TextView) findViewById(R.id.tv_sms_message); receiver = new SmsReceiver(new Handler()); // create receiver registerReceiver(receiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED")); } public class SmsReceiver extends BroadcastReceiver { private SharedPreferences preferences; private String TAG = "SmsReceiver"; private final Handler handler; // for executing code on UI thread public SmsReceiver(Handler handler){ this.handler = handler; } @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){ Bundle bundle = intent.getExtras(); //---get the SMS message passed in--- SmsMessage[] msgs = null; if (bundle != null){ //---retrieve the SMS message received--- try{ Object[] pdus = (Object[]) bundle.get("pdus"); msgs = new SmsMessage[pdus.length]; for(int i=0; i<msgs.length; i++){ msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]); final String msgFrom = msgs[i].getOriginatingAddress(); final String msgBody = msgs[i].getMessageBody(); Log.d(TAG, "SMS Received! From: " + msgFrom + ", Message: " + msgBody); // post the UI-updating code to our Handler handler.post(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "SMS Received!", Toast.LENGTH_LONG).show(); tv_sms_from.setText("From: " + msgFrom); tv_sms_message.setText("Message: " + msgBody); } }); } } catch(Exception e){ Log.d("Exception caught",e.getMessage()); } } } } } } |
I first created a class called SmsReceiver which extends the BroadcastReceiver class that I mentioned earlier. Inside it, there’s an implemented method onReceive(), where we first check if the Intent’s action is android.provider.Telephony.SMS_RECEIVED
, otherwise we do nothing. We read message(s) that the Android devices just received and get the originating address (e.g. phone number of sender) and message body. Then lastly, the TextViews in the XML file are updated with the originating address and message body so you could see that thea app works.
By the way, I used a Handler in this app so that I could set the values of TextViews inside the MainActivity’s XML file. A new Handler object is passed from MainActivity.onCreate() to the SmsReceiver constructor. And later on once the message originating address and message body are available in BroadcastReceiver.onReceive(), we use the handler to “post” and set the TextView values.
Now, for the source files of this Android app…
Feel free to download my Android project files here: Android-Incoming-SMS-Reader
Resource:
http://stackoverflow.com/a/14648933