关于使用AutoCompleteTextView和CursorAdapter查询电话联系人并找出电话号码 发表于50 天前 ⁄ Android, Android开发 ⁄ 暂无评论 ⁄ 被围观 热度 154˚+ 学习到这部分遇见很多的问题,看了很多人讲的关于这部分的文章同时结合自己的测试总结如下: 程序的目地是在AutoCompleteTextView里面输入联系人名同时自动找出建议的联系人,选取某个联系人后得到该联系人的电话号码。 这里关键是实现一个自己的XXXXXAdapter 继承自CursorAdapter。 要继承CursorAdapter类。必须实现(Override)的方法有: 一 先实现 public Cursor runQueryOnBackgroundThread(CharSequence constraint) 其中constraint就是输入的要查询的关键字,注意当选中输入框的时候,此方法就会被调用,此时constraint = null 如处理不当运行时会报错 这里的返回值Cursor.并将提供给方法public View newView( , ,)使用; 二 然后实现方法public View newView(Context context, Cursor cursor, ViewGroup parent),cursor是上一个方法产生的.这个方法里面需要构造一个在dropdown里显示的view(我把这个view理解为例表中每行显示内容的一个模型,这里可以通过LayoutInflater构造出需要的样式)。这个view作为返回值在bindView( )中还会用到。 三 再是实现方法public void bindView(View view, Context context, Cursor cursor) 。view就是第二步产生的。cursor是第一步产生的。这里就是把corsor里的数据绑定到view中对应的元素中去。注意此方法会多次频繁调用,所以不要有耗时的操作,不然会卡。 四 最后是 public CharSequence convertToString(Cursor cursor) 此方法是在我们选择某个联系人后会显示在AutoCompleteTextView中的内容。 AutoCompleteTextView在布局文件中 android:completionThreshold="1" 表示输入1个字符就显示出建议的联系人 android:completionHint="@string/strHint" 表示在建议例表最后显示的一句话,比如“输入*号给出全部联系人“ package my.chenpu.exsdk_05; import android.app.Service; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.provider.ContactsContract; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CursorAdapter; import android.widget.ImageView; import android.widget.TextView; public class ContactsAdapter extends CursorAdapter { private ContentResolver mContent; public ContactsAdapter(Context context, Cursor c) { super(context, c); // TODO Auto-generated constructor stub mContent = context.getContentResolver(); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { // TODO Auto-generated method stub Log.e("ContactsAdapter", "newView!!!"); // LayoutInflater inflater = LayoutInflater.from(context); // LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); // TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false); // view.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Service.LAYOUT_INFLATER_SERVICE); View view = (View) inflater.inflate(R.layout.ex05_09_cursoradapterview, null); TextView text = (TextView) view.findViewById(R.id.textinline); ImageView image = (ImageView) view.findViewById(R.id.viewinline); text.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))); image.setImageResource(R.drawable.min); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { // TODO Auto-generated method stub Log.e("ContactsAdapter", "bindView!!!"); // ((TextView) view).setText( // cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))); TextView text = (TextView) view.findViewById(R.id.textinline); text.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))); } @Override public Cursor runQueryOnBackgroundThread(CharSequence constraint) { // TODO Auto-generated method stub Log.e("ContactsAdapter", "runQueryOnBackgroundThread()!!!"); super.runQueryOnBackgroundThread(constraint); if(getFilterQueryProvider() != null) { Log.e("ContactsAdapter", "getFilterQueryProvider()!!!"); return getFilterQueryProvider().runQuery(constraint); } StringBuilder buffer = null; String[] args = null; Log.e("ContactsAdapter", "|" + constraint.toString() + "|"); if(constraint != null) { buffer = new StringBuilder(); buffer.append("UPPER("); buffer.append(ContactsContract.Contacts.DISPLAY_NAME); buffer.append(") GLOB ?"); args = new String[]{ constraint.toString().toUpperCase() + "*" //匹配以constraint开头的所有联系人名 }; } return mContent.query(ContactsContract.Contacts.CONTENT_URI, null, buffer == null? null : buffer.toString(), args, null); } //当选则某项后输入的位置显示的东西。 @Override public CharSequence convertToString(Cursor cursor) { // TODO Auto-generated method stub return cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); } } 以上就是对CursorAdapter的实现。其中的newView()方法很是让我郁闷了很久, 网上找了很久才大概了解了LayoutInflater的主要目地就是把一个布局文件导入到代码中来,下面//线的几行是不同的使用方法。 我的方法是自己写了个ex05_09_cursoradapterview.xml ,里面就是很简单的左边一个TextView显示联系人名,右边一个ImageView用于显示一个小图标。关于这部分网上很多查查就有了。 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { // TODO Auto-generated method stub Log.e("ContactsAdapter", "newView!!!"); // LayoutInflater inflater = LayoutInflater.from(context); // LayoutInflater inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); // TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false); // view.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Service.LAYOUT_INFLATER_SERVICE); View view = (View) inflater.inflate(R.layout.ex05_09_cursoradapterview, null); TextView text = (TextView) view.findViewById(R.id.textinline); ImageView image = (ImageView) view.findViewById(R.id.viewinline); text.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))); image.setImageResource(R.drawable.min); return view; } android.R.layout.simple_dropdown_item_1line 位置:mydroid/frameworks/base/core/res/res/layout/simple_dropdown_item_1line.xml <?xml version="1.0" encoding="utf-8"?> <!-- /* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml ** ** Copyright 2008, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ --> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" style="?android:attr/dropDownItemStyle" mce_style="?android:attr/dropDownItemStyle" android:textAppearance="?android:attr/textAppearanceLargeInverse" android:singleLine="true" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:ellipsize="marquee" /> 最后还有程序中使用ContactsContract,我看的书写的是Contacts,似乎是2.0后这个就不建议使用了。这里还有个查找联系人后如何找到属于此人的全部电话号码的问题。 这里提供一个链接 http://hi.baidu.com/wudaovip/blog/item/d7f166df13a8241c495403e7.html package my.chenpu.exsdk_05; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.os.Bundle; import android.provider.Contacts.People; import android.provider.ContactsContract; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AutoCompleteTextView; import android.widget.TextView; public class ex05_09 extends Activity { private AutoCompleteTextView myAutoCompleteTextView; private TextView myTextView; private Cursor contactCursor; private ContactsAdapter myContactsAdapter; //无用了 public static final String[] PEOPLE_PROJECTION = new String[]{ ContactsContract.Contacts._ID, ContactsContract.Contacts.PHOTO_ID, ContactsContract.Contacts.CONTENT_TYPE, ContactsContract.Contacts.CONTACT_STATUS_LABEL, ContactsContract.Contacts.DISPLAY_NAME }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.ex05_09); Log.e("ex05_09", "onCreate!!!"); myAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.myAutoCompleteTextView); myTextView = (TextView) findViewById(R.id.myTextView0902); ContentResolver content = getContentResolver(); contactCursor = content.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); myContactsAdapter = new ContactsAdapter(this, contactCursor); myAutoCompleteTextView.setAdapter(myContactsAdapter); myAutoCompleteTextView.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub String _id; Cursor phcursor; Cursor c = myContactsAdapter.getCursor(); c.moveToPosition(position); String number = ""; if(c.getInt(c.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER)) != 0) { _id = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID)); phcursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + _id, null, null); while(phcursor.moveToNext()) { number += phcursor.getString(phcursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)); number += " , "; } } else number = "无输入电话!"; myTextView.setText(c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)) + "的电话是:" + number); } }); } } Cursor c = DBHelper.query(); for(c.moveToFirst(); ! c.isAfterLast(); c.moveToNext()){ int id = c.getInt(0); String ty = c.getString(1); showDialog(“共有”+data_total+“条,id=”+id+“,类型=”+ty); }