黑马短信管理第3天

本文详细介绍了短信应用的设计与实现过程,包括文件夹页面设置、文件夹详情页面展示、群组功能实现及搜索功能的开发。通过对不同页面的布局、交互逻辑及数据处理流程的深入解析,帮助读者理解整个短信应用的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.文件夹页面设置及查询各个箱子的个数



public class FolderUi extends ListActivity implements OnItemClickListener {

	private ListView listView;
	private String[] names = { "收件箱", "发件箱", "草稿箱", "已发送" };

	private int[] iconIds = { R.drawable.a_f_inbox, R.drawable.a_f_outbox,
			R.drawable.a_f_draft, R.drawable.a_f_sent };

	private int[] counts = new int[4];//短信条数
	private FolderAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		listView = getListView();
		
		adapter = new FolderAdapter();
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(this);

		prepareData();
	}

	private void prepareData() {
		MyQueryHandler handler = new MyQueryHandler(getContentResolver());
		//根据点击的item分别查询不同的uri(收件箱...发件箱...)
		for (int i = 0; i < counts.length; i++)
			handler.startQuery(i, null, Tools.getUriFromIndex(i),
					new String[] { " count(*) " }, null, null, null);
//			select count(*) from table 查询个数
		handler.setOnCursorChangedListener(new OnCursorChangedListener() {

			@Override
			public void onCursorChanged(int token, Object cookie, Cursor cursor) {
				if (cursor.moveToFirst()) {
					int count = cursor.getInt(0);// 因为数值只有一个所以不用while(cursor.movetoNext())
					counts[token] = count;// token就是传入的i
					adapter.notifyDataSetChanged();
				}
			}
		});
	}

	class FolderAdapter extends BaseAdapter {

		private View view;

		@Override
		public int getCount() {
			return names.length;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				view = View.inflate(FolderUi.this, R.layout.list_item_folder,
						null);
			} else {
				view = convertView;
			}
			ImageView icon = (ImageView) view.findViewById(R.id.iv_icon_folder);
			TextView name = (TextView) view.findViewById(R.id.tv_name_folder);
			TextView count = (TextView) view.findViewById(R.id.tv_count_folder);

			icon.setBackgroundResource(iconIds[position]);
			name.setText(names[position]);
			count.setText("" + counts[position]);
			if (position % 2 == 0) {
				view.setBackgroundColor(Color.WHITE);
			} else {
				view.setBackgroundColor(Color.GRAY);
			}
			return view;
		}

	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {

		Intent intent = new Intent(this, FolderDetail.class);

		intent.putExtra("position", position);
		startActivity(intent);

	}
}

2.文件夹详情页面设置



public class FolderDetail extends Activity implements OnClickListener {
	private int position;
	private folderListAdapter madapter;
	private String[] projection = { "body", "_id", "address", "date" };
	// 短信内容所在列的索引值 为 0
	private final int INDEX_BODY = 0;
	// 短信联系人电话所在列的索引值 为 2
	private final int INDEX_ADDRESS = 2;
	// 短信日期所在列的索引值 为 3
	private final int INDEX_DATE = 3;
	private ListView listView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		position = getIntent().getIntExtra("position", 0);

		setContentView(R.layout.activity_folder_detail);

		findViewById(R.id.btn_send).setOnClickListener(this);

		listView = (ListView) findViewById(R.id.lv_folder_detail);
		madapter = new folderListAdapter(FolderDetail.this, null);

