这是我获取短信的方式。它可以获取当前消息的正文、内容、日期以及检查它是传入还是传出。此外,它还可以通过其他方法获取与电话号码匹配的联系人姓名。
首先,为 AndroidManifest.xml 文件添加权限。
<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>
其次,实现 SMS Observer 类来获取你需要的信息
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;
}
}
如果设备运行 Android 6.0(API 级别 23)且应用的目标 SdkVersion 为 23 或更高版本,则短信权限将被视为危险权限。因此,您必须事先获得正确的许可。
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;
}
最后,在 HomeActivity 类或任何其他 Activity 类中实例化 SMSObserver 类。
//sms log
smsObserver = new SMSObserver(new Handler(), getApplicationContext());
getContentResolver().registerContentObserver(Telephony.Sms.CONTENT_URI, true, smsObserver);