`
as11051105
  • 浏览: 59335 次
  • 性别: Icon_minigender_1
  • 来自: 贵阳
社区版块
存档分类
最新评论

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" />
  • 大小: 6.9 KB
  • 大小: 6.8 KB
  • 大小: 121.9 KB
分享到:
评论

相关推荐

    android 加载本地联系人实现方法

    以上就是Android中加载本地联系人的一种实现方法,可以根据实际需求进行调整和优化,比如增加头像显示、分组显示等高级功能。通过这种方式,开发者能够方便地将用户的联系人信息整合到自己的应用程序中。

    android4.4源码 android-19源代码

    5. 应用程序:包括预装应用和用户安装的应用,如Phone、联系人、设置等。 二、KitKat新特性 1. ART:Android 4.4引入了新的运行时环境,ART采用预编译方式,提高了应用启动速度和整体性能。 2. 全新WebView:基于...

    Android--仿微信聊天界面

    - 联系人选择:提供联系人列表供用户选择聊天对象。 - 多选功能:支持多选图片、文件进行发送。 9. **性能优化**: - 数据分页加载:避免一次性加载大量数据导致内存消耗过大。 - 刷新机制:上拉加载更多历史...

    android-master.zip

    6. **Applications**:预装的应用程序,如联系人、日历、设置等。 **Android开发环境** 要浏览和修改Android源码,开发者通常需要设置Android Studio集成开发环境(IDE)以及相关的构建工具(如Gradle)。此外,还...

    android-dialer,.zip

    在Android系统中,拨号器是核心组件之一,负责处理电话拨打、联系人管理以及通话记录等功能。这个开源项目是从AOSP(Android Open Source Project)中提取出来的,意味着我们可以深入了解其内部工作原理,并且可以...

    Android-通过用户名首字母生成头像ImageView控件

    这个功能在社交应用或者联系人列表中很常见,特别是在用户没有上传真实头像的情况下。标题所提及的“Android-通过用户名首字母生成头像ImageView控件”就是这样一个功能,它根据用户的姓名首字母创建一个代表性的...

    Android-API大全

    14. **Permissions**:Android权限系统控制应用对敏感资源的访问,如读写联系人、访问GPS等。 15. **Multimedia APIs**:包括音频、视频播放和处理,如MediaPlayer、MediaRecorder和ExoPlayer。 Android API.chm和...

    Android4.1.1原版Contacts代码

    在Android 4.1.1 Contacts代码中,可以看到许多性能优化的实践,如使用CursorLoader异步加载联系人数据,避免阻塞主线程;使用SparseArray存储和查找联系人数据,减少内存消耗;以及在数据处理过程中采用批处理操作...

    Android-AppWeiLiao.rar

    - Android运行时权限:针对Android 6.0及以上版本,需要在运行时请求用户授权,如访问联系人、相册等。 10. **测试与调试**: - 单元测试:针对应用中的各个功能进行测试,确保其正确性。 - Espresso:Android ...

    获取本地联系人的头像并显示

    在Android开发中,获取本地联系人的头像是一个常见的需求,特别是在构建社交应用或者需要个性化展示用户信息时。这个过程涉及到Android系统的联系人API、图片处理以及UI显示等多个方面。下面我们将详细探讨如何实现...

    Android 异步联系人备份与恢复Demo

    在Android开发中,联系人管理是一项重要的功能,用户往往需要备份和恢复他们的联系人信息,以防止数据丢失。本教程将深入探讨如何使用VCard格式实现Android系统的异步联系人备份与恢复操作。 首先,VCard是一种通用...

    Android高级应用源码-android2.3.1系统自带联系人应用源码.rar

    《深入解析Android 2.3.1系统联系人应用源码》 在Android开发领域,对系统源码的研究是提升技术深度的重要途径。本篇将深入探讨Android 2.3.1版本中自带的联系人应用源码,帮助开发者了解其背后的实现原理,提升...

    Android-UI-of-weixin-client.rar_android_weixin_weixin ui_微信客户端_微

    3. **RecyclerView**:用于展示列表数据,如联系人列表、聊天记录等,它比ListView更高效,支持更复杂的布局和动画。 4. **Fragment**:在多屏和动态布局管理中,Fragment扮演着重要角色。微信应用中可能会有多个...

    Android--开发--jChat1.4.rar

    Android系统中的权限管理对即时通讯应用尤为重要,jChat1.4需要处理如录音、读写联系人、获取位置等敏感权限。同时,良好的推送通知策略能提高用户体验,如使用Foreground Service保证推送的及时性。 10. **测试与...

    Android-Hitalk一个MAL架构的即时通讯工具

    - **联系人模块**:管理好友列表、添加删除好友等。 - **设置模块**:包含应用设置、隐私设置、通知设置等。 通过对Hitalk的分析,我们可以看出它在即时通讯领域运用了众多先进的Android技术和最佳实践,为用户...

    新版Android开发教程.rar

    Android 进一步推进了 " 随时随地为每个人提供信息 " 这一企 业 目标的实现。 � Open Handset Alliance 汇集了多家业界巨头。运营商如: China Mobile 、 NTT DoCoMo 、 Vodafone 、 T-M obile 等;设备制造商如 ...

    android开发必备 手机联系人,字母索引列表,联动

    最后,通过Adapter将本地联系人数据集加载到ListView中。 三、查询本地联系人的相关信息 Android提供了ContentResolver接口来访问系统的联系人数据。我们可以使用ContentResolver的query()方法,配合...

    Android-QuickSearchBox程序源码.rar

    它不仅支持本地数据源,如联系人、日历等,还可以集成网络搜索,如Google搜索。 二、源码结构与关键组件 Android-QuickSearchBox程序源码主要包含以下几个关键组件: 1. **SearchableInfo**: 这是定义搜索源的...

    Android 获取手机联系人并按字母排序,且可根据字母右侧A~Z检索-IT计算机-毕业设计.zip

    在Android平台上,获取手机联系人并进行字母排序以及实现按字母检索功能是常见的需求,尤其在开发通讯录类的应用时。这个"Android 获取手机联系人并按字母排序,且可根据字母右侧A~Z检索"的项目,是一个适用于毕业...

Global site tag (gtag.js) - Google Analytics