当前位置: 代码迷 >> Android >> 【Android】利用AutoCompleteTextView控件联系人自动补全与依据联系人姓名查询电话
  详细解决方案

【Android】利用AutoCompleteTextView控件联系人自动补全与依据联系人姓名查询电话

热度:48   发布时间:2016-04-27 23:43:29.0
【Android】利用AutoCompleteTextView控件联系人自动补全与根据联系人姓名查询电话

自动补全功能是app比较友好的功能之一,但利用AutoCompleteTextView自动补全文本框控件完成起来并不简单,因为其中涉及到AutoCompleteTextView填充数据的适配器,与AutoCompleteTextView的监听器。同时还需要利用ContentResolver去查找设备的通讯录,当然,这与《【Android】利用安卓的数据接口、多媒体处理编写内存卡Mp3播放器app》(点击打开链接)中遍历MP3与《【Android】Sqlite数据库增删改查》(点击打开链接)中遍历Sqlite数据库是一样的。下面举一个小例子,说明AutoCompleteTextView的使用:


如上图,假设在用户手机中有3个联系人,现在有一个能自动补全的文本框,输入完名字,自动显示其在通讯录的电话。如果没有则给出相应的信息。

制作过程如下:

1、首先res\values\strings.xml字体文件,没什么好说:

<?xml version="1.0" encoding="utf-8"?><resources>    <string name="app_name">自动补全联系人与寻找其电话</string>    <string name="action_settings">Settings</string>    <string name="textView1">姓名:</string></resources>

2、之后是res\layout\activity_main.xml中的布局修改。一个垂直的线性布局中间放一个水平的线性布局,使TextView1与自动完成的文本框处于一行。之后一个显示结果的TextView2赋予id,此处的autoCompleteTextView1设定android:completionThreshold="1",是指用户输入1个字符就开始给出补全信息了。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/textView1"            android:textSize="24sp" />        <AutoCompleteTextView            android:id="@+id/autoCompleteTextView1"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:completionThreshold="1" />    </LinearLayout>    <TextView        android:id="@+id/textView2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:textSize="24sp" /></LinearLayout>

3、在AndroidManifest.xml申请读取联系人的权限

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.autocomplete"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="18" />    <uses-permission android:name="android.permission.READ_CONTACTS" /><!-- 要求读取通讯录 -->    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.autocomplete.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

4、MainActivity.java才是本app的重点,里面包含autoCompleteTextView自动文本框的适配器,用来填充数据的。数据是通过ContentResolver去查安卓设备中的联系人表查出来的姓名信息。之后,MainActivity本身实现TextWatcher接口,用来作为autoCompleteTextView自动文本框的监听器,当前用户选择自动补全的选项或者自己输入数据,都会给触发TextWatcher监听。根据联系人查询电话的时候,是需要同时对安卓中固有的两张表进行操作,一张是用户设备中的联系人姓名表,一张是与联系人姓名表同id排列的联系人电话表。具体代码具体如下:

