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

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

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

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

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

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

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

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

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

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

   

  1. //---add by antoon
  2. private Cursor getMsgSearchResult(Uri uri, SQLiteDatabase db) {
  3. String keyStr = uri.getQueryParameter("key_str");
  4. String addressStr = uri.getQueryParameter("addressStr");
  5. Log.i("antoon", LOG_TAG + " , keyStr = " + keyStr);
  6. Log.i("antoon", LOG_TAG + " , addressStr = " + addressStr);
  7.  
  8. String threadIdString = getSearchedThreadIdString(addressStr);
  9. Log.i("antoon", LOG_TAG + " , threadIdString = " + threadIdString);
  10.  
  11. String searchString = "%" + addEscapeCharacter(keyStr) + "%";
  12. Log.i("antoon", LOG_TAG + " , searchString = " + searchString);
  13.  
  14. Cursor cursor;
  15. if(DEFAULT_STRING_ZERO.equals(threadIdString)){
  16. cursor = getSmsMmsSearchContent(searchString);
  17. }else {
  18. Cursor cursorThread = getSearchedThreadIds(threadIdString);
  19. Cursor cursorMsg = getSmsMmsSearchContent(searchString);
  20. cursor = new MergeCursor(new Cursor[]{cursorThread, cursorMsg});
  21. }
  22. return cursor;
  23. }
  24.  
  25. private String getSearchedThreadIdString(String keyStr) {
  26. String[] addresses = keyStr.split(",");
  27. int count = addresses.length;
  28. Set<Long> result = new HashSet<Long>(count);
  29.  
  30. for (int i = 0; i < count; i++) {
  31. String address = addresses[i];
  32. if (address != null && !address.equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
  33. Set<Long> ids = getThreadIdsByAddress(address);
  34. if (ids != null) {
  35. result.addAll(ids);
  36. } else {
  37. Log.e(LOG_TAG, "Address ID not found for: " + address);
  38. }
  39. }
  40. }
  41. long[] addressIdSet = getSortedSet(result);
  42. String threadIdString = getCommaSeparatedId(addressIdSet);
  43. if (TextUtils.isEmpty(threadIdString)) {
  44. threadIdString = DEFAULT_STRING_ZERO;
  45. }
  46. return threadIdString;
  47. }
  48.  
  49. private Set<Long> getThreadIdsByAddress(String address) {
  50. String searchString = "%" + addEscapeCharacter(address) + "%";
  51.  
  52. boolean isEmail = Mms.isEmailAddress(address);
  53. String refinedAddress = isEmail ? address.toLowerCase() : address;
  54. String selection = "address LIKE ?";
  55. String[] selectionArgs;
  56.  
  57. if (isEmail) {
  58. selectionArgs = new String[] { refinedAddress };
  59. } else {
  60. selection += " OR " + String.format("PHONE_NUMBERS_EQUAL(address, ?, %d)",
  61. (mUseStrictPhoneNumberComparation ? 1 : 0));
  62. selectionArgs = new String[] { searchString, refinedAddress };
  63. }
  64.  
  65. Cursor cursor = null;
  66. Set<Long> addressIds = new HashSet<Long>();
  67. try {
  68. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  69. cursor = db.query(
  70. "canonical_addresses", ID_PROJECTION,
  71. selection, selectionArgs, null, null, null);
  72. if (cursor.getCount() == 0) {
  73. return null;
  74. }
  75. while(cursor.moveToNext()){
  76. addressIds.add(cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)));
  77. }
  78.  
  79. } finally {
  80. if (cursor != null) {
  81. cursor.close();
  82. }
  83. }
  84.  
  85. return addressIds;
  86. }
  87.  
  88. private synchronized Cursor getSearchedThreadIds(String threadIdString) {
  89. String THREAD_QUERY = String.format(
  90. "SELECT %s FROM threads WHERE (_id in (%s))",
  91. THREADS_PROJECTION,
  92. threadIdString);
  93. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  94. return db.rawQuery(THREAD_QUERY, EMPTY_STRING_ARRAY);
  95. }
  96.  
  97. private synchronized Cursor getSmsMmsSearchContent(String keyStr) {
  98. String smsQuery = String.format(
  99. "SELECT %s FROM sms WHERE (body LIKE ? ESCAPE '" +
  100. SEARCH_ESCAPE_CHARACTER + "') ",
  101. SMS_CONTENT_PROJECTION);
  102.  
  103. String mmsContentQuery = String.format(Locale.US,
  104. "SELECT %s FROM pdu,part,addr WHERE ((part.mid=pdu._id) AND " +
  105. "(addr.msg_id=pdu._id) AND " +
  106. "(addr.type=%d) AND " +
  107. "(part.ct='text/plain') AND " +
  108. "(body like ? escape '" + SEARCH_ESCAPE_CHARACTER + "')) GROUP BY pdu._id",
  109. MMS_CONTENT_PROJECTION,
  110. PduHeaders.TO);
  111.  
  112. String mmsSubjectQuery = String.format(
  113. "SELECT %s FROM pdu,addr WHERE (" +
  114. "(addr.msg_id = pdu._id) AND (addr.type=%d) AND " +
  115. "(body like ? escape '" + SEARCH_ESCAPE_CHARACTER + "')) GROUP BY pdu._id",
  116. MMS_SUBJECT_PROJECTION,
  117. PduHeaders.TO);
  118.  
  119. String rawQuery = String.format(
  120. "%s UNION %s UNION %s ORDER BY date ASC",
  121. smsQuery, mmsContentQuery, mmsSubjectQuery);
  122.  
  123. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  124. return db.rawQuery(rawQuery, new String[] {keyStr,keyStr,keyStr});
  125. }
  126.  
  127. public static final String THREADS_PROJECTION =
  128. "'thread' AS transport_type, _id, recipient_ids, message_count, date";
  129. //下面三个查询字段个数一样,字段名称也一样
  130. private static final String SMS_CONTENT_PROJECTION =
  131. "'sms' AS transport_type, _id, address, body, date";
  132. private static final String MMS_CONTENT_PROJECTION =
  133. "'mms' AS transport_type, pdu._id, addr.address AS address, part.text as body,"
  134. + "pdu.date * 1000 AS date";
  135.  
  136. private static final String MMS_SUBJECT_PROJECTION =
  137. "'mms' AS transport_type, pdu._id, addr.address AS address, pdu.sub as body, "
  138. + "pdu.date * 1000 AS date";
  139. //---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. python---常见的数据队列

    一.FIFO队列(先进先出) #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'zhoufeng' #FIFO队列 import q ...

  2. (转)深入理解javascript连续赋值表达式

    引入 今天逛园子的时候看到一道javascript面试题,是关于连续赋值的,正好最近读jQuery源码经常看到这种连续赋值的表达式,所以很感兴趣. 废话不多说,来看题: var a = {n: 1} ...

  3. C# ADO.NET (sql语句连接方式)(查询)

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  4. awk实现join

    awk 有时确实比较省事,做些简单的文本处理,还是很方便的,在这介绍下两个文件的join的操作. 原始文本 bb.txt a 10 b 12 cc.txt a 11 b 13 c 15 awk joi ...

  5. Hibernate和Struts2整合的增、删、改、查

    1. 新建一个Web项目,准备好jar包和配置文件. 2. web.xml文件中添加过滤器 <?xml version="1.0" encoding="UTF-8& ...

  6. EntityFrameWork 使用时碰到的小问题

    EntityFrameWork 使用时碰到的小问题 1,在使用orm访问数据库的相目里,也要引用EntityFrameWork.dll,否则无法使用orm 否则,编译错误 错误 5 "Sys ...

  7. ActiveMQ学习笔记(5)——使用Spring JMS收发消息

      摘要 ActiveMQ学习笔记(四)http://my.oschina.net/xiaoxishan/blog/380446 中记录了如何使用原生的方式从ActiveMQ中收发消息.可以看出,每次 ...

  8. javascript验证香港身份证

    var assert = require('assert'); describe('test', function() { it('coc', function() { var testCard01 ...

  9. ajax data传值

    如果要我们要把整个form1表单中的输入框都传过去可以用data:$("#form1").serialize(), 但是我们如果还要传一个不在form中的值呢? 可以使用下面这种方 ...

  10. 微信公众平台开发 微信JSSDK开发

    根据微信开发文档步骤如下: 1.先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”. JS接口安全域名设置 mi.com(前面不用带www/http,域名必须备案过) 2.引 ...