Sinyuk
Sinyuk

Reputation: 287

java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range. The statement has 0 parameters

I've checked many similar questions and answers.But in most cases,the questioner forgot to use ? as an adapter in selection.That's just not for me. I wrote the code follow the Content Provider Basics

And my Code is as follow (sorry for my English)

public class UserDictActivity extends Activity {
EditText editTextSearch;
ListView wordList;
String searchWord;
Cursor cursor;
SimpleCursorAdapter adapter;
// A projection defines the columns that will be returned for each row
String[] projection = {
        UserDictionary.Words._ID,
        UserDictionary.Words.WORD,
        UserDictionary.Words.LOCALE
};

// Selection defines SELECTE clause "var = ?"
String seletionClause = null;

// Selection arguments define the ? in the SELECT clause
String[] selectionArgs = new String[]{""};

// Defines a list of columns to retrieve from the Cursor and load into an output row
String[] wordListColumns = {
        UserDictionary.Words.WORD,   // Contract class constant containing the word column name
        UserDictionary.Words.LOCALE  // Contract class constant containing the locale column name
};

// Defines a list of View IDs that will receive the Cursor columns for each row
int[] wordListItems = {R.id.tv_word, R.id.tv_local};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_user_dict);

    editTextSearch = (EditText) findViewById(R.id.et_search);

    wordList = (ListView) findViewById(R.id.lv_wordlist);

    // TODO: Gets a word from the UI
    searchWord = editTextSearch.getText().toString();

    // TODO: Check for invalid or malicious input.

    // If the word is the empty string, gets everything
    if (TextUtils.isEmpty(searchWord)) {
        seletionClause = null;
        selectionArgs[0] = "";
    } else {
        // TODO: Constructs a selection clause that matches the word that the user entered.
        seletionClause = UserDictionary.Words.WORD + " = ?";

        // TODO: Moves the user's input string to the selection arguments.
        selectionArgs[0] = searchWord;
    }

    doQuery();
    // Creates a new SimpleCursorAdapter
    adapter = new SimpleCursorAdapter(
            getApplicationContext(),               // The application's Context object
            R.layout.wordlist_item,                  // A layout in XML for one row in the ListView
            cursor,                               // The result from the query
            wordListColumns,                      // A string array of column names in the cursor
            wordListItems,                        // An integer array of view IDs in the row layout
            0                                    // Flags (usually none are needed)
    );

    wordList.setAdapter(adapter);
}

private void doQuery() {


    // TODO: Does a query against the table and returns a Cursor object
    cursor = getContentResolver().query(
            UserDictionary.Words.CONTENT_URI,
            projection,
            seletionClause,
            selectionArgs,
            null                                // sortOrder
    );

    // Some providers return null if an error occurs, others throw an exception
    if (cursor == null) {
    /*
     * Insert code here to handle the error. Be sure not to use the cursor! You may want to
     * call android.util.Log.e() to log this error.
     *
     */
        Log.e("NullPointerException", "Cursor is NULL");
    }
    // If the Cursor is empty, the provider found no matches
    else if (cursor.getCount() < 1) {

        /*
        * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
        * an error. You may want to offer the user the option to insert a new row, or re-type the
        * search term.
        */
        Toast.makeText(this, "No word found", Toast.LENGTH_SHORT).show();
    } else {
        // Insert code here to do something with the results

    }
}

}

And the Error Log is as follow

07-04 07:06:35.788    1622-1622/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.sinyuk.contentproviderdemo, PID: 1622
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sinyuk.contentproviderdemo/com.example.sinyuk.contentproviderdemo.UserDictActivity}: java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range.  The statement has 0 parameters.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
        at android.app.ActivityThread.access$800(ActivityThread.java:151)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Upvotes: 2

Views: 3900

Answers (2)

Blackbelt
Blackbelt

Reputation: 157437

The problem is your if:

  if (TextUtils.isEmpty(searchWord)) {
        seletionClause = null;
        selectionArgs[0] = "";
    }

if selectionClause is null also your selectionArgs has to be null. Also you don't really need to keep both as member variables. But you can easily instantiate both in the local scope. You could also change the signature of doQuery, to accept the the String selectionClause and String[] selectionArgs, freeing yourself by the necessity to keep them as member class. E.g.

if (TextUtils.isEmpty(searchWord)) {
    seletionClause = null;
    selectionArgs = null;
} else {
    // TODO: Constructs a selection clause that matches the word that the user entered.
    seletionClause = UserDictionary.Words.WORD + " = ?";

    // TODO: Moves the user's input string to the selection arguments.
    selectionArgs = new String[] { searchWord };
}

doQuery(selectionClause, selectionArgs);



private void doQuery(String selectionClause, String[] selectionArgs) {
  //
}

Upvotes: 1

BladeCoder
BladeCoder

Reputation: 12929

selectionArgs should have a size of zero or be null when selectionClause is null. In your current code it's an array which always contain 1 element (which sometimes is empty string).

Upvotes: 0

Related Questions