		listView.setAdapter(madapter);
		madapter.notifyDataSetChanged();
		prepareData();
	}

	private void prepareData() {
		MyQueryHandler handler = new MyQueryHandler(getContentResolver());
		//根据点击的item查询不同的收件箱,发件箱
		handler.startQuery(110, madapter, Tools.getUriFromIndex(position),
				projection, null, null, "date desc");
		//当完成查询之后,监听该事件
		handler.setOnCursorChangedListener(new OnCursorChangedListener() {

			@Override
			public void onCursorChanged(int token, Object cookie, Cursor cursor) {
				madapter.notifyDataSetChanged();
			}
		});

	}

	class folderListAdapter extends CursorAdapter {

		private View view;

		public folderListAdapter(Context context, Cursor c) {
			super(context, c);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			view = View
					.inflate(context, R.layout.list_item_folder_detail, null);
			FolderDetailViewHolder vh = new FolderDetailViewHolder();

			vh.title = (TextView) view.findViewById(R.id.tv_title_list_item);

			vh.face = (ImageView) view.findViewById(R.id.iv_face_list_item);
			vh.address = (TextView) view
					.findViewById(R.id.tv_address_list_item);
			vh.body = (TextView) view.findViewById(R.id.tv_body_list_item);
			vh.date = (TextView) view.findViewById(R.id.tv_date_list_item);

			view.setTag(vh);

			return view;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			FolderDetailViewHolder vh = (FolderDetailViewHolder) view.getTag();
			// 设置内容
			vh.body.setText(cursor.getString(INDEX_BODY));

			// 设置时间
			long when = cursor.getLong(INDEX_DATE);
			String dateStr;
			if (DateUtils.isToday(when)) {
				dateStr = DateFormat.getTimeFormat(context).format(when);
			} else {
				dateStr = DateFormat.getDateFormat(context).format(when);
			}
			vh.date.setText(dateStr);

			// 设置联系人的名字
			String number = cursor.getString(INDEX_ADDRESS);
			String name = Tools.findNameByNumber(context, number);
			if (name == null) {// 无此联系人
				vh.address.setText(number);
			} else {
				vh.address.setText(name);
			}

			// 设置头像

			int contactId = Tools.findIDByNumber(context, number);
			if (contactId == -1) { // 无此联系人
				vh.face.setBackgroundResource(R.drawable.ic_unknow_contact_picture);
			} else {
				Bitmap bitmap = Tools.getFaceById(context, "" + contactId);
				if (bitmap == null) {// 联系人,无头像
					vh.face.setBackgroundResource(R.drawable.ic_contact_picture);
				} else {
					vh.face.setBackgroundDrawable(new BitmapDrawable(bitmap));
				}
			}
			
			//将日期一样的隐藏,只显示一个标题------(比较当前的和上一个的日期是否一样)
			if (cursor.getPosition() != 0) {
				cursor.moveToPosition(cursor.getPosition() - 1);// 移动到上一个
				long lastwhen = cursor.getLong(INDEX_DATE);
				String lastdateStr = null;
				if (DateUtils.isToday(lastwhen)) {
					lastdateStr = DateFormat.getTimeFormat(context).format(
							lastwhen);
				} else {
					lastdateStr = DateFormat.getDateFormat(context).format(
							lastwhen);
				}
				//比较当前和上一个日期是否一样,不一样就显示,否则隐藏
				if (!dateStr.equals(lastdateStr)) {

					vh.title.setVisibility(View.VISIBLE);
					vh.title.setText(dateStr);
				} else {
					vh.title.setVisibility(View.GONE);
				}
			} else {//这是特殊item (0),因为无法和-1比较,cursor的-1行为null 第0个一定是显示的
				long lastwhen = cursor.getLong(INDEX_DATE);
				String lastdateStr = null;
				if (DateUtils.isToday(lastwhen)) {
					lastdateStr = DateFormat.getTimeFormat(context).format(
							lastwhen);
				} else {
					lastdateStr = DateFormat.getDateFormat(context).format(
							lastwhen);
				}
				vh.title.setVisibility(View.VISIBLE);
				vh.title.setText(lastdateStr);
			}
		}

	}

	@Override
	public void onClick(View v) {
		Intent intent = new Intent(this,NewMessageUI.class);
		startActivity(intent);
	}

	static class FolderDetailViewHolder {

		public TextView title;
		public ImageView face;
		public TextView address;
		public TextView body;
		public TextView date;

	}
}

