高通平台的MMS源码中提供了搜索功能,但要先选择分类(名字,号码,信息内容,彩信主题),再输入字符,根据分类进行搜索。

而在Contacts中却不需要分类,直接根据输入字符搜索任意匹配字段。相比之下,MMS搜索功能繁琐,用户体验不好。

那么我们来修改一下代码,实现MMS搜索,自动匹配任意字段吧

分析:查看代码TelephonyProvider\src\com\android\providers\telephony\MmsSmsProvider.java中,

   从搜索语句sql设计看:名字和号码的搜索属于一类, 信息内容和主题搜索属于一类。

             (名字搜索——先根据名字查询对应号码,再根据号码搜索会话)

   从搜索结果看:名字和号码的搜索结果为thread表, 信息内容和主题搜索的结果为sms/mms表

   具体设计:输入一个字符,可能是名字,也可能是号码,也可能是内容,也可能是主题。所以需要针对每种类型分别搜索,然后将结果合并。

        对于名字和号码,在where语句中用or分别匹配;

对于短信/彩信内容和彩信主题搜索,用UNION将三个sql组合(因为查询字段个数一样,可以取同样的别名)

   

//---add by antoon
private Cursor getMsgSearchResult(Uri uri, SQLiteDatabase db) {
String keyStr = uri.getQueryParameter("key_str");
String addressStr = uri.getQueryParameter("addressStr");
Log.i("antoon", LOG_TAG + " , keyStr = " + keyStr);
Log.i("antoon", LOG_TAG + " , addressStr = " + addressStr); String threadIdString = getSearchedThreadIdString(addressStr);
Log.i("antoon", LOG_TAG + " , threadIdString = " + threadIdString); String searchString = "%" + addEscapeCharacter(keyStr) + "%";
Log.i("antoon", LOG_TAG + " , searchString = " + searchString); Cursor cursor;
if(DEFAULT_STRING_ZERO.equals(threadIdString)){
cursor = getSmsMmsSearchContent(searchString);
}else {
Cursor cursorThread = getSearchedThreadIds(threadIdString);
Cursor cursorMsg = getSmsMmsSearchContent(searchString);
cursor = new MergeCursor(new Cursor[]{cursorThread, cursorMsg});
}
return cursor;
} private String getSearchedThreadIdString(String keyStr) {
String[] addresses = keyStr.split(",");
int count = addresses.length;
Set<Long> result = new HashSet<Long>(count); for (int i = 0; i < count; i++) {
String address = addresses[i];
if (address != null && !address.equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
Set<Long> ids = getThreadIdsByAddress(address);
if (ids != null) {
result.addAll(ids);
} else {
Log.e(LOG_TAG, "Address ID not found for: " + address);
}
}
}
long[] addressIdSet = getSortedSet(result);
String threadIdString = getCommaSeparatedId(addressIdSet);
if (TextUtils.isEmpty(threadIdString)) {
threadIdString = DEFAULT_STRING_ZERO;
}
return threadIdString;
} private Set<Long> getThreadIdsByAddress(String address) {
String searchString = "%" + addEscapeCharacter(address) + "%"; boolean isEmail = Mms.isEmailAddress(address);
String refinedAddress = isEmail ? address.toLowerCase() : address;
String selection = "address LIKE ?";
String[] selectionArgs; if (isEmail) {
selectionArgs = new String[] { refinedAddress };
} else {
selection += " OR " + String.format("PHONE_NUMBERS_EQUAL(address, ?, %d)",
(mUseStrictPhoneNumberComparation ? 1 : 0));
selectionArgs = new String[] { searchString, refinedAddress };
} Cursor cursor = null;
Set<Long> addressIds = new HashSet<Long>();
try {
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
cursor = db.query(
"canonical_addresses", ID_PROJECTION,
selection, selectionArgs, null, null, null);
if (cursor.getCount() == 0) {
return null;
}
while(cursor.moveToNext()){
addressIds.add(cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)));
} } finally {
if (cursor != null) {
cursor.close();
}
} return addressIds;
} private synchronized Cursor getSearchedThreadIds(String threadIdString) {
String THREAD_QUERY = String.format(
"SELECT %s FROM threads WHERE (_id in (%s))",
THREADS_PROJECTION,
threadIdString);
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
return db.rawQuery(THREAD_QUERY, EMPTY_STRING_ARRAY);
} private synchronized Cursor getSmsMmsSearchContent(String keyStr) {
String smsQuery = String.format(
"SELECT %s FROM sms WHERE (body LIKE ? ESCAPE '" +
SEARCH_ESCAPE_CHARACTER + "') ",
SMS_CONTENT_PROJECTION); String mmsContentQuery = String.format(Locale.US,
"SELECT %s FROM pdu,part,addr WHERE ((part.mid=pdu._id) AND " +
"(addr.msg_id=pdu._id) AND " +
"(addr.type=%d) AND " +
"(part.ct='text/plain') AND " +
"(body like ? escape '" + SEARCH_ESCAPE_CHARACTER + "')) GROUP BY pdu._id",
MMS_CONTENT_PROJECTION,
PduHeaders.TO); String mmsSubjectQuery = String.format(
"SELECT %s FROM pdu,addr WHERE (" +
"(addr.msg_id = pdu._id) AND (addr.type=%d) AND " +
"(body like ? escape '" + SEARCH_ESCAPE_CHARACTER + "')) GROUP BY pdu._id",
MMS_SUBJECT_PROJECTION,
PduHeaders.TO); String rawQuery = String.format(
"%s UNION %s UNION %s ORDER BY date ASC",
smsQuery, mmsContentQuery, mmsSubjectQuery); SQLiteDatabase db = mOpenHelper.getReadableDatabase();
return db.rawQuery(rawQuery, new String[] {keyStr,keyStr,keyStr});
} public static final String THREADS_PROJECTION =
"'thread' AS transport_type, _id, recipient_ids, message_count, date";
//下面三个查询字段个数一样,字段名称也一样
private static final String SMS_CONTENT_PROJECTION =
"'sms' AS transport_type, _id, address, body, date";
private static final String MMS_CONTENT_PROJECTION =
"'mms' AS transport_type, pdu._id, addr.address AS address, part.text as body,"
+ "pdu.date * 1000 AS date"; private static final String MMS_SUBJECT_PROJECTION =
"'mms' AS transport_type, pdu._id, addr.address AS address, pdu.sub as body, "
+ "pdu.date * 1000 AS date";
//---end add

