Reputation: 287
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
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
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