一、何谓Android的过滤机制?
六、实战
知道了Android的过滤机制,我们就以AutoCompleteTextView为例,通过输入文本筛选数据库中的数据。
1、首先写ContentProvider
由于代码量比较多,只写出对外的接口。
- public static final class Location implements BaseColumns {
- public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "location" );
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/weather_location" ;
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/weather_location" ;
- public static final String CONTENT_DIRECTORY = "location" ;
- public static final String LOCATION_NAME = "location_name" ;
- public static final String LONGITUDE = "longitude" ;
- public static final String ALTITUDE = "altitude" ;
- }
2、写CursorAdapter
- private static class LocationAdapter extends CursorAdapter {
- private LayoutInflater mInflater;
- private Context mContext;
- private Cursor mCursor;
- public LocationAdapter(Context context, Cursor c) {
- super (context, c);
- mContext = context;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
- @Override
- public void bindView(View view, Context context, Cursor cursor) {
- TextView textView = (TextView) view;
- String location = cursor.getString(cursor.getColumnIndex(Location.LOCATION_NAME));
- textView.setText(location);
- }
- @Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(android.R.layout.simple_dropdown_item_1line, null );
- }
- @Override
- public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
- String selection = Location.LOCATION_NAME + " LIKE '%" + constraint + "%'" ;
- return mContext.getContentResolver().query(Location.CONTENT_URI
- , null , selection, null , null );
- }
- /**一定要重写该方法,否则AutoCompleteTextView选中某一项后,文本框显示的不是所要的文本*/
- @Override
- public CharSequence convertToString(Cursor cursor) {
- return cursor.getString(cursor.getColumnIndex(Location.LOCATION_NAME));
- }
- }
- private void initialTextView() {
- mTextView = new AutoCompleteTextView(mContext);
- mTextView.setThreshold(0 );
- Cursor cursor = mContext.getContentResolver().query(Location.CONTENT_URI
- , null , null , null , null );
- LocationAdapter adapter = new LocationAdapter(mContext, cursor);
- mTextView.setAdapter(adapter);
- }
对于短信搜索,是直接使用了Android系统的搜索框架,当然在我们平常做项目的时候,也可以直接调用系统自带的搜索框,这个具体的怎么调用可以用Google或者百度搜索,有许多相关的资料,现在主要记录下自己阅读短息搜索源码的流程以及遇到的问题。
1. 在ConversationList.java文件中有如下一段代码:
- public boolean onSearchRequested() { startSearch( null , false , null /*appData*/ , false ); return true ;}
在这里是重写了Activity里的onSearchRequested()方法,如果我们不想在这里面做一些操作的话,可以直接调用onSearchRequested()方法。在onSearchRequested()方法里是调用了startSearch()方法。
2. 一直追踪下去可以追溯到SearchaDialog.java中。这里在搜索框中添加了一个Adapter,这个Adapter就是来显示下拉列表的,在 这个类中发现在runQueryOnBackgroundThread()方法中还是回到了SearchManager的getSuggestions方 法中,根据相应的Uri, mContext.getContentResolver().query(uri, null, selection, selArgs, null);去查询相关的数据库。
3. 在短信搜索这里与之相关的Uri为SuggestionsProvider,最后还是到了MmsSmsProvider中去进行数据库查询操作。
4.在MmsSmsProvider中有条查询语句:String.format("SELECT _id, index_text, source_id, table_to_use, offsets(words) FROM words WHERE words MATCH '%s*' LIMIT 50;", searchString); 这里将通过这条SQL语句进行查询,将结果以Cursor的形式进行返回。
4. 在SuggestionsProvider,这边对cursor的内容进行提取,显示在下拉列表中。但是这里可能是Google留给广大厂商去解决,就是 SQLite中的 MATCH 并不能很好的匹配亚洲文字,如:汉字,韩语等。所以按照源码的话,这个短信搜索功能搜索英文还可以,但是搜索亚洲文字,则无法搜索出来。不知道以后 SQLite 会不会对 MATCH 增加对非字母文字的支持。
关于offsets(),的一些说明:
offsets(),返回一系列以空格隔开的整数,至少含有4为数(以4个整数为一组返回)。
对于这四位数的解释:
第0位:表示列号
第1位:表示在该列中该字符出现的次数
第2位:在该列中匹配项字符的偏移位 (bytes)
第3位:匹配项的大小(bytes)
offsets()需要和MATCH配对使用。
关于MATCH()
MATCH : 如 MATCH 'Hi', 表示存在Hi的字符串,MATCH ‘Hi*’, 表示以Hi开头的字符串。