First, create a layout file. The interface is very simple. It is a search box and the following contact list:
Copy codeThe Code is as follows: <? Xml version = "1.0" encoding = "UTF-8"?>
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
Android: layout_width = "fill_parent"
Android: layout_height = "fill_parent"
Android: background = "# FFD3D7DF"
Android: orientation = "vertical"
Android: padding = "0dip">
<RelativeLayout
Android: layout_width = "fill_parent"
Android: layout_height = "wrap_content"
Android: layout_marginLeft = "3dip"
Android: layout_marginRight = "3dip"
Android: layout_marginTop = "3dip">
<EditText
Android: id = "@ + id/search_view"
Android: layout_width = "fill_parent"
Android: layout_height = "wrap_content"
Android: hint = "@ string/hint_search_contacts"
Android: paddingLeft = "32dip"
Android: singleLine = "true"
Android: textSize = "16sp"/>
<ImageView
Android: layout_width = "wrap_content"
Android: layout_height = "wrap_content"
Android: layout_alignLeft = "@ id/search_view"
Android: layout_centerVertical = "true"
Android: layout_marginLeft = "3dip"
Android: src = "@ drawable/contacts"/>
</RelativeLayout>
<ListView
Android: id = "@ + id/contact_list"
Android: layout_width = "fill_parent"
Android: layout_height = "wrap_content"
Android: layout_marginBottom = "0dip"
Android: layout_marginLeft = "0dip"
Android: layout_marginRight = "0dip"
Android: layout_marginTop = "0dip"
Android: layout_weight = "1.0"
Android: cacheColorHint = "#00000000"
Android: divider = "#00000000"
Android: dividerHeight = "0.1px"
Android: fadingEdge = "none"
Android: footerDividersEnabled = "false"
Android: listSelector = "@ null"
Android: paddingBottom = "0dip"
Android: paddingLeft = "0dip"
Android: paddingRight = "0dip"
Android: paddingTop = "0dip"/>
</LinearLayout>
Copy codeThe Code is as follows: <? Xml version = "1.0" encoding = "UTF-8"?>
<LinearLayout
Xmlns: android = "http://schemas.android.com/apk/res/android"
Android: orientation = "horizontal"
Android: layout_height = "wrap_content"
Android: layout_width = "fill_parent"
Android: paddingTop = "2dip"
Android: paddingBottom = "2dip"
Android: background = "@ color/list_item_background">
<ImageView
Android: id = "@ + id/photo"
Android: layout_height = "wrap_content"
Android: layout_width = "wrap_content"
Android: layout_marginLeft = "5dip"
Android: layout_gravity = "center_vertical"
Android: layout_weight = "1"
Android: src = "@ drawable/default_avatar"
/>
<LinearLayout
Android: orientation = "vertical"
Android: layout_height = "wrap_content"
Android: layout_width = "wrap_content"
Android: layout_gravity = "center_vertical"
Android: layout_marginLeft = "5dip"
Android: layout_weight = "100">
<TextView android: id = "@ + id/text1"
Android: typeface = "serif"
Android: singleLine = "true"
Style = "@ style/list_font_main_text"/>
<LinearLayout
Android: orientation = "horizontal"
Android: layout_height = "wrap_content"
Android: layout_width = "wrap_content"
Android: layout_marginTop = "3dip">
<TextView android: id = "@ + id/text2"
Android: typeface = "serif"
Android: singleLine = "true"
Style = "@ style/list_font_detail_text"/>
<TextView android: id = "@ + id/text3"
Android: ellipsize = "marquee"
Android: layout_marginLeft = "3dip"
Android: marqueeRepeatLimit = "marquee_forever"
Android: scrollHorizontally = "true"
Style = "@ style/list_font_detail_text"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Then click the event: (After clicking it, you need to return the selected contact number to the input box)
Copy codeThe Code is as follows: // get the contact Button Object and bind the onClick event
PhoneButton = (Button) findViewById (R. id. find_phone );
PhoneButton. setOnClickListener (new OnClickListener (){
Public void onClick (View v ){
// Select a number from the contact and process the callback result using the onActivityResult () method.
Intent intent = new Intent (context, ContactsActivity. class );
StartActivityForResult (intent, REQUEST_CODE );
}
});
/**
* Select the callback handler for the contact.
*/
@ Override
Public void onActivityResult (int reqCode, int resultCode, Intent data ){
Super. onActivityResult (reqCode, resultCode, data );
If (resultCode = RESULT_ OK ){
Switch (reqCode ){
Case REQUEST_CODE:
String phone = data. getStringExtra ("phone ");
PhoneEditText. setText (phone );
Break;
}
}
}
The following is the activity of the contact interface:Copy codeThe Code is as follows :/**
* Display contacts on users' mobile phones
*
* @ Author Mr. Z
* @ Time 2012-3-21
*
*/
Public class ContactsActivity extends Activity {
Private Context ctx = ContactsActivity. this;
Private TextView topTitleTextView;
Private ListView listView = null;
List <HashMap <String, String> contactsList = null;
Private EditText contactsSearchView;
Private ProgressDialog progressDialog = null;
// Message of data loading completion
Private final int MESSAGE_SUCC_LOAD = 0;
// Message of Data Query completion
Private final int MESSAGE_SUCC_QUERY = 1;
Private Handler handler = new Handler (){
@ Override
Public void handleMessage (Message msg ){
Super. handleMessage (msg );
Switch (msg. what ){
Case MESSAGE_SUCC_LOAD:
ListView. setAdapter (new ContactsAdapter (ctx ));
ProgressDialog. dismiss ();
Break;
Case MESSAGE_SUCC_QUERY:
ListView. setAdapter (new ContactsAdapter (ctx ));
Break;
}
}
};
Protected void onCreate (Bundle savedInstanceState ){
RequestWindowFeature (Window. FEATURE_NO_TITLE );
GetWindow (). setFlags (WindowManager. LayoutParams. FLAG_FULLSCREEN, WindowManager. LayoutParams. FLAG_FULLSCREEN );
Super. onCreate (savedInstanceState );
This. setContentView (R. layout. contacts );
// Use listView to display contacts
ListView = (ListView) findViewById (R. id. contact_list );
LoadAndSaveContacts ();
// Bind the Click Event of the listView item
ListView. setOnItemClickListener (new OnItemClickListener (){
@ SuppressWarnings ("unchecked ")
Public void onItemClick (AdapterView <?> AdapterView, View view, int position, long _ id ){
HashMap <String, String> map = (HashMap <String, String>) adapterView. getItemAtPosition (position );
String phone = map. get ("phone ");
// Pre-process the mobile phone number (remove the plus 86, spaces at the beginning and end, and "-" before the number)
Phone = phone. replaceAll ("^ (\ + 86 )","");
Phone = phone. replaceAll ("^ (86 )","");
Phone = phone. replaceAll ("-","");
Phone = phone. trim ();
// If the current number is not a mobile phone number
If (! SaleUtil. isValidPhoneNumber (phone ))
SaleUtil. createDialog (ctx, R. string. dialog_title_tip, getString (R. string. alert_contacts_error_phone ));
Else {
Intent intent = new Intent ();
Intent. putExtra ("phone", phone );
SetResult (RESULT_ OK, intent );
// Close the current window
Finish ();
}
}
});
ContactsSearchView = (EditText) findViewById (R. id. search_view );
ContactsSearchView. addTextChangedListener (new TextWatcher (){
Public void afterTextChanged (Editable s ){
}
Public void beforeTextChanged (CharSequence s, int start, int count, int after ){
}
Public void onTextChanged (CharSequence s, int start, int before, int count ){
QueryContacts (s. toString ());
}
});
}
/**
* Load and store contact data
*/
Private void loadAndSaveContacts (){
ProgressDialog = ProgressDialog. show (ctx, null, "loading contact data ...");
New Thread (){
@ Override
Public void run (){
// Obtain contact data
ContactsList = findContacts ();
// Temporarily store contact data
DBHelper. saveContacts (ctx, contactsList );
// Send a message notification to update the UI
Handler. sendEmptyMessage (MESSAGE_SUCC_LOAD );
}
}. Start ();
}
/**
* Obtain contacts from the local temporary library based on the conditions
*
* @ Param keyWord: Query keywords
*/
Private void queryContacts (final String keyWord ){
New Thread (){
@ Override
Public void run (){
// Obtain contact data
ContactsList = DBHelper. findContactsByCond (ctx, keyWord );
// Send a message notification to update the UI
Handler. sendEmptyMessage (MESSAGE_SUCC_QUERY );
}
}. Start ();
}
/**
* Get mobile phone contact information
*
* @ Return List <HashMap <String, String>
*/
Public List <HashMap <String, String> findContacts (){
List <HashMap <String, String> list = new ArrayList <HashMap <String, String> ();
// Query contacts
Cursor contactsCursor = ctx. getContentResolver (). query (ContactsContract. Contacts. CONTENT_URI, null, null, PhoneLookup. DISPLAY_NAME + "collate localized asc ");
// Name index
Int nameIndex = 0;
// Contact name
String name = null;
// Contact Profile ID
String photoId = null;
// Contact ID index value
String contactsId = null;
// Query the contact's phone number
Cursor phoneCursor = null;
While (contactsCursor. moveToNext ()){
NameIndex = contactsCursor. getColumnIndex (PhoneLookup. DISPLAY_NAME );
Name = contactsCursor. getString (nameIndex );
PhotoId = contactsCursor. getString (contactsCursor. getColumnIndex (PhoneLookup. PHOTO_ID ));
ContactsId = contactsCursor. getString (contactsCursor. getColumnIndex (ContactsContract. Contacts. _ ID ));
PhoneCursor = getContentResolver (). query (ContactsContract. response. Phone. CONTENT_URI, null, ContactsContract. CommonDataKinds. Phone. CONTACT_ID + "=" + contactsId, null, null );
// Traverse the contact number (one person corresponds to multiple phone numbers)
While (phoneCursor. moveToNext ()){
HashMap <String, String> phoneMap = new HashMap <String, String> ();
// Add a contact name
PhoneMap. put ("name", name );
// Add a Contact Profile
PhoneMap. put ("photo", photoId );
// Add a phone number
PhoneMap. put ("phone", phoneCursor. getString (phoneCursor. getColumnIndex (ContactsContract. CommonDataKinds. Phone. NUMBER )));
// Add the number type (residential phone number, mobile phone number, or organization phone number)
PhoneMap. put ("type", getString (ContactsContract. response. Phone. getTypeLabelResource (phoneCursor. getInt (phoneCursor. getColumnIndex (ContactsContract. response. Phone. TYPE )))));
List. add (phoneMap );
}
PhoneCursor. close ();
}
ContactsCursor. close ();
Return list;
}
/**
* Get the Contact Profile
*
* @ Param context
* @ Param photoId: ID of the Avatar
* @ Return Bitmap
*/
Public static Bitmap getPhoto (Context context, String photoId ){
Bitmap bitmap = BitmapFactory. decodeResource (context. getResources (), R. drawable. default_avatar );
If (photoId! = Null & "". equals (photoId )){
String [] projection = new String [] {ContactsContract. Data. DATA15 };
String selection = "ContactsContract. Data. _ ID =" + photoId;
Cursor cur = context. getContentResolver (). query (ContactsContract. Data. CONTENT_URI, projection, selection, null, null );
If (cur! = Null ){
Cur. moveToFirst ();
Byte [] contactIcon = null;
ContactIcon = cur. getBlob (cur. getColumnIndex (ContactsContract. Data. DATA15 ));
If (contactIcon! = Null ){
Bitmap = BitmapFactory. decodeByteArray (contactIcon, 0, contactIcon. length );
}
}
}
Return bitmap;
}
/**
* Custom contact Adapter
*/
Class ContactsAdapter extends BaseAdapter {
Private LayoutInflater inflater = null;
Public ContactsAdapter (Context ctx ){
Inflater = LayoutInflater. from (ctx );
}
Public int getCount (){
Return contactsList. size ();
}
Public Object getItem (int position ){
Return contactsList. get (position );
}
Public long getItemId (int position ){
Return position;
}
Public View getView (int position, View convertView, ViewGroup parent ){
ViewHolder holder = null;
If (convertView = null ){
Holder = new ViewHolder ();
ConvertView = inflater. inflate (R. layout. contacts_listview_item, null );
Holder. text1 = (TextView) convertView. findViewById (R. id. text1 );
Holder. text2 = (TextView) convertView. findViewById (R. id. text2 );
Holder. text3 = (TextView) convertView. findViewById (R. id. text3 );
ConvertView. setTag (holder );
} Else {
Holder = (ViewHolder) convertView. getTag ();
}
Holder. text1.setText (contactsList. get (position). get ("name "));
Holder. text2.setText (contactsList. get (position). get ("type "));
Holder. text3.setText (contactsList. get (position). get ("phone "));
Return convertView;
}
Public final class ViewHolder {
Private TextView text1;
Private TextView text2;
Private TextView text3;
}
}
}
Query Method statement:Copy codeThe Code is as follows :/**
* Query contact data based on conditions
*
* @ Param context
* @ Param keyWord: Query keywords
* @ Return List <HashMap <String, String>
*/
Public static List <HashMap <String, String> findContactsByCond (Context context, String keyWord ){
List <HashMap <String, String> list = new ArrayList <HashMap <String, String> ();
SQLiteDatabase db = DBHelper. getSQLiteDb (context );
String SQL = "select * from contacts where name like '" + keyWord + "%' or name_alias like '" + keyWord + "% 'order by _ id ";
// Query data
Cursor cursor = db. rawQuery (SQL, null );
While (cursor. moveToNext ()){
HashMap <String, String> map = new HashMap <String, String> ();
Map. put ("name", cursor. getString (cursor. getColumnIndex ("name ")));
Map. put ("phone", cursor. getString (cursor. getColumnIndex ("phone ")));
Map. put ("type", cursor. getString (cursor. getColumnIndex ("type ")));
Map. put ("photo", cursor. getString (cursor. getColumnIndex ("photo ")));
List. add (map );
}
Cursor. close ();
Db. close ();
Return list;
}
/**
* Store contact information
*
* @ Param context
* @ Param contactsList contact list
*/
Public static void saveContacts (Context context, List <HashMap <String, String> contactsList ){
SQLiteDatabase db = DBHelper. getSQLiteDb (context );
// Enable transaction control
Db. beginTransaction ();
Try {
// Clear the contact data first
Db.exe cSQL ("drop table if exists contacts ");
Db.exe cSQL ("create table contacts (_ id integer not null primary key autoincrement, name varchar (50), name_alias varchar (10), phone varchar (30 ), type varchar (50), photo varchar (50 ))");
String SQL = null;
For (HashMap <String, String> contactsMap: contactsList ){
SQL = String. format ("insert into contacts (name, name_alias, phone, type, photo) values ('% s',' % s ', '% s') ", contactsMap. get ("name"), SaleUtil. getPinYinFirstAlphabet (contactsMap. get ("name"), contactsMap. get ("phone"), contactsMap. get ("type"), contactsMap. get ("photo "));
Db.exe cSQL (SQL );
}
// Set the transaction flag to successful
Db. setTransactionSuccessful ();
} Finally {
// End the transaction
Db. endTransaction ();
Db. close ();
}
}
Tool class:Copy codeThe Code is as follows :/**
* Determine whether the customer's mobile phone number meets the rules
*
* @ Param userPhone: the customer's mobile phone number
* @ Return true | false
*/
Public static boolean isValidPhoneNumber (String userPhone ){
If (null = userPhone | "". equals (userPhone ))
Return false;
Pattern p = Pattern. compile ("^ 0? 1 [0-9] {10 }");
Matcher m = p. matcher (userPhone );
Return m. matches ();
}
/**
* Get the first letter of Chinese pinyin
*
* @ Param chinese
* @ Return first letter of Pinyin
*/
Public static String getPinYinFirstAlphabet (String chinese ){
String convert = "";
For (int j = 0; j <chinese. length (); j ++ ){
Char word = chinese. charAt (j );
String [] pinyinArray = PinyinHelper. toHanyuPinyinStringArray (word );
If (pinyinArray! = Null ){
Convert + = pinyinArray [0]. charAt (0 );
} Else {
Convert + = word;
}
}
Return convert;
}
Add permissions;Copy codeThe Code is as follows: <! -- Access contact permissions -->
<Uses-permission android: name = "android. permission. READ_CONTACTS"/>