1. 程式人生 > >Android 通訊錄搜尋(中文和拼音檢索通訊錄)

Android 通訊錄搜尋(中文和拼音檢索通訊錄)

使用ContentResolver

在使用Google網頁搜尋功能時,只要輸入幾個字,就會在下方出現很多建議關鍵字。這次的範例,將以手機裡的通訊錄作為查詢物件,並設計出一個類似建議的可能聯絡人。要使用類似建議完成功能的AutoCompleteView Widget,以及示範如何使用ContentResolver來訪問通訊錄裡聯絡人的關鍵字,並將所有找到的聯絡人存入CursorAdapter裡。

執行此範例前,通訊錄裡頭必須要有一些資料,否則會造成程式為null的錯誤;執行的結果是輸入搜尋人員名字a,會將所有名字a開頭的人名撈出來,當輸入*,則是將所有通訊錄的人名顯示於AutoCompleteView的AdapterView裡,若發生了User選擇事件後,會將勾選的聯絡人電話號碼顯示於TextView,故此範例除了學會取得通訊錄的聯絡人資料之外,瞭解如何讀取ContentProvider裡的聯絡人電話,也是重要課題之一。

效果圖:

3.jpg


要取得通訊錄裡的資料,則是使用ContentResolver物件(content),以content.query的方式取出所有通訊錄裡的聯絡人,並以Cursor的方式取得其儲存內容(電話、姓名等)。在SDK2.1之後的聯絡人設定,可有多組電話"型別"與"電話",所使用的類物件為android.provider. Contacts,寫法與前幾版SDK有很大差別。最後設計AutoCompleteTextView. OnItemClickListener事件,這也是當User單擊聯絡人姓名之後,所攔截的事件處理,在其中便以Contacts- Adapter.getCursor()方法取得聯絡人的電話號碼。


Java程式碼:

import android.content.ContentResolver; 
import android.database.Cursor; 
import android.provider.ContactsContract; 
import android.widget.AdapterView; 
import android.widget.AutoCompleteTextView; 

public class EX05_09 extends Activity { 
private AutoCompleteTextView myAutoCompleteTextView; 
private TextView myTextView1; 
private Cursor contactCursor; 
private ContactsAdapter myContactsAdapter; 
/* 要撈出通訊錄的欄位 */ 
public static final String[] PEOPLE_PROJECTION = new String[] { 
ContactsContract.Contacts._ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts.DISPLAY_NAME 
}; 

/*
 
* Called when the activity is first created. 
*/ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.main); 
myAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.myAutoCompleteTextView); 
myTextView1 = (TextView) findViewById(R.id.myTextView1); 
/* 取得ContentResolver */ 
ContentResolver content = getContentResolver(); 
/* 取得通訊錄的Cursor */ 
contactCursor = content.query ( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PEOPLE_PROJECTION, null, null, "" ); 
/* 將Cursor傳入自己實現的ContactsAdapter */ 
myContactsAdapter = new ContactsAdapter(this, contactCursor); myAutoCompleteTextView.setAdapter(myContactsAdapter); myAutoCompleteTextView.setOnItemClickListener ( new AdapterView.OnItemClickListener() { 

@Override 
public void onItemClick (AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
/* 取得Cursor */ 
Cursor c = myContactsAdapter.getCursor(); 
/* 移到所點選的位置 */ 
c.moveToPosition(arg2); 
String number = c.getString ( c.getColumnIndexOrThrow (ContactsContract.CommonDataKinds.Phone.NUMBER) ); 
/* 當找不到電話時顯示無輸入電話 */ 
numbernumber = number == null ? "無輸入電話" : number; myTextView1.setText ( c.getString ( c.getColumnIndexOrThrow (ContactsContract.Contacts.DISPLAY_NAME) )+ "的電話是" + number ); 
} 
} );
 
} 

} 

 使用ContentResolver

src/irdc.ex05_09/ContactsAdapter.java


繼承CursorAdapter以cursor作為下拉選單data的class,重寫runQueryOnBackgroundThread這個方法,當輸入*號時,將所有資料找出。

Java程式碼:
import android.content.ContentResolver; 
import android.database.Cursor; 
import android.provider.ContactsContract; 

public class ContactsAdapter extends CursorAdapter { 
private ContentResolver mContent; 
public ContactsAdapter(Context context, Cursor c) { 
super(context, c); 
mContent = context.getContentResolver(); 
} 
@Override 
public void bindView(View view, Context context, Cursor cursor) { 
/* 取得通訊錄人員的名字 */ 
((TextView) view).setText ( cursor.getString ( cursor.getColumnIndexOrThrow (ContactsContract.Contacts.DISPLAY_NAME) ) ); 
} 

@Override 
public View newView(Context context, Cursor cursor, ViewGroup parent) { 
final LayoutInflater inflater = LayoutInflater.from(context); 
final TextView view = (TextView)inflater.inflate (android.R.layout.simple_dropdown_item_1line, parent, false); 
view.setText ( cursor.getString ( cursor.getColumnIndexOrThrow (ContactsContract.Contacts.DISPLAY_NAME) ) ); 
return view; 
} 

@Override 
public String convertToString(Cursor cursor) { 
return cursor.getString ( cursor.getColumnIndexOrThrow (ContactsContract.Contacts.DISPLAY_NAME) ); 
} 
@Override 
public Cursor runQueryOnBackgroundThread(CharSequence constraint) { 
if (getFilterQueryProvider() != null) { 
return getFilterQueryProvider().runQuery(constraint); 
} 
StringBuilder buffer = null; 
String[] args = null; 
if (constraint != null) { 
buffer = new StringBuilder(); 
buffer.append("UPPER("); 
buffer.append(ContactsContract.Contacts.DISPLAY_NAME); 
buffer.append(") GLOB ?"); 
args = new String[] { 
constraint.toString().toUpperCase() + "*" 
}; 
} 
return mContent.query ( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, EX05_09.PEOPLE_PROJECTION, buffer == null ? null : buffer.toString(), args, "" ); 
} 

} 

AndroidManifest.xml

將讀取通訊錄(Android.permission.READ_CONTACTS)的許可權開啟,否則,一執行程式就會發生異常。

Java程式碼:
<uses-permission android:name="android.permission.READ_CONTACTS"> </uses-permission> 

  這個範例介紹到搜尋通訊錄的方法,通過ContentResolver物件,也可以新增、修改及刪除通訊錄的人員資訊,除了通訊錄外,還可以訪問諸如Audio、Video、Images的資料。

新增public final Uri insert(Uri url, ContentValues values),ContentValue.put(key,value)key為欄位名稱,value為新增的資料。

修改public final int update(Uri uri, ContentValues values, String where, String[] selectionArgs,where為sql where後面的條件字串,selectionArgs為where裡的資料。

刪除public final int delete(Uri url, String where, String[] selectionArgs)。