33-Android之Mms多个联系人消息显示修改
Orange运营商要求,当使用Mms同时向多个联系人发送信息时,只显示一条发送信息。
首先, 我们需要知道在查询一个会话的所有的消息,所必须需要的字段(thread_id,address,date)。
其次,同时向多个联系人发送的消息,每个联系人都会在数据库插入一条发送的消息,而这些插入的消息thread_id和date是一致的, 因此使用thread_id和date作为消息过滤的字段。
最后,修改MmsSmsProvider中查询会话消息的SQL语句。
packages/providers/TelephonyProvider/src/com/android/providers/telephony/MmsSmsProvider.java
// 创建查询会话所有消息的SQL的方法
private static String buildConversationQuery(String[] projection,
String selection, String sortOrder, String smsTable, String pduTable) {
String[] mmsProjection = createMmsProjection(projection, pduTable);
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
mmsQueryBuilder.setDistinct(true);
smsQueryBuilder.setDistinct(true);
mmsQueryBuilder.setTables(joinPduAndPendingMsgTables(pduTable));
smsQueryBuilder.setTables(smsTable);
String[] smsColumns = handleNullMessageProjection(projection);
String[] mmsColumns = handleNullMessageProjection(mmsProjection);
String[] innerMmsProjection = makeProjectionWithNormalizedDate(mmsColumns, 1000);
String[] innerSmsProjection = makeProjectionWithNormalizedDate(smsColumns, 1);
Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS);
columnsPresentInTable.add(pduTable + "._id");
columnsPresentInTable.add(PendingMessages.ERROR_TYPE);
String mmsSelection = concatSelections(selection,
Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS);
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection,
columnsPresentInTable, 0, "mms",
concatSelections(mmsSelection, MMS_CONVERSATION_CONSTRAINT),
null, null);
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, SMS_COLUMNS,
0, "sms", concatSelections(selection, SMS_CONVERSATION_CONSTRAINT),
null, null);
/// M: Code analyze 003, new feature, support for cellbroadcast. @{
SQLiteQueryBuilder cbQueryBuilder = new SQLiteQueryBuilder();
cbQueryBuilder.setDistinct(true);
cbQueryBuilder.setTables("cellbroadcast");
String[] cbColumns = handleNullMessageProjection(projection);
String[] innerCbProjection = makeProjectionWithNormalizedDate(cbColumns, 1);
String cbSubQuery = cbQueryBuilder.buildUnionSubQuery(
MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerCbProjection, CB_COLUMNS,
0, "cellbroadcast", selection, null, null);
/// @}
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
unionQueryBuilder.setDistinct(true);
/// M: Code analyze 003, new feature, support for cellbroadcast. @{
String unionQuery = unionQueryBuilder.buildUnionQuery(
new String[] { smsSubQuery, mmsSubQuery, cbSubQuery },
handleNullSortOrder(sortOrder), null);
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
outerQueryBuilder.setTables("(" + unionQuery + ")");
// 添加的代码 begin
String groupBy = null;
LogUtils.d(LOG_TAG,"buildConversationQuery projection: " + projection);
if(deduplication(projection)) { // 判断是否是我们需要的会话消息查询
groupBy ="thread_id,date"; // 如果是,使用groupBy对thread_id和date一致的消息进行过滤
// 因为只有消息同时向多个联系人发送时,thread_id和date才会一致
}
Log.d(LOG_TAG, "groupBy: " + groupBy);
// 添加的代码 end
return outerQueryBuilder.buildQuery(
smsColumns, null, groupBy, null, sortOrder, null);
}
// 该方法是对查询进行过滤, 如果不包含thread_id, address, date这三个字段查询不进行处理
// 通过对查询日志分析这三个字段是查询会话消息的必须字段
private static boolean deduplication(String[] old) {
int count = 0;
for (int i = 0; i < old.length; i++) {
Log.d(LOG_TAG, "old["+i+"]: "+old[i]);
if(old[i].equals("thread_id")
|| old[i].equals("address")
|| old[i].equals("date")) {
count += 1;
if(count == 3) {
return true;
}
}
}
return count == 3;
}