用户登录
用户注册

分享至

Android访问和加载本地联系人的代码实现

  • 作者: 那晚越女说我?
  • 来源: 51数据库
  • 2020-08-21

在Android开发中,我们经常会遇到访问和加载本地联系人的情况,毕竟手机中联系人是最重要的数据之一,很多手机应用都会需要手机联系人的信息,比如姓名、手机号码等。本文通过一个简单的例子以及Android代码,来实现一个本地联系人加载读取的功能。

首先先建布局文件,界面很简单,就是一个搜索框和下面的联系人列表:

<?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>
<?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>

然后是点击事件:(点击后要把选择的联系人号码返回到输入框里)

// 获取联系人按钮对象并绑定onClick单击事件?
phoneButton = (Button) findViewById(R.id.find_phone);?
phoneButton.setOnClickListener(new OnClickListener() {?
public void onClick(View v) {?
// 从联系人选择号码,再通过onActivityResult()方法处理回调结果?
Intent intent = new Intent(context, ContactsActivity.class);?
startActivityForResult(intent, REQUEST_CODE);?
}?
});?
/**?
* 选择联系人的回调处理函数?
*/?
@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;?
}?
}?
}

下面就是联系人界面的activity了:

/**?
* 显示用户手机上的联系人?
*?
* @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;?
// 数据加载完成的消息?
private final int MESSAGE_SUCC_LOAD = 0;?
// 数据查询完成的消息?
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);?
// 使用listView显示联系人?
listView = (ListView) findViewById(R.id.contact_list);?
loadAndSaveContacts();?
// 绑定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");?
// 对手机号码进行预处理(去掉号码前的+86、首尾空格、“-”号等)?
phone = phone.replaceAll("^(\\+86)", "");?
phone = phone.replaceAll("^(86)", "");?
phone = phone.replaceAll("-", "");?
phone = phone.trim();?
// 如果当前号码并不是手机号码?
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);?
// 关闭当前窗口?
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());?
}?
});?
}?
/**?
* 加载并存储联系人数据?
*/?
private void loadAndSaveContacts() {?
progressDialog = ProgressDialog.show(ctx, null, "正在加载联系人数据...");?
new Thread() {?
@Override?
public void run() {?
// 获取联系人数据?
contactsList = findContacts();?
// 临时存储联系人数据?
DBHelper.saveContacts(ctx, contactsList);?
// 发送消息通知更新UI?
handler.sendEmptyMessage(MESSAGE_SUCC_LOAD);?
}?
}.start();?
}?
/**?
* 根据条件从本地临时库中获取联系人?
*?
* @param keyWord 查询关键字?
*/?
private void queryContacts(final String keyWord) {?
new Thread() {?
@Override?
public void run() {?
// 获取联系人数据?
contactsList = DBHelper.findContactsByCond(ctx, keyWord);?
// 发送消息通知更新UI?
handler.sendEmptyMessage(MESSAGE_SUCC_QUERY);?
}?
}.start();?
}?
/**?
* 获取手机联系人信息?
*?
* @return List<HashMap<String, String>>?
*/?
public List<HashMap<String, String>> findContacts() {?
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();?
// 查询联系人?
Cursor contactsCursor = ctx.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, PhoneLookup.DISPLAY_NAME + " COLLATE LOCALIZED ASC");?
// 姓名的索引?
int nameIndex = 0;?
// 联系人姓名?
String name = null;?
// 联系人头像ID?
String photoId = null;?
// 联系人的ID索引值?
String contactsId = null;?
// 查询联系人的电话号码?
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.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactsId, null, null);?
// 遍历联系人号码(一个人对应于多个电话号码)?
while (phoneCursor.moveToNext()) {?
HashMap<String, String> phoneMap = new HashMap<String, String>();?
// 添加联系人姓名?
phoneMap.put("name", name);?
// 添加联系人头像?
phoneMap.put("photo", photoId);?
// 添加电话号码?
phoneMap.put("phone", phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));?
// 添加号码类型(住宅电话、手机号码、单位电话等)?
phoneMap.put("type", getString(ContactsContract.CommonDataKinds.Phone.getTypeLabelResource(phoneCursor.getInt(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)))));
list.add(phoneMap);?
}?
phoneCursor.close();?
}?
contactsCursor.close();?
return list;?
}?
/**?
* 获取联系人头像?
*?
* @param context 上下文环境?
* @param photoId 头像ID?
* @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;?
}?
/**?
* 自定义联系人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;?
}?
}?
}

查询方法语句:

/**?
* 根据条件查询联系人数据?
*?
* @param context 上下文环境?
* @param keyWord 查询关键字?
* @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";?
// 查询数据?
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;?
}?
/**?
* 存储联系人信息?
*?
* @param context 上下文环境?
* @param contactsList 联系人列表?
*/?
public static void saveContacts(Context context, List<HashMap<String, String>> contactsList) {?
SQLiteDatabase db = DBHelper.getSQLiteDb(context);?
// 开启事务控制?
db.beginTransaction();?
try {?
// 先将联系人数据清空?
db.execSQL("drop table if exists contacts");?
db.execSQL("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','%s','%s')", contactsMap.get("name"), SaleUtil.getPinYinFirstAlphabet(contactsMap.get("name")), contactsMap.get("phone"), contactsMap.get("type"), contactsMap.get("photo"));?
db.execSQL(sql);?
}?
// 设置事务标志为成功?
db.setTransactionSuccessful();?
} finally {?
// 结束事务?
db.endTransaction();?
db.close();?
}?
}

工具类:

/**?
* 判断客户手机号码是否符合规则?
*?
* @param userPhone 客户手机号码?
* @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();?
}?
/**?
* 获取中文的拼音首字母?
*?
* @param chinese 中文?
* @return 拼音首字母?
*/?
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;?
}

最后加上权限就行了;

 <!-- 访问联系人的权限 -->
 <uses-permission android:name="android.permission.READ_CONTACTS"/>
软件
前端设计
程序设计
Java相关