use*_*032 10 android android-query android-11
内部版本号为 RQ1A.201205.003 或更高版本的 Pixel 设备上会出现以下错误。
\n我想知道错误原因以及如何处理。
\n这是一个错误还是规格更改?
\xe2\x96\xa0code
\n ContentResolver resolver = getContentResolver();\n String order = "date ASC limit 100";\n Cursor cursor = resolver.query(\n CallLog.Calls.CONTENT_URI,\n null,\n null,\n null,\n order);\nRun Code Online (Sandbox Code Playgroud)\n\xe2\x96\xa0错误
\n"Invalid token limit,LINE:142,Method:readExceptionFromParcel Exception:Invalid token limit"\nRun Code Online (Sandbox Code Playgroud)\n\xe2\x96\xa0发生错误的内部版本号
\nhttps://support.google.com/pixelphone/thread/87641266\n\xe3\x83\xbbRQ1A.201205.003\n\xe3\x83\xbbRQ1A.201205.008\n\xe3\x83\xbbRQ1A.201205.011\n\nhttps://support.google.com/pixelphone/thread/93232095\n\xe3\x83\xbbRQ1A.210105.002\n\xe3\x83\xbbRQ1A.210105.003\n\nhttps://support.google.com/pixelphone/thread/96244000\n\xe3\x83\xbbRQ1A.210205.004\nRun Code Online (Sandbox Code Playgroud)\n\xe2\x96\xa0如果替换为以下代码,则不会出现错误。
\nbuildUpon().appendQueryParameter("limit", "100")\nRun Code Online (Sandbox Code Playgroud)\n\xe2\x96\xa0附加信息\n使用官方文档方法实现时,没有发生错误,但该LIMIT子句不起作用(检索了所有记录)。
// Request 20 records starting at row index 30.\n Bundle queryArgs = new Bundle();\n queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 30);\n queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 20);\n \n Cursor cursor = getContentResolver().query(\n contentUri, // Content Uri is specific to individual content providers.\n projection, // String[] describing which columns to return.\n queryArgs, // Query arguments.\n null); // Cancellation signal.\nRun Code Online (Sandbox Code Playgroud)\n
Spa*_*ace 15
从 Android 11 开始,LIMIT应OFFSET使用 Bundle 进行检索
public Cursor query (Uri uri,
String[] projection,
Bundle queryArgs,
CancellationSignal cancellationSignal)
Run Code Online (Sandbox Code Playgroud)
我使用这样的解决方案,它对我有用:
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import androidx.annotation.RequiresApi
import androidx.core.database.getLongOrNull
import androidx.core.database.getStringOrNull
data class MediaItem(
val id: Long,
val contentUri: Uri,
val data: String?,
val mimeType: String?,
val duration: Long?
)
private fun fetchGalleryImages(
context: Context,
orderBy: String,
orderAscending: Boolean,
limit: Int = 20,
offset: Int = 0
): List<MediaItem> {
val galleryImageUrls = mutableListOf<MediaItem>()
val collection = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
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 whereCondition = "${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()
)
createCursor(
contentResolver = context.contentResolver,
collection = collection,
projection = projection,
whereCondition = whereCondition,
selectionArgs = selectionArgs,
orderBy = orderBy,
orderAscending = orderAscending,
limit = limit,
offset = offset
)?.use { cursor ->
while (cursor.moveToNext()) {
val idIndex = cursor.getColumnIndex(MediaStore.Audio.Media._ID)
if (idIndex < 0) continue
val id = cursor.getLong(idIndex)
galleryImageUrls.add(
MediaItem(
id = id,
contentUri = ContentUris.withAppendedId(collection, id),
data = cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)),
mimeType = cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Files.FileColumns.MIME_TYPE)),
duration = cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DURATION))
)
)
}
}
return galleryImageUrls
}
private fun createCursor(
contentResolver: ContentResolver,
collection: Uri,
projection: Array<String>,
whereCondition: String,
selectionArgs: Array<String>,
orderBy: String,
orderAscending: Boolean,
limit: Int = 20,
offset: Int = 0
): Cursor? = when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
val selection = createSelectionBundle(whereCondition, selectionArgs, orderBy, orderAscending, limit, offset)
contentResolver.query(collection, projection, selection, null)
}
else -> {
val orderDirection = if (orderAscending) "ASC" else "DESC"
var order = when (orderBy) {
"ALPHABET" -> "${MediaStore.Audio.Media.TITLE}, ${MediaStore.Audio.Media.ARTIST} $orderDirection"
else -> "${MediaStore.Audio.Media.DATE_ADDED} $orderDirection"
}
order += " LIMIT $limit OFFSET $offset"
contentResolver.query(collection, projection, whereCondition, selectionArgs, order)
}
}
@RequiresApi(Build.VERSION_CODES.O)
fun createSelectionBundle(
whereCondition: String,
selectionArgs: Array<String>,
orderBy: String,
orderAscending: Boolean,
limit: Int = 20,
offset: Int = 0
): Bundle = Bundle().apply {
// Limit & Offset
putInt(ContentResolver.QUERY_ARG_LIMIT, limit)
putInt(ContentResolver.QUERY_ARG_OFFSET, offset)
// Sort function
when (orderBy) {
"ALPHABET" -> putStringArray(ContentResolver.QUERY_ARG_SORT_COLUMNS, arrayOf(MediaStore.Files.FileColumns.TITLE))
else -> putStringArray(ContentResolver.QUERY_ARG_SORT_COLUMNS, arrayOf(MediaStore.Files.FileColumns.DATE_ADDED))
}
// Sorting direction
val orderDirection =
if (orderAscending) ContentResolver.QUERY_SORT_DIRECTION_ASCENDING else ContentResolver.QUERY_SORT_DIRECTION_DESCENDING
putInt(ContentResolver.QUERY_ARG_SORT_DIRECTION, orderDirection)
// Selection
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, whereCondition)
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6884 次 |
| 最近记录: |