3.群组页面的设置

①.创建群组和会话id的关系表 (1.群组表:查找群组id可以获得群组名字   2.群组会话表:通过群组id的条件去查询每个群组里面的会话)

public class MySqliteHelper extends SQLiteOpenHelper {

	public MySqliteHelper(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, null, version);
	}
	public static final String TAB_GROUPS = "groups";
	public static final String TAB_THREAD_GROUPS = "thread_groups";
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table groups(_id integer primary " +
				"key autoincrement, group_name varchar(20));");
		db.execSQL("create table thread_groups(_id integer primary key autoincrement, " +
				"group_id integer ,thread_id integer);");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

	}

	
}

②创建单例表数据库和数据库的工具类

public class DBUtils {
	private Context context;
	private MySqliteHelper helper;
	private Uri uri = Uri.parse("content://laoluo.com.cn");

	private static DBUtils dbutils;

	private DBUtils(Context context) {
		this.context = context;
		helper = new MySqliteHelper(context, "messageMan", null, 1);
	}

	public static synchronized DBUtils getInstance(Context context) {
		if (dbutils == null) {
			dbutils = new DBUtils(context);
		}
		return dbutils;
	}

	// 增加群组
	public void createNewGroup(String name) {
		SQLiteDatabase db = helper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put("group_name", name);
		db.insert(MySqliteHelper.TAB_GROUPS, "_id", values);
		// 设置为null,cursor中有一个观察者监听
		// 1.内容处理者发送通知
		context.getContentResolver().notifyChange(uri, null);
	}

	// 查询所有群组
	public Cursor getAllgroup() {
		SQLiteDatabase db = helper.getReadableDatabase();
		Cursor cursor = db.query(MySqliteHelper.TAB_GROUPS, null, null, null,
				null, null, null);
		// 2.cursor接收
		cursor.setNotificationUri(context.getContentResolver(), uri);// 设置一个数据改变接收通知,接收这个uri的通知
		return cursor;
	}

	// 根据id删除该群组
	public void deleteGroupBy_id(int _id) {
		SQLiteDatabase db = helper.getWritableDatabase();
		db.delete(MySqliteHelper.TAB_GROUPS, " _id = " + _id, null);
		// 1.内容处理者发送通知
		context.getContentResolver().notifyChange(uri, null);
	}

	// 根据id 和 名字 更新群组
	public void updateGroupNameBy_id(int _id, String name) {
		SQLiteDatabase db = helper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put("group_name", name);
		db.update(MySqliteHelper.TAB_GROUPS, values, " _id = ?", new String[]{_id+""});
		// 1.内容处理者发送通知
		context.getContentResolver().notifyChange(uri, null);

	}
	
	//将会话id和群组id插入到数据库中
	public void insertThradIdAndGroupId(int threadId, int groupId) {
		SQLiteDatabase db = helper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put("thread_id", threadId);
		values.put("group_id", groupId);
		db.insert(MySqliteHelper.TAB_THREAD_GROUPS, null, values);
	}
	
	//通过群组id查找该群组中所有的会话id
	public Cursor getAllThreadIdByGroupId(int groupId) {
		SQLiteDatabase db  = helper.getReadableDatabase();
		Cursor cursor = db.query(MySqliteHelper.TAB_THREAD_GROUPS, null, " group_id = "+groupId, null, null, null, null);
		return cursor;
	}
}

③增加群组.更新群组和进入显示该群组的会话消息


