MMS搜索功能修改

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MMS搜索功能修改相关的知识,希望对你有一定的参考价值。

高通平台的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搜索功能修改的主要内容,如果未能解决你的问题,请参考以下文章

Android 短信模块分析 MMS数据库定义及结构整理

7.11做pdsdt狮虎给的旧题mms协议分析

git 怎么查看一个文件修改的内容

Android系统修改之展讯平台的Mms不能发送西班牙特殊字符ú的问题

Mms编辑短信时候联系人重复或者无效则删除解决方案

手机端ios和android浏览器 如何实现mms广播电台在线音频播放?