DatabaseUtils: java.lang.IllegalArgumentException: Invalid token LIMIT

I. Introduction

Encountered a bug on Android12, part of it is solved here. ContentResolveEncountered the following error when using

DatabaseUtils: java.lang.IllegalArgumentException: Invalid token LIMIT

The following important link was referred to during the solution:
https://blog.csdn.net/u010471406/article/details/118112086.
After testing, the use of the database, such as SQLiteOpenHelperregular use, will not cause this problem.
Another solution is provided in the following link:
https://stackoverflow.com/questions/66280961/contentresolver-query-method-throws-invalid-token-limit-error

Two, solve the code

limitAfter the above link provides a solution to the restrictions in the query statement , the code is now sorted out. The original code is about querying phone record errors. Here is the author's code:

     /**
         * 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();
            }
        }

There will be problems during the execution of the above code, the modified code is as follows


        /**
         * 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();
            }
        }
        

After verification, the code can actually be made into a general code, which CallLog.Calls.CONTENT_URIcan be replaced with anything Uri. CallLog.Calls.LIMIT_PARAM_KEYcan be replaced with ContactsContract.LIMIT_PARAM_KEY. After verification, ContactsContractthere are related code samples in the class:

 /**
         * <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(&quot;limit&quot;, &quot;3&quot;)
         *          .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…

3. Expansion

When used on Android 11 ContentResolver, the official does not recommend the use of sql statements to query, the recommended Bundleway, its reference code has a sample code in the official API, the link is as follows:
https://developer.android.com/reference/android /content/ContentProvider#query(android.net.Uri,%20java.lang.String[],%20android.os.Bundle,%20android.os.CancellationSignal)

The official sample code is posted here, but it is only part of the detailed parameters, and you need to check the official

 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.

4. Reference link

  1. ContentProvider
  2. https://stackoverflow.com/questions/66280961/contentresolver-query-method-throws-invalid-token-limit-error
  3. https://blog.csdn.net/u010471406/article/details/118112086

Guess you like

Origin blog.csdn.net/Mr_Tony/article/details/125996836