public class GroupUi extends ListActivity implements OnItemLongClickListener,
		OnItemClickListener {

	private ListView listView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		listView = getListView();
		adapter = new GropListAdapter(this, null);
		listView.setAdapter(adapter);

		listView.setOnItemLongClickListener(this);
		listView.setOnItemClickListener(this);
		
		prepare();

	}

	private void prepare() {
		DBUtils dbu = DBUtils.getInstance(GroupUi.this);
		
		// 查询所有群组
		Cursor cursor = dbu.getAllgroup();

		// 将cursor改变为这个cursor
		adapter.changeCursor(cursor);
	}

	class GropListAdapter extends CursorAdapter {

		public GropListAdapter(Context context, Cursor c) {
			super(context, c);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {

			View view = View.inflate(context, R.layout.list_item_group, null);
			TextView name = (TextView) view.findViewById(R.id.tv_name_group);
			view.setTag(name);

			return view;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			//获取群组名字
			TextView name = (TextView) view.getTag();
			name.setText(cursor.getString(cursor.getColumnIndex("group_name")));
		}

	}

	public boolean onCreateOptionsMenu(Menu menu) {
		// 将 资料ID对应的文件转换为 菜单条目 ,并添加至 menu 中
		getMenuInflater().inflate(R.menu.activity_group, menu);
		return true;
	}

	@Override
	/**
	 * 1.响应菜单的点击事件
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_new_group:

			showCreateGroupDialog();

			break;
		}
		return true;
	}

	private AlertDialog dialog;
	private GropListAdapter adapter;

	//2.创建群组的Dialog
	private void showCreateGroupDialog() {
		AlertDialog.Builder adb = new AlertDialog.Builder(this);
		dialog = adb.create();
		View view = View.inflate(this, R.layout.dialog_new_group, null);
		final EditText etInputName = (EditText) view
				.findViewById(R.id.et_input_new_group);
		Button btnOk = (Button) view.findViewById(R.id.btn_ok);
		btnOk.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				String name = etInputName.getText().toString();
				if (TextUtils.isEmpty(name)) {
					Toast.makeText(GroupUi.this, "请输入群组名称", 0).show();
					return;
				}
				// 3.将群组名称保存至数据库
				DBUtils dbu = DBUtils.getInstance(GroupUi.this);
				dbu.createNewGroup(name);
				dialog.dismiss();
			}
		});
		dialog.setView(view, 0, 0, 0, 0);// 左上右下的边距
		dialog.show();
	}

	//点击item,根据群组id获取到该群组的会话id   再通过会话id去查找所有的会话消息
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		Cursor cursor = adapter.getCursor();
		cursor.moveToPosition(position);
		int groupId = cursor.getInt(0);//群组的id
		//通过群组的id获取到该群组中的所有会话id
		DBUtils dbUtils = DBUtils.getInstance(this);
		Cursor cursor2 = dbUtils.getAllThreadIdByGroupId(groupId);
		if(cursor2.getCount()==0){
			Toast.makeText(this, "该群组没有人,快增加点人气吧!!", Toast.LENGTH_SHORT).show();
		}else{
			// 如果有人的话,希望能过cursor2 拼凑出如: thread_id in (1,2);
			String subSql = convertCursor2Str(cursor2);
			Intent intent = new Intent(this,ConversationUi.class);
			intent.putExtra("subSql", subSql);
			startActivity(intent);
		}

	}

	private String convertCursor2Str(Cursor cursor2) {
		cursor2.moveToPosition(-1);
		StringBuilder sb=new StringBuilder("  thread_id in ( ");
		while(cursor2.moveToNext()){
			int threadId = cursor2.getInt(cursor2.getColumnIndex("thread_id"));
			sb.append(threadId+",");  //  thread_id in (1,
		}
		sb.replace(sb.lastIndexOf(","), sb.length(), ")");
		return sb.toString();
	}

	// listVIew的长按事件
	@Override
	public boolean onItemLongClick(AdapterView<?> parent, View view,
			int position, long id) {
		showEditGroupDialog(position);
		return true;
	}

	private void showEditGroupDialog(final int position) {
		AlertDialog.Builder adb = new AlertDialog.Builder(this);

		String items[] = new String[] { "编辑", "删除" };

		adb.setItems(items, new DialogInterface.OnClickListener() {
			@Override
			/**
			 * which 是点击的条目的位置
			 */
			public void onClick(DialogInterface dialog, int which) {
				if (which == 0) { // “编辑”
					showUpdateGroupDialog(position);
				} else { // 删除
					showConfirmDeleteDialog(position);
				}

			}
		});

		adb.show();
	}

	// 更新群组对话框
	protected void showUpdateGroupDialog(final int position) {
		AlertDialog.Builder adb = new AlertDialog.Builder(this);
		dialog = adb.create();
		View view = View.inflate(this, R.layout.dialog_new_group, null);
		
		TextView title = (TextView) view.findViewById(R.id.tv_title_dialog);
		title.setText("更新群组名称");
		
		final EditText etInputName = (EditText) view
				.findViewById(R.id.et_input_new_group);
		Button btnOk = (Button) view.findViewById(R.id.btn_ok);
		btnOk.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				String name = etInputName.getText().toString();
				if (TextUtils.isEmpty(name)) {
					Toast.makeText(GroupUi.this, "请输入群组名称", 0).show();
					return;
				}
			
				DBUtils dbu = DBUtils.getInstance(GroupUi.this);
				
				// 将群组名称更新保存至数据库
				Cursor cursor = adapter.getCursor();
				cursor.moveToPosition(position);//确认一下
				int _id = cursor.getInt(0);
				dbu.updateGroupNameBy_id(_id,name);
				dialog.dismiss();
			}
		});
		dialog.setView(view, 0, 0, 0, 0);// 左上右下的边距
		dialog.show();
	}

	//确认删除对话框
	protected void showConfirmDeleteDialog(final int position) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		
		builder.setTitle("删除群组");
		builder.setMessage("确定要删除这个群组吗");
		builder.setNegativeButton("确定", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				Cursor cursor = adapter.getCursor();
				cursor.moveToPosition(position);
				int _id = cursor.getInt(0);//获得第0列的值,就是_id(总共两列。_id和group_name 
				DBUtils dbUtils = DBUtils.getInstance(GroupUi.this);
				dbUtils.deleteGroupBy_id(_id);
			}
		});
		
		builder.setPositiveButton("取消", null);
		builder.show();
		
	}

}

