This is my way of getting the SMS. It can get body, content, date of the current message as well as check if it is incoming or outgoing. In addition, it can get the contact name that matches the phone number by another method.
First of all, add permission to AndroidManifest.xml file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.app.myapp" >
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
...
</manifest>
Secondly, implement SMS Observer class to get the information you need
public class SMSObserver extends ContentObserver {
private Context context;
private static final String TAG = "SMSObserver";
private static final Uri SMS_URI = Telephony.Sms.CONTENT_URI; //get uri depending on different devices
public SMSObserver(Handler handler, Context context) {
super(handler);
this.context = context;
}
@Override
public boolean deliverSelfNotifications() {
return true;
}
//this onChange method will be fired up when you send or receive message
@Override
public void onChange(boolean selfChange) {
Cursor cursor = context.getContentResolver().query(SMS_URI, null, null, null, Telephony.Sms.DATE + " DESC");
String phNumber = null;
//make sure there is a message being operating
if (cursor != null && cursor.moveToFirst()) {
try {
//the meanings of those variables are quite straight forward
String type = cursor.getString(cursor.getColumnIndex(Telephony.Sms.TYPE));
String content = cursor.getString(cursor.getColumnIndex(Telephony.Sms.BODY));
String date = cursor.getString(cursor.getColumnIndex(Telephony.Sms.DATE));
Date SMSDate = new Date(Long.valueOf(date));
phNumber = cursor.getString(cursor.getColumnIndex(Telephony.Sms.ADDRESS)); //this is phone number rather than address
String contact = getContactDisplayNameByNumber(phNumber); //call the metod that convert phone number to contact name in your contacts
int typeCode = Integer.parseInt(type);
String direction = "";
//get the right direction
switch (typeCode) {
case Telephony.Sms.MESSAGE_TYPE_INBOX:
direction = "INCOMING";
break;
case Telephony.Sms.MESSAGE_TYPE_OUTBOX:
direction = "OUTGOING";
break;
case Telephony.Sms.MESSAGE_TYPE_SENT:
direction = "SENT";
break;
default:
direction = "UNKNOWN";
Log.e(TAG, typeCode + " is unknown");
break;
}
} catch (CursorIndexOutOfBoundsException e) {
Log.e(TAG, "SMSHelper: outgoingSMS", e);
} finally {
cursor.close();
}
}
Toast.makeText(context, "\nName: " + contact + "\nPhone Number:--- " + phNumber + " \nContent:--- "
+ content + " \nCall Date:--- " + SMSDate
+ " Direction: " + direction, Toast.LENGTH_LONG).show();
Log.i(TAG, "\nName: " + contact + "\nPhone Number:--- " + phNumber + " \nContent:--- "
+ content + " \nCall Date:--- " + SMSDate
+ " Direction: " + direction + "\n----------------------------------");
super.onChange(selfChange);
}
/**
* http://stackoverflow.com/questions/3712112/search-contact-by-phone-number
* Look up phone number
*
* @param number phone number
* @return the name matched with the phone number
*/
private String getContactDisplayNameByNumber(String number) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String name = "<Not in contact list>";
ContentResolver contentResolver = context.getContentResolver();
Cursor contactLookup = contentResolver.query(uri, new String[]{BaseColumns._ID, ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
try {
if (contactLookup != null && contactLookup.getCount() > 0) {
contactLookup.moveToFirst();
name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
//String contactId = contactLookup.getString(contactLookup.getColumnIndex(BaseColumns._ID));
Log.i(TAG, "Found number in contacts: " + number + " = " + name);
} else {
Log.e(TAG, "Cursor is null or empty " + number + " not found in contacts");
}
} finally {
if (contactLookup != null) {
contactLookup.close();
}
}
return name;
}
}
If the device is on running Android 6.0 (API level 23) and the
app's target SdkVersion is 23 or higher, the SMS permission will be
considered as dangerous permission. Therefore you must get the right
permission beforehand .
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED
&&ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
//grant permission
ActivityCompat.requestPermissions( this,
new String[]{Manifest.permission.READ_CONTACTS,Manifest.permission.READ_SMS},
10);
return;
}
Lastly, instantiate the SMSObserver class in the HomeActivity class or any
other Activity classes.
//sms log
smsObserver = new SMSObserver(new Handler(), getApplicationContext());
getContentResolver().registerContentObserver(Telephony.Sms.CONTENT_URI, true, smsObserver);