zoukankan      html  css  js  c++  java
  • MMS搜索功能修改

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

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

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

    分析:查看代码TelephonyProvidersrccomandroidproviders elephonyMmsSmsProvider.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
  • 相关阅读:
    Vue组件开发实例(详细注释)
    Vue组件进阶知识总结
    webpack配置:打包第三方类库、第三方类库抽离、watch自动打包、集中拷贝静态资源
    webpack配置:less/sass文件打包和分离、自动处理css前缀、消除未使用的css及完整的webpack.config.js文件
    webpack配置:增加babel支持、打包后调试
    webpack配置:图片处理、css分离和路径问题
    webpack配置:css文件打包、JS压缩打包和HTML文件发布
    使用webpack构建本地服务器
    Webpack安装和配置
    npm模块安装机制
  • 原文地址:https://www.cnblogs.com/antoon/p/5181120.html
Copyright © 2011-2022 走看看