④.长按ConversationUi中的item添加该信息到群组中

/**
	 * 响应listView条目的长按事件   保存该短信到群组中
	 */
	public boolean onItemLongClick(AdapterView<?> parent, View view,
			int position, long id) {
		if(isEditState){
			// 如果是编辑状态,直接退出
			return true;
		}
		//弹出群组
		showSelectGroupDialog(position);
		return true;
	}

	private void showSelectGroupDialog(final int position) {
		final DBUtils dbu = DBUtils.getInstance(ConversationUi.this);
		Cursor cursor = dbu.getAllgroup();//获得所有群组的cursor对象
		
		String groupNames[] = new String[cursor.getCount()];
		final int groupIds[] = new int[cursor.getCount()];
		
		while(cursor.moveToNext()){
			int groupId = cursor.getInt(0); // 获得群组ID
			String groupName = cursor.getString(1); // 获得群组名称
			
			//保存id和群组名字到数组中
			groupNames[cursor.getPosition()] = groupName;
			groupIds[cursor.getPosition()] = groupId;
		}
		cursor.close();
		
		AlertDialog.Builder builder = new AlertDialog.Builder(ConversationUi.this);
		builder.setTitle("选择群组");
		builder.setItems(groupNames, new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// 点击的群组的ID = groupIds[which ]
				int groupId = groupIds[which];
				
				Cursor cursor2 = myadapter.getCursor();
				cursor2.moveToPosition(position);
				
				//获得会话id
				int threadId = cursor2.getInt(MyConstants.INDEX_THREAD_ID);
				//将会话id和群组id保存进    (群组和会话的关系表中)
				dbu.insertThradIdAndGroupId(threadId,groupId);
			}
		});
		builder.show();
	}

