![](/img/trans.png)
[英]ContentResolver.query: CursorIndexOutOfBoundsException
[英]limiting number of rows in a ContentResolver.query() function
有沒有辦法限制游標的返回行數? 我有一部有大約 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
要限制游標中的結果數,請嘗試:
cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, ContactName + " LIMIT 100");
while(cursor.moveToNext()) {
// something clever
}
接受的答案對 android 11 不再有效。在 android 11 中添加了一個約束,不允許在排序值中使用 LIMIT。 您需要使用帶有捆綁參數的查詢。 例如:
val bundle = Bundle().apply {
putInt(ContentResolver.QUERY_ARG_LIMIT, 100)
}
resolver.query(
ContactsContract.Contacts.CONTENT_URI,
projection,
bundle,
null
)
從 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
}
在 android 26 查詢方法升級。 此函數正在使用這些參數。 Uri uri、String[] 投影、Bundle queryArgs、CancellationSignal 取消信號
下面的例子我得到了最近的 5 張照片。
val whereArgs = arrayOf("image/jpeg", "image/png", "image/jpg")
val projection = arrayOf(MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.MIME_TYPE)
val selection =
"${MediaStore.Files.FileColumns.MIME_TYPE} = ? OR ${MediaStore.Files.FileColumns.MIME_TYPE} = ? OR ${MediaStore.Files.FileColumns.MIME_TYPE} = ?"
val queryArgs = Bundle()
val sortArgs = arrayOf(MediaStore.Images.ImageColumns.DATE_TAKEN)
queryArgs.putStringArray(ContentResolver.QUERY_ARG_SORT_COLUMNS, sortArgs)
queryArgs.putInt(ContentResolver.QUERY_ARG_SORT_DIRECTION, ContentResolver.QUERY_SORT_DIRECTION_DESCENDING)
queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 5)
queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
queryArgs.putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, whereArgs)
val cursor = context!!.contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
queryArgs,
null)
if (cursor!!.moveToFirst()) {
do {
val imageLocation = cursor.getString(1)
val imageFile = File(imageLocation)
if (imageFile.exists()) {
//access you file from imageLocation
}
} while (cursor.moveToNext())
fiveRecentlyImagesAdapter!!.notifyDataSetChanged()
}
如果有人正在尋找上述 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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.