MMS搜索功能修改的更多相关文章

  1. idea 光标变成粗体且当前文件搜索功能无法使用的问题

    今天安装了idea最新版,安装完成后发现光标变成了粗体,并且快捷键在使用时出现了问题,比如:ctrl+F搜索功能无法使用 经过反复修改配置也无法改善情况,后来一次重启看到下面小窗弹出有关vim的一个提 ...

  2. ILSpy搜索功能加强版

    1.修改搜索功能,增加如下的额外搜索选项 A.按文本搜索(默认选项) B.按通配符搜索 C.按正则表达式搜索 2.搜索增加如下特性: A.可以按照名字空间检索特定名字空间下的所有类. B.修正了官方版 ...

  3. PHP+mysql数据库开发搜索功能:中英文分词+全文检索(MySQL全文检索+中文分词(SCWS))

    PHP+mysql数据库开发类似百度的搜索功能:中英文分词+全文检索 中文分词: a)   robbe PHP中文分词扩展: http://www.boyunjian.com/v/softd/robb ...

  4. yii2组件之下拉框带搜索功能(yii-select2)

    简单的小功能,但是用起来还是蛮爽的.分享出来让更多的人有更快的开发效率,开开心心快乐编程. 如果你还没有使用过composer,你可就out了,看我的教程分享,composer简直就是必备神奇有木有. ...

  5. 简单三步-实现dede站内搜索功能

    第一步:找到对应的搜索模板的代码 我们都知道,dede有自带的搜索功能,我们只要找到对应的模板,然后把我们想要的代码拿出来就行了.具体如下: 首先进入templets-->default--&g ...

  6. mac 功能修改。。。。

    个人表示 Mac 下的 Spotlight 搜索功能确实是个鸡肋,安装 QuickSilver 才是王道!所以我个人就把 Spotlight 关闭掉了.方法很简单,还是要用到 “终端” 工具. 在 “ ...

  7. 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能

    package com.jadyer.lucene; import java.io.File; import java.io.IOException; import java.text.SimpleD ...

  8. 关于ligerui 中 grid 表格的扩展搜索功能在远程数据加载时无法使用的解决办法

    要想使用grid里的扩展搜索功能,除了要引用ligerui主要的js文件外,还必须引入下面的JS文件: 1.Source\demos\filter\ligerGrid.showFilter.js 2. ...

  9. PHPCMS快速建站系列之搜索功能

    默认模板的搜索功能代码 <div class="bd"> <form action="{APP_PATH}index.php" method= ...

随机推荐

  1. Ubuntu 14.04下搭建 Android 开发环境(1) -JDK安装

    1.下载最新的jdk安装,地址:http://www.oracle.com/technetwork/java/javase/downloads/ 2.解压jdk-8u20-linux-x64.gz,我 ...

  2. SpringMVC学习笔记(一)

    一.MVC的流程图 分析流程图 1. 首先用户发送请求---->前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分:图 ...

  3. JS实现关闭当前子窗口,刷新父窗口

    一.JS实现关闭当前子窗口,刷新父窗口 JS代码如下: <script> function refreshParent() {  window.opener.location.href = ...

  4. Idea安装及简单配置

    1. 安装JDK   设置环境变量   JAVA_HOME    C:\Program Files\Java\jdk1.8.0_45   CLASSPATH    .;%JAVA_HOME%\lib; ...

  5. PHP文件缓存实现

    有些时候,我们不希望使用redis等第三方缓存,使得系统依赖于其他服务.这时候,文件缓存会是一个不错的选择. 我们需要文件缓存实现哪些共更能: 功能实现:get.set.has.increment.d ...

  6. Easyui表单之下拉列表的三级联动

    一.实现三级联动需要连接数据库 二.需要JSON数据的解析 三.需要Servlet类与界面相对应值的传递 1. 界面层需要的代码如下: <!DOCTYPE html> <html&g ...

  7. SQL初级语法 [查询: SELECT]

    SQL查询: SELECT 普通查询: SELECT "栏位名" FROM "表格名" DISTINCT 查询:(去掉重复) SELECT DISTINCT & ...

  8. Windows服务二:测试新建的服务、调试Windows服务

    一.测试Windows服务 为了使Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点.像其他应用程序一样,Windows服务也是在Program.cs的Main ...

  9. 建筑材料系统 ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout 的架构设计开发

    框架介绍: 1.基于 ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout 的架构设计开发 2.采用MVC的框架模式,具有耦合性低.重用性高.生命周期成本低.可维护性 ...

  10. chrome 点击上传文件选择框会延迟几秒才会显示 反应很慢

    chrome52.0.2743.80以上, accept: { title: 'Images', extensions: 'jpg,jpeg,png', mimeTypes: 'image/*' } ...