⑤.点击群组,重新进入conversationUi,根据查询条件查询会话

//点击item,根据群组id获取到该群组的会话id   再通过会话id去查找所有的会话消息
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		Cursor cursor = adapter.getCursor();
		cursor.moveToPosition(position);
		int groupId = cursor.getInt(0);//群组的id
		//通过群组的id获取到该群组中的所有会话id
		DBUtils dbUtils = DBUtils.getInstance(this);
		Cursor cursor2 = dbUtils.getAllThreadIdByGroupId(groupId);
		if(cursor2.getCount()==0){
			Toast.makeText(this, "该群组没有人,快增加点人气吧!!", Toast.LENGTH_SHORT).show();
		}else{
			// 如果有人的话,希望能过cursor2 拼凑出如: thread_id in (1,2);
			String subSql = convertCursor2Str(cursor2);
			Intent intent = new Intent(this,ConversationUi.class);
			intent.putExtra("subSql", subSql);
			startActivity(intent);
		}

	}

	private String convertCursor2Str(Cursor cursor2) {
		cursor2.moveToPosition(-1);
		StringBuilder sb=new StringBuilder("  thread_id in ( ");
		while(cursor2.moveToNext()){
			int threadId = cursor2.getInt(cursor2.getColumnIndex("thread_id"));
			sb.append(threadId+",");  //  thread_id in (1,
		}
		sb.replace(sb.lastIndexOf(","), sb.length(), ")");
		return sb.toString();
	}

//7.点击item,根据群组id获取到该群组的会话id   再通过会话id去查找所有的会话消息
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			Cursor cursor = adapter.getCursor();
			cursor.moveToPosition(position);
			int groupId = cursor.getInt(0);//群组的id
			//通过群组的id获取到该群组中的所有会话id
			DBUtils dbUtils = DBUtils.getInstance(this);
			Cursor cursor2 = dbUtils.getAllThreadIdByGroupId(groupId);
			if(cursor2.getCount()==0){
				Toast.makeText(this, "该群组没有人,快增加点人气吧!!", Toast.LENGTH_SHORT).show();
			}else{
				// 如果有人的话,希望能过cursor2 拼凑出如: thread_id in (1,2);
				String subSql = convertCursor2Str(cursor2);
				Intent intent = new Intent(this,ConversationUi.class);
				intent.putExtra("subSql", subSql);
				startActivity(intent);
			}

		}


<span style="white-space:pre">		</span>//根据查询条件查询
<pre name="code" class="java">		String where = getIntent().getStringExtra("subSql");
		// 123是编号 myadapter是一个对象
		handler.startQuery(123, myadapter, MyConstants.URI_CONVERSATION,
				MyConstants.projection, where, null, "date desc");




4.搜索框的使用





①.设置xml文件

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_title"
    android:hint="@string/search_hint" >
</searchable>

②.设置SearchActivity

<activity
            android:name="com.example.message.SearchActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />//这是一个发送的消息
            </intent-filter>

            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>

③.设置该搜索框放在哪里
(放在ConversationUi页面中)

<activity
            android:name="com.example.message.ConversationUi"
            android:label="@string/app_name" >
            
            <meta-data android:name="android.app.default_searchable"
                   android:value="com.example.message.SearchActivity" />
        </activity>

当查询完之后就会跳到该SearchActivity中
④.配置SearchActivity


public class SearchActivity extends ListActivity {
	private ListView listView;
	private SearchListAdapter adapter;

	private String[] projection = { "_id", "address", "body", "date" };

	private final int INDEX_ADDRESS = 1;
	private final int INDEX_BODY = 2;
	private final int INDEX_DATE = 3;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		listView = getListView();

		// 通过intent 获得,在搜索框中输入的内容 ,系统固定格式
		Intent intent = getIntent();
		if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
			String query = intent.getStringExtra(SearchManager.QUERY);

