背景:
在开发全局搜索中,要求搜索短信内容。其中短信包含短信列表和会话列表。
要求显示短信头像、联系人名称、短信内容、时间等。
准备工作:
一开始以为直接查询短信数据库(Telephony.Sms.CONTENT_URI)就可以了,百度也有很多这种示例。实践之后才发现,这种查询只有收件箱能获取到号码,发件箱和草稿箱无法获取到号码。
之后再网上慢慢爬,终于在看到了希望的曙光。
查询会话列表(Telephony.Mms.CONTENT_URI),
然后根据thread_id查询短信列表(Telephony.Sms.CONTENT_URI),得到所有的短信内容。
再根据recipient_ids查询会话列表(Telephony.Mms.CONTENT_URI)这一步是为了循环拿到手机号码。
最后根据手机号码查询(ContactsContract.PhoneLookup.CONTENT_FILTER_URI)得到联系人头像和姓名。
到这里,已经拿到了所有的短信数据和会话数据。剩下的就是数据的组装和显示了。
代码:
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.Telephony;
import android.text.TextUtils;
import android.util.Log;
import com.techain.custompage.manager.CustomPageManager;
import com.techain.custompage.search.item.SmsItem;
import java.util.ArrayList;
/**
* Created by Administrator on 2017/10/13.
* 加载短信帮助类
*/
public class SmsHelp {
private static final String TAG="SmsHelp";
public static String THREAD_TYPE="1";
public static String SMS_TYPE="2";
private static class Thread_sms{
String boby;
String date;
public Thread_sms(String boby, String date) {
this.boby = boby;
this.date = date;
}
}
private static ArrayList<Thread_sms> thread_smsArrayList=new ArrayList<>();
/**
* 从mms数据库中检索threads表
*/
public static ArrayList<SmsItem> getMmsMessage(Context context) {
ContentResolver cr = context.getContentResolver();
ArrayList<SmsItem> threadDataList=new ArrayList<>();
ArrayList<SmsItem> smsDataList=new ArrayList<>();
Cursor cursor=null;
try {
cursor = cr.query(Telephony.Mms.CONTENT_URI,
new String[] { "* from threads--" }, null, null, null);
if (cursor!=null){
Log.i(TAG,"cursor: "+cursor.getCount());
while (cursor.moveToNext()) {
int thread_id = cursor.getColumnIndex(Telephony.Mms._ID);
int date = cursor.getColumnIndex(Telephony.Mms.DATE);
int message_count = cursor.getColumnIndex(Telephony.ThreadsColumns.MESSAGE_COUNT);
int snippet = cursor.getColumnIndex(Telephony.ThreadsColumns.SNIPPET);
int recipient = cursor.getColumnIndex(Telephony.ThreadsColumns.RECIPIENT_IDS);
//短信日期
String timeInMillis = cursor.getString(date);
//会话id
String threadId = cursor.getString(thread_id);
// 获得短信的各项内容
String[] phoneInfo = getPhoneInfo(context, threadId);
//手机号码
String phoneNum =phoneInfo[0];
//未读数量
String noReadCount=phoneInfo[1];
//最后的信息
String last_mms = cursor.getString(snippet);
//短信数量
String mmsCount = cursor.getString(message_count);
//收件人
String recipient_ids = cursor.getString(recipient);
String phoneNumNew = getCanonicalAddresses(context, recipient_ids);
if (TextUtils.isEmpty(phoneNum)&&!TextUtils.isEmpty(phoneNumNew)){
phoneNum=phoneNumNew;
}
// 判断是否联系人
String[] contactNameFromPhoneNum = getContactNameFromPhoneNum(context, phoneNum);
//联系人姓名
String contactName = contactNameFromPhoneNum[0];
//联系人头像id
String curPersonID=contactNameFromPhoneNum[1];
// 获得最后的未读短信与已读短信
String final_count = "(" + noReadCount + "/" + mmsCount + ")";
//会话列表添加数据
SmsItem smsItem_thread=new SmsItem();
smsItem_thread.setThread_id(threadId);
smsItem_thread.setType(THREAD_TYPE);
smsItem_thread.setDate(timeInMillis);
smsItem_thread.setSmsBody(last_mms);
smsItem_thread.setName(contactName);
smsItem_thread.setPhoneNumber(phoneNum);
smsItem_thread.setContactId(curPersonID);
//会话结果需要显示消息数量
smsItem_thread.setNoReadCount(noReadCount);
smsItem_thread.setMmsCount(mmsCount);
smsItem_thread.setFinalCount(final_count);
threadDataList.add(smsItem_thread);
Log.i(TAG," smsItem_thread: "+smsItem_thread.toString());
//短信列表添加数据
if (thread_smsArrayList!=null&&thread_smsArrayList.size()>0){
Log.w(TAG," thread_smsArrayList: "+thread_smsArrayList.size());
for (int i = 0; i <thread_smsArrayList.size() ; i++) {
Thread_sms thread_sms = thread_smsArrayList.get(i);
SmsItem smsItem_sms=new SmsItem();
smsItem_sms.setThread_id(threadId);
smsItem_sms.setType(SMS_TYPE);
//boby和date与会话列表不同
smsItem_sms.setDate(thread_sms.date);
smsItem_sms.setSmsBody(thread_sms.boby);
smsItem_sms.setName(contactName);
smsItem_sms.setPhoneNumber(phoneNum);
smsItem_sms.setContactId(curPersonID);
//短信不需要显示数量
// smsItem_thread.setNoReadCount(noReadCount);
// smsItem_thread.setMmsCount(mmsCount);
// smsItem_thread.setFinalCount(final_count);
smsDataList.add(smsItem_sms);
Log.d(TAG," smsItem_sms: "+smsItem_sms.toString());
}
//处理完后清除数据
thread_smsArrayList.clear();
Log.e(TAG," thread_smsArrayList.clear();: ");
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor!=null){
cursor.close();
}
}
//合并会话列表和短信列表后返回
if (smsDataList.size()>0){
threadDataList.addAll(smsDataList);
}
return threadDataList;
}
/**
*
* @param thread_id 根据thread_id 检索sms库, 获得对应的号码
* @return
*/
private static String[] getPhoneInfo(Context context,String thread_id) {
String PhoneNum = "";
int noRead_mms = 0;
String[] info=new String[]{"",""};
String[] projection = new String[] { Telephony.Sms.THREAD_ID,Telephony.Sms.ADDRESS,Telephony.Sms.READ,Telephony.Sms.BODY, Telephony.Sms.DATE};
Cursor cursor=null;
try {
cursor = context.getContentResolver().query(Telephony.Sms.CONTENT_URI, projection, Telephony.Sms.THREAD_ID+"=?",
new String[] { thread_id }, null);
if (cursor!=null){
while (cursor.moveToNext()) {
int phoneNumber = cursor.getColumnIndex(Telephony.Sms.ADDRESS);
int isRead = cursor.getColumnIndex(Telephony.Sms.READ);
if (cursor.getString(isRead).equals("0")) {
noRead_mms++;
}
PhoneNum = cursor.getString(phoneNumber);
int bodyIndex = cursor.getColumnIndex(Telephony.Sms.BODY);
int dateIndex = cursor.getColumnIndex(Telephony.Sms.DATE);
String body = cursor.getString(bodyIndex);
String date = cursor.getString(dateIndex);
Log.d(TAG," body: "+body+" date: "+date);
thread_smsArrayList.add(new Thread_sms(body,date));
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor!=null){
cursor.close();
}
}
info[0] = PhoneNum;
info[1] = String.valueOf(noRead_mms);
return info;
}
private static String getCanonicalAddresses(Context context,String recipient_ids) {
String[] ids = recipient_ids.split(" ");
String addressResult = "";
String PhoneNum="";
for (int i = 0; i < ids.length; i++) {
if (!TextUtils.isEmpty(ids[i])){
String id = ids[i];
Cursor cur=null;
try {
cur = context.getContentResolver().query(Telephony.Mms.CONTENT_URI,new String[] { " * from canonical_addresses where _id="+ id + " --" }, null, null, null);
if (cur!=null){
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String _id = cur.getString(cur.getColumnIndex("_id"));
String address = cur.getString(cur
.getColumnIndex("address"));
addressResult += "{" + _id + "," + address + "}";
if (!TextUtils.isEmpty(address)&&TextUtils.isEmpty(PhoneNum)){
PhoneNum=address;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cur!=null){
cur.close();
}
}
}
}
return PhoneNum;
}
/**
* 获取联系人信息
* @param context
* @param contactInfo
* @return
*/
private static String[] getContactNameFromPhoneNum(Context context, String contactInfo) {
String contactNames = "";
String[] info=new String[]{"",""};
Long curPersonID=-1L;
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, contactInfo);
Cursor cursor=null;
try {
cursor = context.getContentResolver().query(uri, null, null, null, null);
if (cursor!=null){
if (cursor.moveToFirst()) {
String contactName = cursor.getString(cursor
.getColumnIndex("display_name"));
curPersonID = cursor.getLong(cursor.getColumnIndex("_id"));
if (contactNames == "")
contactNames = contactName;
else
contactNames = contactNames + "," + contactName;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor!=null){
cursor.close();
}
}
info[0]=contactNames;
info[1]=String.valueOf(curPersonID);
return info;
}
}
后记:
初次接触短信模块,做的一塌糊涂。简单的记录一下,留着以后用。