集团通过在ContentResolver的在冰淇淋三明治明治、冰淇淋、集团、ContentResolver

2023-09-12 09:45:52 作者:青沐挽余寄笙歌

我正在对Android联系人ContentProvider的查询。我需要一个group by子句。在姜饼和蜂窝,我做这样的事情来搜索电话号码和电子邮件在同一时间:

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

 字符串请求= Phone.NUMBER +是否喜欢?+ Email.DATA +怎么样?;
的String [] PARAMS =新的String [%测试%,%测试%];

光标光标= getContentResolver()查询(
    Data.CONTENT_URI,
    新的String [] {Data._ID,Data.RAW_CONTACT_ID},
    请求+)GROUP BY(+ Data.RAW_CONTACT_ID,
    参数,可以低级(+ Data.DISPLAY_NAME +)ASC);
 

的')'注射完成的WHERE子句和允许一组的插入BY子句。

然而,冰淇淋三明治,看来,ContentProvider的检测这一点,并增加了括号的正确数量为prevent我注射。在单光标查询这样做的任何其他方式?

修改

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

  MatrixCursor结果=新MatrixCursor(新的String [] {Data._ID,Data.RAW_CONTACT_ID});
设置<龙>可见=新的HashSet<龙>();
而(cursor.moveToNext()){
    LONG RAW = cursor.getLong(1);
    如果(!seen.contains(原始)){
        seen.add(生);
        result.addRow(新对象[] {cursor.getLong(0),生});
    }
}
 
这些 网红 冰淇淋让你收获满满的夏日小幸福

解决方案

首先关闭所有原谅我的英语不好! 我是新来的Java / Android的,开始与4.2.1,并与战斗过近2天,然后我开始阅读一些有关的 SQLiteQueryBuilder 中的查询部分是pretty的多,什么ü正在寻找;)

这有:

 公开光标查询(SQLiteDatabase分贝,的String [] projectionIn,选择字符串,字符串[] selectionArgs两个,GROUPBY字符串,字符串有,字符串排序顺序)
 

内容提供商的查询功能只给你:

 查询(URI URI,字符串[]投影,选择字符串,字符串[] selectionArgs两个,串排序顺序)
 

这里u可以欺骗的时候,我会后你我的code剪断:

  @覆盖
公共光标查询(URI URI,字符串[]投影,串选择,
        的String [] selectionArgs两个,串排序顺序){
    SQLiteQueryBuilder QueryBuilder的=新SQLiteQueryBuilder();
    最后SQLiteDatabase DB = mOpenHelper.getReadableDatabase();
/ *一个String是一个对象,因此它可以为空!* /
    字符串GROUPBY = NULL;
    字符串具有= NULL;

    开关(sUriMatcher.match(URI)){
...
...
...
        案例EPISODES_NEXT:
        GROUPBY =ShowID;
        queryBuilder.setTables(EpisodenTable.TableName);
        打破;
    默认:
        抛出新抛出:IllegalArgumentException(未知URI+ URI);
    }

    光标C = queryBuilder.query(分贝,投影,选择,selectionArgs两个,
            GROUPBY,有,排序顺序);
    c.setNotificationUri(的getContext()getContentResolver(),URI);
    返回℃;
}
 

这就是它!

这里的code我用它来执行:

 光标showsc时=的getContext()。getContentResolver()查询(
            WhatsOnTVProvider.CONTENT_EPISODES_NEXT_URI,
            EpisodenTable.allColums_inclCount,
            将String.valueOf(Calendar.getInstance()。getTimeInMillis()/ 1000)
                    +<日期,NULL,NULL);
 

I am making a query on the Android Contacts ContentProvider. I need a Group By clause. In Gingerbread and Honeycomb, I do something like this to search phone numbers and emails at the same time:

(The actual WHERE clause is much more complicated as it includes types checks. This is a simplification, but it yields the same result)

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");

The injection of the ')' finishes the WHERE clause and allow the insertion of a GROUP BY clause.

However, in Ice Cream Sandwich, it appears that the ContentProvider detects this and adds the correct number of parenthesis to prevent my injection. Any other way of doing this in a single cursor query?

Edit

Currently, I have removed the GROUP BY, and added a MatrixCursor to limit the impact, but I'd rather have a real cursor:

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});
    }
}

解决方案

first off all excuse my POOR English! I'm new to Java/Android, started with 4.2.1 and fight with that too almost 2 days, then i start reading some more details about SQLiteQueryBuilder the query part is pretty much that what u are looking for ;)

it have:

public Cursor query (SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder)

the query "function" of the Content Provider only gives you:

query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder)

here u can trick around, i will post you my code snip:

    @Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
/* a String is a Object, so it can be null!*/
    String groupBy = null;
    String having = null;

    switch (sUriMatcher.match(uri)) {
...
...
...
        case EPISODES_NEXT:
        groupBy = "ShowID";
        queryBuilder.setTables(EpisodenTable.TableName);
        break;
    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    Cursor c = queryBuilder.query(db, projection, selection, selectionArgs,
            groupBy, having, sortOrder);
    c.setNotificationUri(getContext().getContentResolver(), uri);
    return c;
}

thats its!

here the code i use to execute:

        Cursor showsc = getContext().getContentResolver().query(
            WhatsOnTVProvider.CONTENT_EPISODES_NEXT_URI,
            EpisodenTable.allColums_inclCount,
            String.valueOf(Calendar.getInstance().getTimeInMillis() / 1000)
                    + " < date", null, null);