			System.out.println("query::" + query);

			adapter = new SearchListAdapter(this, null);
			listView.setAdapter(adapter);

			doMySearch(query);
		}
	}

	private void doMySearch(String query) {
		MyQueryHandler myQueryHandler = new MyQueryHandler(getContentResolver());
		
		//查询sms表中和框中内容匹配的信息内容 
		myQueryHandler.startQuery(99, adapter, MyConstants.URI_ALL, projection,
				" body like '%" + query + "%'", null, "date desc");
	}

	class SearchListAdapter extends CursorAdapter {

		public SearchListAdapter(Context context, Cursor c) {
			super(context, c);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup arg2) {
			View view = View.inflate(context, R.layout.list_item_search, null);
			ViewHolder vh = new ViewHolder();

			vh.face = (ImageView) view.findViewById(R.id.iv_face_list_item);
			vh.address = (TextView) view
					.findViewById(R.id.tv_address_list_item);
			vh.body = (TextView) view.findViewById(R.id.tv_body_list_item);
			vh.date = (TextView) view.findViewById(R.id.tv_date_list_item);
			view.setTag(vh);

			return view;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			ViewHolder vh = (ViewHolder) view.getTag();
			//
			vh.body.setText(cursor.getString(INDEX_BODY));

			String dateStr = DateFormat.getDateFormat(context).format(
					cursor.getLong(INDEX_DATE));
			vh.date.setText(dateStr);

			String number = cursor.getString(INDEX_ADDRESS);
			String name = Tools.findNameByNumber(context, number);
			if (name == null) {
				vh.address.setText(number);
			} else {
				vh.address.setText(name);
			}

			int id = Tools.findIDByNumber(context, number);
			if (id == -1) {
				vh.face.setBackgroundResource(R.drawable.ic_unknow_contact_picture);
			} else {

				Bitmap bitmap = Tools.getFaceById(context, "" + id);
				if (bitmap == null) {
					vh.face.setBackgroundResource(R.drawable.ic_contact_picture);
				} else {
					vh.face.setBackgroundDrawable(new BitmapDrawable(bitmap));
				}
			}
		}

	}

	class ViewHolder {
		public ImageView face;
		public TextView address;
		public TextView body;
		public TextView date;
	}
}

⑤.添加一个建议,当打字的时候,下面会有一个建议的下拉框




①.改变xml.增加权限和搜索匹配

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_title"
    android:hint="@string/search_hint" 
    android:searchSuggestAuthority="com.example.message.provider.MySearchprovider"
    android:searchSuggestSelection=" ?">
</searchable>

②.设置一个搜索提供者

public class MySearchprovider extends SearchRecentSuggestionsProvider {
	//权限设置
	public final static String AUTHORITY = "com.example.message.provider.MySearchprovider";
	//匹配模式 为数据库查询和两行数据
	public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

	//换成系统可以知道的别名
	private String[] mprojection = { "_id as " + BaseColumns._ID,
			"address as " + SearchManager.SUGGEST_COLUMN_TEXT_1,
			"body as " + SearchManager.SUGGEST_COLUMN_TEXT_2,
			"body as " + SearchManager.SUGGEST_COLUMN_QUERY };//告诉系统这是我要查询的东西
	
	//构造函数
	public MySearchprovider() {
		setupSuggestions(AUTHORITY, MODE);
	}

	//查询语句执行完之后,就会跳到SearchActivity
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		String query = selectionArgs[0];
		System.out.println("qurey::" + query);// 就是输入框中的内容

		Cursor cursor = getContext().getContentResolver().query(
				MyConstants.URI_ALL, mprojection,
				" body like '%" + query + "%'", null, null);
		return cursor;
	}
}


③.配置manifest文件

 <provider android:name="com.example.message.provider.MySearchprovider"
            android:authorities="com.example.message.provider.MySearchprovider" >
        </provider>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值