我的內容提供商遇到問題。我在我的一個活動中使用內容提供者,並使用CursorLoader和適配器來顯示列表。net.sqlcipher.database.SQLiteException:綁定或列索引超出範圍:句柄0x7bf058da88
當且僅當我沒有在CursorLoader構造函數中指定selection和selectionArgs參數時,該列表顯示Task表的內容。
我已經嘗試過在選擇和選擇參數的空值,這將返回整個表的內容。我想要做的是選擇基於C_TASK_CALLID列的表的完整投影並傳遞一個callID。
所以我想要做的是一些這樣的SQL返回遊標基地:
select * from table TASK where C_TASK_CALLID = callID;
誰能告訴我爲什麼我收到的folloing錯誤?
我看過以下SO帖子,但它表明選擇和selectionArgs之間存在不匹配。就我而言,這是不正確的,因爲我只傳入一個參數。
。
我得到以下錯誤:
06-01 14:05:56.631 32037-32037/com.carefreegroup.rr3 E/ViewCompletedTasksActivity: about to create CursorLoader.....LoginValidate.C_TASK_CALLID = taskcallid callID = d5f5482f-b240-4eb6-8be1-489a8d75af9b
06-01 14:05:56.636 32037-2691/com.carefreegroup.rr3 E/RR3ContentProvider: inside RR3ContentProvider query method
06-01 14:05:56.636 32037-2691/com.carefreegroup.rr3 E/LoginValidate: NfcScannerApplication.getSecretKey() = 12345
06-01 14:05:56.636 32037-2691/com.carefreegroup.rr3 E/RR3ContentProvider: CASE TASKS
06-01 14:05:56.636 32037-2691/com.carefreegroup.rr3 E/RR3ContentProvider: About to do the query method in content provider
06-01 14:05:56.645 32037-2691/com.carefreegroup.rr3 E/CustomExceptionHandler: stack = java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)
Caused by: net.sqlcipher.database.SQLiteException: bind or column index out of range: handle 0x7bf058da88
at net.sqlcipher.database.SQLiteProgram.native_bind_string(Native Method)
at net.sqlcipher.database.SQLiteProgram.bindString(SQLiteProgram.java:245)
at net.sqlcipher.database.SQLiteQuery.bindString(SQLiteQuery.java:183)
at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:48)
at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1820)
at net.sqlcipher.database.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:330)
at net.sqlcipher.database.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:280)
at com.carefreegroup.rr3.RR3ContentProvider.query(RR3ContentProvider.java:396)
at com.carefreegroup.rr3.RR3ContentProvider.query(RR3ContentProvider.java:23)
at android.content.ContentProvider.query(ContentProvider.java:1027)
at android.content.ContentProvider$Transport.query(ContentProvider.java:243)
at android.content.ContentResolver.query(ContentResolver.java:536)
at android.content.CursorLoader.loadInBackground(CursorLoader.java:64)
at android.content.CursorLoader.loadInBackground(CursorLoader.java:56)
at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:312)
at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:69)
at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:66)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:762)
。
下面是我的任務表:
public static final String C_ID_TASK_QUEST_COMM = BaseColumns._ID;
public static final String C_TASK_QUEST_COMM_QUESTSION = "taskquestcommquestion";
public static final String C_TASK_QUEST_COMM_COMMENTS = "taskquestcommcomments";
public static final String C_TASK_QUEST_ID = "taskquestid";
public static final String C_TASK_QUEST_TYPE = "taskquesttype";
public static final String C_TASK_CALLID = "taskcallid";
public static final String C_TASK_SENT_TO_SERVER = "tasksenttoserver";
public static final String C_TASK_VALUE = "taskvalue";
。下面
是在我的活動我CursorLoader構造:
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Log.e(TAG, "inside3 onCreateLoader in ViewCompletedTasksActivityAsync");
String[] projection = { LoginValidate.C_ID_TASK_QUEST_COMM, LoginValidate.C_TASK_QUEST_COMM_QUESTSION, LoginValidate.C_TASK_QUEST_COMM_COMMENTS,
LoginValidate.C_TASK_QUEST_ID,
LoginValidate.C_TASK_QUEST_TYPE , LoginValidate.C_TASK_CALLID, LoginValidate.C_TASK_SENT_TO_SERVER, LoginValidate.C_TASK_VALUE};
String [] selectionArgs = {callID};
Log.e(TAG, "about to create CursorLoader.....LoginValidate.C_TASK_CALLID = " + LoginValidate.C_TASK_CALLID + " callID = " + callID);
cursorLoader = new CursorLoader(this, RR3ContentProvider.CONTENT_URI_TASKS, projection, LoginValidate.C_TASK_CALLID, selectionArgs , null);
return cursorLoader;
}
。
下面是我的ContentProvider:
public class RR3ContentProvider extends ContentProvider {
private static final String TAG = RR3ContentProvider.class.getSimpleName();
NfcScannerApplication nfcAppObj;
static final String PROVIDER_NAME = "com.xxxxx.xxx.ContentProvider";
static final String URLTASKS = "content://" + PROVIDER_NAME + "/tasks";
static final Uri CONTENT_URI_TASKS = Uri.parse(URLTASKS);
static final String _ID_TASKS = "_id";
static final String TASK_QUESTION = "taskquestcommquestion";
static final String TABLETASKS = "tabletaskquestion";
private static HashMap<String, String> TASK_PROJECTION_MAP;
static final int TASKS = 9;
static final int TASK_ID = 10;
static final UriMatcher uriMatcher;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "tasks", TASKS);
uriMatcher.addURI(PROVIDER_NAME, "tasks/#", TASK_ID);
}
/**
* Database specific constant declarations
*/
private SQLiteDatabase db;
@Override
public boolean onCreate() {
Context applicationContext = getContext().getApplicationContext();
nfcAppObj = getRealApplication(applicationContext);
Log.e(TAG, "inside RR3ContentProvider onCreate");
return (nfcAppObj == null)? false:true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Log.e(TAG, "inside RR3ContentProvider query method");
db = nfcAppObj.getDb();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch (uriMatcher.match(uri)) {
case TASKS:
Log.e(TAG, "CASE TASKS");
qb.setTables(TABLETASKS);
qb.setProjectionMap(TASK_PROJECTION_MAP);
/*if (sortOrder == null || sortOrder == ""){
sortOrder = LOG_CREATED_TIME + " DESC";
}*/
break;
case TASK_ID:
Log.e(TAG, "CASE TASK_ID");
qb.setTables(TABLETASKS);
qb.appendWhere(_ID_TASKS + "=" + uri.getPathSegments().get(1));
/*if (sortOrder == null || sortOrder == ""){
sortOrder = LOG_CREATED_TIME + " DESC";
}*/
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
Log.e(TAG, "About to do the query method in content provider");
Cursor c = qb.query(db, projection, selection, selectionArgs,
null, null, sortOrder);
/**
* register to watch a content URI for changes
*/
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}//end of query
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
/**
* Get all records
*/
case TASKS:
return "vnd.android.cursor.dir/vnd.example.tasks";
/**
* Get a particular record
*/
case TASK_ID:
return "vnd.android.cursor.item/vnd.example.tasks";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
}
。
你的查詢有incorect WHERE statment - 你正在傳遞selectionArgs但沒有地方綁定它 – Selvin
@Selvin我在這裏找到了解決方案。 https://stackoverflow.com/questions/25754360/how-to-use-selection-args-to-query-specific-rows-from-a-contentprovider-in-andro我認爲CursorLoader構造器抽象了一切,所以我只需要通過選擇和選擇Args。但事實證明,我必須做到以下幾點,並提供佔位符。 cursorLoader = new CursorLoader(this,RR3ContentProvider.CONTENT_URI_TASKS,projection, LoginValidate.C_TASK_CALLID +「=?」,new String [] {callID.trim()},null);無論如何,謝謝 – turtleboy
是的...你shoyld通過'LoginValidate.C_TASK_CALLID +「=?」'那裏 – Selvin