限制ContentResolver.query()函数中的行数

时间:2012-04-30 21:06:45

标签: android database contacts

有没有办法将返回的行数限制为游标? 我有一个有大约4000个联系人的电话,我只需要其中一些。

这是我正在使用的代码

        db = new dBHelper(this);
        ContentResolver cr = getContentResolver();
        Cursor cursor;

        cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, ContactName + " ASC");
        Log.i(TAG, CLASSNAME + " got contacts entries");
        for (int it = 0; it <100 ; it++){//cursor.getCount()
            Log.i(TAG, CLASSNAME + " getting string");
            String mytimes_contacted = cursor.getString(cursor.getColumnIndex(dBHelper.times_contacted)); 
            Log.i(TAG, CLASSNAME + " done from the string");
        }

我得到的日志是

I/Check(11506): [ContactsPicker] got contacts entries
I/Check(11506): [ContactsPicker] getting first string
D/AndroidRuntime(11506): Shutting down VM
W/dalvikvm(11506): threadid=1: thread exiting with uncaught exception (group=0x2aac8578)
D/dalvikvm(11541): GC_CONCURRENT freed 923K, 46% free 4000K/7303K, external 1685K/2133K, paused 1ms+8ms
E/AndroidRuntime(11506): FATAL EXCEPTION: main
E/AndroidRuntime(11506): java.lang.RuntimeException: Unable to start activity ComponentInfo{~~my package name~~}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 3537

5 个答案:

答案 0 :(得分:36)

要限制光标中的结果数量,请尝试:

cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, ContactName + " LIMIT 100");
while(cursor.moveToNext()) {
    // something clever
}

答案 1 :(得分:5)

已接受的答案对于android 11不再有效。在android 11中,添加了一个约束以不允许在排序值中使用LIMIT。您需要将查询与包参数一起使用。例如:

        val bundle = Bundle().apply {
            putInt(ContentResolver.QUERY_ARG_LIMIT, 100)
        }
        resolver.query(
                ContactsContract.Contacts.CONTENT_URI,
                projection,
                bundle,
                null
        )

答案 2 :(得分:3)

从Android 11开始,上述解决方案将无法正常工作,您可以尝试使用此方法来获取数据。

    /**
 * Call to fetch all media on device, it but be called synchronously since function is called on a background thread
 */
private fun fetchGalleryImages(
    context: Context,
    offset: Int,
    limit: Int
): List<MediaItem> {
    val galleryImageUrls = mutableListOf<MediaItem>()
    try {
        if (EasyPermissions.hasPermissions(
                context,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
        ) {
            // Define the columns that will be fetched
            val projection = arrayOf(
                MediaStore.Files.FileColumns._ID,
                MediaStore.Files.FileColumns.DATA,
                MediaStore.Files.FileColumns.DATE_ADDED,
                MediaStore.Files.FileColumns.MEDIA_TYPE,
                MediaStore.Files.FileColumns.MIME_TYPE,
                MediaStore.Files.FileColumns.TITLE,
                MediaStore.Video.Media.DURATION
            )
            val selection =
                "${MediaStore.Files.FileColumns.MEDIA_TYPE} = ? OR ${MediaStore.Files.FileColumns.MEDIA_TYPE} = ?"
            val selectionArgs = arrayOf(
                MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE.toString(),
                MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO.toString()
            )
            /**
             * Change the way to fetch Media Store
             */
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                // Get All data in Cursor by sorting in DESC order
                context.contentResolver.query(
                    contentUri(),
                    projection,
                    Bundle().apply {
                        // Limit & Offset
                        putInt(ContentResolver.QUERY_ARG_LIMIT, limit)
                        putInt(ContentResolver.QUERY_ARG_OFFSET, offset)
                        // Sort function
                        putString(
                            ContentResolver.QUERY_ARG_SORT_COLUMNS,
                            MediaStore.Files.FileColumns.DATE_MODIFIED
                        )
                        putInt(
                            ContentResolver.QUERY_ARG_SORT_DIRECTION,
                            ContentResolver.QUERY_SORT_DIRECTION_DESCENDING
                        )
                        // Selection
                        putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
                        putStringArray(
                            ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS,
                            selectionArgs
                        )
                    }, null
                )
            } else {
                val sortOrder =
                    "${MediaStore.Files.FileColumns.DATE_MODIFIED} DESC LIMIT $limit OFFSET $offset"
                // Get All data in Cursor by sorting in DESC order
                context.contentResolver.query(
                    contentUri(),
                    projection,
                    selection,
                    selectionArgs,
                    sortOrder
                )
            }?.use { cursor ->
                while (cursor.moveToNext()) {
                    galleryImageUrls.add(
                        MediaItem(
                            cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID)),
                            ContentUris.withAppendedId(
                                contentUri(),
                                cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID))
                            ),
                            cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)),
                            cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Files.FileColumns.MIME_TYPE)),
                            cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DURATION))
                        )
                    )
                }
            }
        }
    } catch (ex: Exception) {
        ex.printStackTrace()
    }
    return galleryImageUrls
}

答案 3 :(得分:2)

在 android 26 查询方法升级。此函数正在使用这些参数。 uri uri, String[] 投影, Bundle queryArgs, CancellationSignal 取消信号

下面的例子我得到了最近的 5 张照片。

id13

答案 4 :(得分:1)

如果有人正在寻找上述 Ignacio Tomas Crespo 答案的 Java 版本,

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {

            cursor = context.getContentResolver().query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                            .buildUpon()
                            .encodedQuery("limit=" + offSet + "," + "100")
                            .build(),
                    columns,
                    null,
                    null,
                    null);
        } else {
            Bundle bundle = new Bundle();
            bundle.putInt(ContentResolver.QUERY_ARG_LIMIT, 100);

            cursor = context.getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            columns,
                            bundle,
                            null);
        }