一、前言
在Android12上遇到了一个错误,这里解决了一部分。在使用ContentResolve
时候遇到以下错误
DatabaseUtils: java.lang.IllegalArgumentException: Invalid token LIMIT
在解决过程中参考了以下重要链接:
https://blog.csdn.net/u010471406/article/details/118112086。
经过测试,数据库的使用,比如SQLiteOpenHelper
的常规使用是不会引起这个问题的。
在以下链接里面提供了另外一种解决方式:
https://stackoverflow.com/questions/66280961/contentresolver-query-method-throws-invalid-token-limit-error
二、解决代码
经过上述链接其中关于查询语句中的limit
的限制提供了解决方式,现在将代码进行整理。原代码是关于查询电话记录错误。这里借鉴下作者的代码:
/**
* Get if the query is marked as strict, as last configured by
* {@link #setStrictGrammar(boolean)}.
*/
public static String getLastOutgoingCall(Context context) {
final ContentResolver resolver = context.getContentResolver();
Cursor c = null;
try {
c = resolver.query(Calls.CONTENT_URI,
new String[] {
Calls.NUMBER
}, Calls.TYPE + " = "
+ Calls.OUTGOING_TYPE, null,
Calls.DEFAULT_SORT_ORDER + " LIMIT 1");
if (c == null || !c.moveToFirst()) {
return "";
}
return c.getString(0);
} finally {
if (c != null)
c.close();
}
}
上述代码执行过程中会出现问题,修改后的代码如下
/**
* Get if the query is marked as strict, as last configured by
* {@link #setStrictGrammar(boolean)}.
*/
public static String getLastOutgoingCall(Context context) {
final ContentResolver resolver = context.getContentResolver();
Cursor c = null;
try {
Uri limitedCallLogUri = CallLog.Calls.CONTENT_URI.buildUpon()
.appendQueryParameter(CallLog.Calls.LIMIT_PARAM_KEY, "1").build();
c = resolver.query(limitedCallLogUri,
new String[] {
Calls.NUMBER
}, Calls.TYPE + " = "
+ Calls.OUTGOING_TYPE, null,
Calls.DEFAULT_SORT_ORDER + " LIMIT 1");
if (c == null || !c.moveToFirst()) {
return "";
}
return c.getString(0);
} finally {
if (c != null)
c.close();
}
}
该代码经过查证其实是可以做成通用代码的,其中CallLog.Calls.CONTENT_URI
可以替换成任意Uri
。CallLog.Calls.LIMIT_PARAM_KEY
可以替换成ContactsContract.LIMIT_PARAM_KEY
。经过查证在ContactsContract
类中有相关代码示例:
/**
* <p>
* A <i>read-only</i> sub-directory of a single contact aggregate that
* contains all aggregation suggestions (other contacts). The
* aggregation suggestions are computed based on approximate data
* matches with this contact.
* </p>
* <p>
* <i>Note: this query may be expensive! If you need to use it in bulk,
* make sure the user experience is acceptable when the query runs for a
* long time.</i>
* <p>
* Usage example:
*
* <pre>
* Uri uri = Contacts.CONTENT_URI.buildUpon()
* .appendEncodedPath(String.valueOf(contactId))
* .appendPath(Contacts.AggregationSuggestions.CONTENT_DIRECTORY)
* .appendQueryParameter("limit", "3")
* .build()
* Cursor cursor = getContentResolver().query(suggestionsUri,
* new String[] {Contacts.DISPLAY_NAME, Contacts._ID, Contacts.LOOKUP_KEY},
* null, null, null);
* </pre>
*
* </p>
* <p>
* This directory can be used either with a {@link #CONTENT_URI} or
* {@link #CONTENT_LOOKUP_URI}.
* </p>
*/
end…
三、拓展
在Android11之上使用ContentResolver
时候,官方不在推荐使用sql语句的方式去查询,推荐使用Bundle
的方式,其参考代码在官方API里面有示例代码,链接如下:
https://developer.android.com/reference/android/content/ContentProvider#query(android.net.Uri,%20java.lang.String[],%20android.os.Bundle,%20android.os.CancellationSignal)
这里将官方的示例代码贴出,不过只是部分的详细参数部分,还需去查阅官方
Bundle queryArgs = new Bundle();
queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 30);
queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 20);
Cursor cursor = getContentResolver().query(
contentUri, // Content Uri is specific to individual content providers.
projection, // String[] describing which columns to return.
queryArgs, // Query arguments.
null); // Cancellation signal.
四、参考链接
- ContentProvider
- https://stackoverflow.com/questions/66280961/contentresolver-query-method-throws-invalid-token-limit-error
- https://blog.csdn.net/u010471406/article/details/118112086