gpt4 book ai didi

android - 在 Ice Cream Sandwich 的 ContentResolver 中分组

转载 作者:IT老高 更新时间:2023-10-28 23:15:43 26 4
gpt4 key购买 nike

我正在查询 Android Contacts ContentProvider。我需要一个 Group By 子句。在 Gingerbread 和 Honeycomb 中,我会做这样的事情来同时搜索电话号码和电子邮件:

(实际的 WHERE 子句要复杂得多,因为它包括类型检查。这是一种简化,但产生相同的结果)

String request = Phone.NUMBER + " LIKE ? OR " + Email.DATA + " LIKE ?";
String[] params = new String["%test%", "%test%"];

Cursor cursor = getContentResolver().query(
Data.CONTENT_URI,
new String[] { Data._ID, Data.RAW_CONTACT_ID },
request + ") GROUP BY (" + Data.RAW_CONTACT_ID,
params, "lower(" + Data.DISPLAY_NAME + ") ASC");

')' 的注入(inject)完成了 WHERE 子句并允许插入 GROUP BY 子句。

但是,在 Ice Cream Sandwich 中,ContentProvider 似乎检测到了这一点并添加了正确数量的括号以防止我的注入(inject)。在单个游标查询中执行此操作的任何其他方式?

编辑

目前,我已经删除了 GROUP BY,并添加了一个 MatrixCursor 来限制影响,但我宁愿有一个真正的光标:

MatrixCursor result = new MatrixCursor(new String[] { Data._ID, Data.RAW_CONTACT_ID });
Set<Long> seen = new HashSet<Long>();
while (cursor.moveToNext()) {
long raw = cursor.getLong(1);
if (!seen.contains(raw)) {
seen.add(raw);
result.addRow(new Object[] {cursor.getLong(0), raw});
}
}

最佳答案

我最近在查询 CallLog.Calls DB(我们无法修改 ContentProvider)时解决了这个问题。我们最终要做的是构建一个如下所示的查询:

SELECT _id, date, duration, type, normalized_number FROM calls WHERE _id IN (
SELECT _id FROM calls WHERE date < ? GROUP BY normalized_number ORDER BY date DESC LIMIT ?
);

这里的想法是,我们在子查询中放置任何有效的 sqlite,返回一个 id 列表,然后再次查询所有具有这些 id 的调用。

最终代码如下所示:

String whereClause = "_id IN (SELECT _id FROM calls WHERE data < ? GROUP BY normalized_number ORDER BY date DESC LIMIT ?)";

Cursor cursor = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI,
new String[] { "_id", "date", "duration", "normalized_number" },
whereClause,
new String[]{ String.valueOf(amount), String.valueOf(dateFrom) },
null
);

...

如果您要查询联系人,它看起来像这样:

String whereClause = "_id IN (SELECT _id FROM contacts WHERE " + Phone.NUMBER + " LIKE ? OR " + Email.DATA + " LIKE ? GROUP BY " + Data.RAW_CONTACT_ID + " ORDER BY lower(" + Data.DISPLAY_NAME + ") ASC)";

String[] params = new String["%test%", "%test%"];

Cursor cursor = getContentResolver().query(
Data.CONTENT_URI,
new String[] { Data._ID, Data.RAW_CONTACT_ID },
whereClause,
params,
null
);

性能会有所下降(因为我们实际上要查询两次以获得相同的结果),但肯定会比查询所有调用和执行 GROUP BY 工作快得多在 Java 世界中,还允许您使用附加子句构建查询。

希望这会有所帮助。我们在奥利奥上使用了它,它满足了我们的需求。

关于android - 在 Ice Cream Sandwich 的 ContentResolver 中分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8654904/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com