SQLite结构
Table: Class
Column1: classID (primary key)
Column2: className
Table: Students
Column1: studentID (primary key)
Column2: classID (foreign key)
Column3: studentName
问题
我已按照Adding Custom Suggestions开发者指南进行操作。当我输入操作栏搜索小部件时,系统正确调用我的内容提供者的查询功能,我可以看到搜索建议。我的问题是查询返回整个学生表中的建议(这是预期的行为)。但我需要限制给定classID的建议。但是,如开发人员指南中所述搜索建议的工作方式,只有一个参数传递给查询函数,在我的例子中是selectionArgs [0]。
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/student_search_hint"
android:label="@string/app_name"
android:searchSuggestThreshold="2"
android:searchSuggestAuthority="com.androidapp.providers.database"
android:searchSuggestSelection="studentName LIKE ? "
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchMode="queryRewriteFromText" >
摘自内容提供商
@Override
public Cursor query(Uri uri, String[] projection, String selection,String[], selectionArgs, String sortOrder) {
...
queryBuilder.setTables(StudentsTable.TABLE);
HashMap<String, String> columnMap = new HashMap<String, String>();
columnMap.put(BaseColumns._ID, StudentsTable.STUDENT_ID + " AS " + BaseColumns._ID);
columnMap.put(SearchManager.SUGGEST_COLUMN_TEXT_1, StudentsTable.NAME + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
columnMap.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, StudentsTable.STUDENT_ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA);
queryBuilder.setProjectionMap(columnMap);
limit = uri.getQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT);
selectionArgs[0] = "%"+selectionArgs[0] + "%";
SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder, limit);
return cursor;
}
如果查询是由我发起的,我可以简单地在selectionArgs [1]中传递第二个参数(classID)并相应地修改选择字符串以形成正确的SQLite语句。
但查询是由系统启动的。那我该怎么做?是否可以拦截对我的内容提供商的调用并修改对查询的调用?
答案 0 :(得分:1)
我希望这对某人有帮助,我花了好几天试图解决这个问题,感谢pskink提供的link我能够实现以下解决方案:
我在内容提供商中创建了一个变量,并使用了相应的setter方法:
public class MyContentProvider extends ContentProvider {
...
private long id;
...
public void setId(long id) {
this.id = id;
}
}
然后在我的活动中,我想为特定班级的学生提供搜索建议,我这样做:
ContentProviderClient client = getContentResolver().acquireContentProviderClient("com.androidapp.providers.database");
MyContentProvider provider = (MyContentProvider)client.getLocalContentProvider();
provider.setId(rowid); //rowid is the classId from which students will be searched
client.release();
修改查询功能:
@Override
public Cursor query(Uri uri, String[] projection, String selection,String[], selectionArgs, String sortOrder) {
...
queryBuilder.setTables(StudentsTable.TABLE);
HashMap<String, String> columnMap = new HashMap<String, String>();
columnMap.put(BaseColumns._ID, StudentsTable.STUDENT_ID + " AS " + BaseColumns._ID);
columnMap.put(SearchManager.SUGGEST_COLUMN_TEXT_1, StudentsTable.NAME + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
columnMap.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, StudentsTable.STUDENT_ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA);
queryBuilder.setProjectionMap(columnMap);
limit = uri.getQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT);
selectionArgs[0] = "%" + selectionArgs[0] + "%";
/*AMMENDMENT*/
selection = selection + "AND " + StudentsTable.CLASS_ID + "=" + id;
//This forms the SQL statement "WHERE studentName LIKE ? AND classId=3" (Assuming that rowid was 3).
//As per normal Android behaviour the "?" mark will be replaced by selectionArgs[0].
/*END*/
SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder, limit);
return cursor;
}
答案 1 :(得分:0)
我刚为内容提供商的第二个参数创建了一个静态变量,并从活动中设置了它。我一直在考虑它,这是我找到的最干净的解决方法!