package com.autocomplete;import android.net.Uri;import android.os.Bundle;import android.provider.ContactsContract.CommonDataKinds.Phone;import android.provider.ContactsContract.Contacts;import android.support.v4.widget.CursorAdapter;import android.text.Editable;import android.text.TextWatcher;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AutoCompleteTextView;import android.widget.FilterQueryProvider;import android.widget.Filterable;import android.widget.TextView;import android.app.Activity;import android.content.ContentResolver;import android.content.Context;import android.database.Cursor;//autoCompleteTextView自动文本框的适配器class ContactListAdapter extends CursorAdapter implements Filterable {	private ContentResolver resolver;	private String[] columns = new String[] { Contacts._ID,			Contacts.DISPLAY_NAME };// 一会儿,游标查询出来的表就两列,一列是id,一列是联系人姓名	public ContactListAdapter(Context context, Cursor c, int flags) {		// 调用父类构造方法,此处ContactListAdapter(Context context, Cursor		// c)方法已经过时,多出了一个参数flags		// 其实都没有什么用,flags扔个0给它就OK		super(context, c, flags);		resolver = context.getContentResolver();// 初始化ContentResolver	}	// 这里要自己形成一个下拉菜单	@Override	public void bindView(View view, Context arg1, Cursor cursor) {		((TextView) view).setText(cursor.getString(1));	}	@Override	public View newView(Context context, Cursor cursor, ViewGroup parent) {		LayoutInflater inflater = LayoutInflater.from(context);		TextView view = (TextView) inflater.inflate(				android.R.layout.simple_dropdown_item_1line, parent, false);		view.setText(cursor.getString(1));// 各项项的文字,就是游标查询出来的,联系人姓名那一列		return view;	}	@Override	public CharSequence convertToString(Cursor cursor) {		return cursor.getString(1);	}	@Override	public Cursor runQueryOnBackgroundThread(CharSequence constraint) {		FilterQueryProvider filter = getFilterQueryProvider();		if (filter != null) {			return filter.runQuery(constraint);		}		// 这里是指明游标的查询的表,与查询结果列		Uri uri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,				Uri.encode(constraint.toString()));		return resolver.query(uri, columns, null, null, null);	}}public class MainActivity extends Activity implements TextWatcher {	private AutoCompleteTextView autoCompleteTextView1;	private TextView textView2;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		// 注册组件		autoCompleteTextView1 = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);		textView2 = (TextView) findViewById(R.id.textView2);		// 构造autoCompleteTextView的适配器		ContentResolver contentResolver = getContentResolver();		String[] colmuns = new String[] { Contacts._ID, Contacts.DISPLAY_NAME };		Cursor cursor = contentResolver.query(Contacts.CONTENT_URI, colmuns,				null, null, null);		ContactListAdapter contactListAdapter = new ContactListAdapter(this,				cursor, 0);		// 指明autoCompleteTextView的适配器与监听器		autoCompleteTextView1.setAdapter(contactListAdapter);		autoCompleteTextView1.addTextChangedListener(this);	}	// 根据联系人的姓名查询电话	private String getQueryData(String name) {		String phoneNum = "";		// 查联系人姓名这张表,有无用户输入的姓名		ContentResolver contentResolver1 = getContentResolver();		String[] colmuns1 = new String[] { Contacts._ID, Contacts.DISPLAY_NAME };		Cursor cursor1 = contentResolver1.query(Contacts.CONTENT_URI, null,				null, null, null);		for (cursor1.moveToFirst(); !(cursor1.isAfterLast()); cursor1				.moveToNext()) {			String contactsName = cursor1.getString(cursor1					.getColumnIndex(colmuns1[1]));			// 如果有,则开始查联系人电话这张表			if (name.equals(contactsName)) {				int id = cursor1.getInt(cursor1.getColumnIndex(colmuns1[0]));				ContentResolver contentResolver2 = getContentResolver();				String[] colmuns2 = new String[] { Phone.CONTACT_ID,						Phone.NUMBER };				// 查询的联系人电话这张表时候,加入一个条件,就查目录联系人姓名那列数据中的id				// 由于联系人电话这张表与联系人姓名这张表是同id的				// 查询参数放在第三个参数这个位置				Cursor cursor2 = contentResolver2.query(Phone.CONTENT_URI,						null, colmuns2[0] + "=" + id, null, null);				if (cursor2.moveToNext()) {// 如果Cursor中有数据,要把初始位置为0的Cursor下拉一位才能拿到数据					phoneNum = cursor2.getString(cursor2							.getColumnIndex(colmuns2[1]));				}			}		}		return phoneNum;// 查到就返回相应的电话,没查到就扔回0	}	// autoCompleteTextView自动文本框的监听器,果断是等信息完完整整地摆到文本框才是查找	@Override	public void afterTextChanged(Editable arg0) {		String name = autoCompleteTextView1.getText() + "";		String phoneNum = getQueryData(name);		if (phoneNum.equals("")) {			textView2.setText("无此联系人!");		} else {			textView2.setText("电话为:" + phoneNum);		}	}	@Override	public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,			int arg3) {		// TODO Auto-generated method stub	}	@Override	public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {		// TODO Auto-generated method stub	}}


版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案