Android 代碼新增聯繫人至手機通訊錄中

因項目需求,需要將本產品的客服電話信息,默默寫入用戶手機通訊錄中,作爲一個程序員,內心是拒絕的,但仍要實現該功能。

1. 動態申請讀寫權限

首先,在 Maniifest.xml 文件中添加如下兩個權限的聲明:

  <uses-permission android:name="android.permission.READ_CONTACTS"/>
  <uses-permission android:name="android.permission.WRITE_CONTACTS"/>

然後在代碼中需要用到讀寫權限時,動態申請權限:

requestRuntimePermission(new String[]{Manifest.permission.READ_CONTACTS,
		Manifest.permission.WRITE_CONTACTS}, new PermissionListener() {
	@Override
	public void onGranted() {
		//todo 處理接下來的流程
	}

	@Override
	public void onDenied(List<String> deniedPermission) {
		showToast("權限被拒絕");
	}

});

2. 判斷該聯繫人是否存在,如果存在,僅追加手機號碼;不存在,則新增該聯繫人的頭像、姓名及手機號等相關信息。

/**
 * 添加聯繫人信息
 *
 */
public static void insertConstacts(Context context, String name, List<String> list) {
	try {
		//該店管家用戶是否存在,存在的話,就追加號碼,不存在新增聯繫人
		long rawContactId = getContactsId(context, name);
		ContentValues values = new ContentValues();

		if (rawContactId == 0 ) {
			//插入raw_contacts表,並獲取_id屬性
			Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
			ContentResolver resolver = context.getContentResolver();
			rawContactId = ContentUris.parseId(resolver.insert(uri, values));

			//插入data表
			uri = Uri.parse("content://com.android.contacts/data");

			//add Name
			values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
			values.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
			values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
			resolver.insert(uri, values);
			values.clear();

			//寫入頭像
			Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_poraital);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
			out.flush();
			out.close();
			values.clear();
			values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
			values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
			values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
			context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
			
		}

		//寫入手機號碼
		values.clear();
		values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone1);
        values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        //插入data表
        Uri uri = Uri.parse("content://com.android.contacts/data");
        context.getContentResolver().insert(uri, values);

	} catch (Exception e) {
		Log.i(TAG, "insertConstacts:  e = " + e.getMessage());
		e.printStackTrace();
	}

}

    /**
     * 判斷某個手機號是否存在
     */
    public static boolean isThePhoneExist(Context context, String phoneNum) {
        //uri=  content://com.android.contacts/data/phones/filter/#
        Cursor cursor = null;
        try {
            Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
            ContentResolver resolver = context.getContentResolver();
            cursor = resolver.query(uri, new String[]{ContactsContract.Data.DISPLAY_NAME},
                    null, null, null); //從raw_contact表中返回display_name
            if (cursor.moveToFirst()) {
                //Log.i(TAG, "name=" + cursor.getString(0) + " , phoneNum = " + phoneNum);
                cursor.close();
                return true;
            }
        } catch (Exception e) {
            //Log.i(TAG, "163 e =" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        return false;
    }

3. 查詢數據庫中所有的聯繫人

/**
 * 獲取所有聯繫人信息
 */
public static List<SysContactsListBean> getAllSysContacts(Context context) {
	List<SysContactsListBean> list = new ArrayList<>();
	try {
		ContentResolver resolver = context.getContentResolver();
		SysContactsListBean sysContactsListBean;
		Uri uri = Uri.parse("content://com.android.contacts/data/phones");

		Cursor cursor1 = resolver.query(uri,
				new String[]{ContactsContract.Data.RAW_CONTACT_ID,
						ContactsContract.Data.DISPLAY_NAME,
						ContactsContract.CommonDataKinds.Phone.NUMBER},
				null, null, null);

		while (cursor1.moveToNext()) {
			sysContactsListBean = new SysContactsListBean();
			sysContactsListBean.setCustomerId(cursor1.getLong(0));
			sysContactsListBean.setCustomerName(cursor1.getString(1));
			sysContactsListBean.setPhoneNumber(cursor1.getString(2));
			list.add(sysContactsListBean);
		}
	} catch (Exception e) {
		e.printStackTrace();
	}

	if (!CollectorUtils.isEmpty(list)) {
		Collections.sort(list, new Comparator<SysContactsListBean>() {
			@Override
			public int compare(SysContactsListBean o1, SysContactsListBean o2) {
				return o2.getCustomerName().compareTo(o1.getCustomerName());
			}
		});
	}
	return list;
}

4. 總結

關於通訊錄的更多操作可參考鏈接:https://www.cnblogs.com/liaojie970/p/5744580.html
還有幾個表需要特別注意:

4.1 raw_contacts:存放聯繫人的 ID,_id屬性爲主鍵,聲明爲autoincrement,即不需要手動設置,其他屬性也不需要手動設置就有默認值;display_name屬性爲姓名;sort_key屬性可以用於查詢後的排序

4.2 mimetypes:存放數據的類型,比如"vnd.android.cursor.item/name"表示“姓名”類型的數據,"vnd.android.cursor.item/phone_v2"表示“電話”類型的數據;

4.3 data:存放具體的數據;raw_contact_id 屬性用來連接raw_contacts表,每條記錄表示一個具體數據;raw_contact_id 需要重點記住,手機中顯示的每一個聯繫人對應一個固定的raw_contact_id,raw_contact_id對應着 raw_contacts表的 _id ,他倆是相同的值,兩個表之間的關係必須理清。(我剛開始就是沒有理清表之間的關係,以及各個字段代表的意思,做起來就感覺很混亂,這3個表很重要)我們主要的數據(email、phone等)都存放在data表;

ps:有些手機系統下,data 表的 raw_contact_id 和 data 表的 raw_contacts表的 _id 不一定相同,如果用 後者的id 作爲主鍵來追加手機號碼,就會出現追加不成功的現象。切記,切記。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章