使用Contacts Contract Content Provider操作通讯录最佳实践

简介: Android向所有被赋予READ_CONTACTS权限的应用程序提供了联系人信息数据库的完全访问权限。Contacts Contract使用3层数据模型去存储数据,下面介绍Contacts Contract的子类: 1.Data 表中的每行都定义了个人的数据集(电话号码,email地址,等等),用MIME类型区分开。尽管有为每个个人数据的类型预定义可用的列名(ContactsContr
Android向所有被赋予READ_CONTACTS权限的应用程序提供了联系人信息数据库的完全访问权限。Contacts Contract使用3层数据模型去存储数据,下面介绍Contacts Contract的子类:
1.Data 表中的每行都定义了个人的数据集(电话号码,email地址,等等),用MIME类型区分开。尽管有为每个个人数据的类型预定义可用的列名(ContactsContract.CommonDataKinds里装有合适的MIME类型),此表能被用来存储任何值。
当向Data表中加入数据的时候,你需要指定与数据集相关的Raw Contact。
2.RawContacts 从Android 2.0(API 5)向前,用户可以增加多个联系人账户的Provider。RawContacts表中的每行定义了一个与数据集相关的账户。说白了就是账户信息。

3.Contacts Contacts表的行聚合了RawContacts中的数据,每行代表了不同的人信息。




读取联系人详情:

首先在庆典文件中添加权限:<uses-permission android:name=”android.permission.READ_CONTACTS”/>

然后是访问Contacts Contract Content Provider:

private String[] getNames() {
    /**
     * Listing 8-36: Accessing the Contacts Contract Contact Content Provider
     */
    // Create a projection that limits the result Cursor
    // to the required columns.
    String[] projection = {
      ContactsContract.Contacts._ID,
      ContactsContract.Contacts.DISPLAY_NAME
    };
  
   // Get a Cursor over the Contacts Provider.
    Cursor cursor = 
      getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
                                 projection, null, null, null);
       
    // Get the index of the columns.
    int nameIdx = 
      cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
    int idIdx = 
      cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
  
    // Initialize the result set.
    String[] result = new String[cursor.getCount()];
  
    // Iterate over the result Cursor.
    while(cursor.moveToNext()) {
      // Extract the name.
      String name = cursor.getString(nameIdx);
      // Extract the unique ID.
      String id = cursor.getString(idIdx);
   
      result[cursor.getPosition()] = name + " (" + id + ")";
    } 
  
    // Close the Cursor.
    cursor.close();

    //
    return result;
  }
找到联系人姓名的联系信息:

 private String[] getNameAndNumber() {
    /**
     * Listing 8-37: Finding contact details for a contact name
     */
    ContentResolver cr = getContentResolver();
    String[] result = null;

    // Find a contact using a partial name match
    String searchName = "andy";
    Uri lookupUri = 
      Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,
                           searchName);

    // Create a projection of the required column names.
    String[] projection = new String[] {
      ContactsContract.Contacts._ID
    };

    // Get a Cursor that will return the ID(s) of the matched name.
    Cursor idCursor = cr.query(lookupUri, 
      projection, null, null, null);

    // Extract the first matching ID if it exists.
    String id = null;
    if (idCursor.moveToFirst()) {
      int idIdx = 
        idCursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
      id = idCursor.getString(idIdx);
    }

    // Close that Cursor.
    idCursor.close();

    // Create a new Cursor searching for the data associated with the returned Contact ID.
    if (id != null) {
      // Return all the PHONE data for the contact.
      String where = ContactsContract.Data.CONTACT_ID + 
        " = " + id + " AND " +
        ContactsContract.Data.MIMETYPE + " = '" +
        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE +
        "'";

      projection = new String[] {
        ContactsContract.Data.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.Phone.NUMBER
      };
      
      Cursor dataCursor = 
        getContentResolver().query(ContactsContract.Data.CONTENT_URI,
          projection, where, null, null);

      // Get the indexes of the required columns.
      int nameIdx = 
        dataCursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME);
      int phoneIdx = 
        dataCursor.getColumnIndexOrThrow(
          ContactsContract.CommonDataKinds.Phone.NUMBER);

      result = new String[dataCursor.getCount()];
      
      while(dataCursor.moveToNext()) {
        // Extract the name.
        String name = dataCursor.getString(nameIdx);
        // Extract the phone number.
        String number = dataCursor.getString(phoneIdx);

        result[dataCursor.getPosition()] = name + " (" + number + ")";
      }
      
      dataCursor.close();
    }
    
    return result;
  }

Contacts子类还提供了电话号码查找URI,用来帮助找到与特定电话号码相关的联系人,执行呼叫者ID查找:

private String performCallerId() {
    /**
     * Listing 8-38: Performing a caller-ID lookup
     */
    String incomingNumber = "(650)253-0000";
    String result = "Not Found";

    Uri lookupUri =
      Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                           incomingNumber);

    String[] projection = new String[] {
      ContactsContract.Contacts.DISPLAY_NAME
    };

    Cursor cursor = getContentResolver().query(lookupUri,
      projection, null, null, null);

    if (cursor.moveToFirst()) {
      int nameIdx = 
        cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
      
      result = cursor.getString(nameIdx);
    }

    cursor.close();

    
    return result;
  }
使用Intent创建和选择联系人,这是一种最佳的实践做法,其优势在于用户在执行相同任务的时候看到的一致的界面,这可以避免用户感到混淆,并且改善用户体验,下面是悬着一个联系人:

  private static int PICK_CONTACT = 0;

  private void pickContact() {
    Intent intent = new Intent(Intent.ACTION_PICK,
                               ContactsContract.Contacts.CONTENT_URI);  
    startActivityForResult(intent, PICK_CONTACT);  
  }
当选择好之后,作为返回Intent的data属性内的URI返回:

@Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if ((requestCode == PICK_CONTACT) && (resultCode == RESULT_OK)) {
      resultTextView.setText(data.getData().toString());
    }
  }
插入新联系人:,当然这需要一个权限:

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

之后就可以插入联系人啦!

Intent intent = 
      new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT,
                 ContactsContract.Contacts.CONTENT_URI);
    intent.setData(Uri.parse("tel:(650)253-0000"));

    intent.putExtra(ContactsContract.Intents.Insert.COMPANY, "Google");
    intent.putExtra(ContactsContract.Intents.Insert.POSTAL, 
      "1600 Amphitheatre Parkway, Mountain View, California");

    startActivity(intent);






目录
相关文章
|
Android开发
跨程序共享数据——Content Provider 之 ContentResolver基本用法 & 一个读取系统联系人的Demo
跨程序共享数据——Content Provider 之 ContentResolver基本用法 & 一个读取系统联系人的Demo
|
JSON API 数据格式
使用OData API批量删除Marketing Cloud里的contact
基本思路就是使用Odata的batch操作,在一个batch容器里放入多个delete动作。一个典型的payload如下面所示: –batch_1e89-cb21-3cdd Content-Type: multipart/mixed; boundary=changeset_b099-6fed-59d4 –changeset_b099-6fed-59d4 Content-Type: application/http Content-Transfer-Encoding: binary
192 0
使用OData API批量删除Marketing Cloud里的contact
调用Hybris API时遇到的错误消息Cannot find user with uid如何解决
调用Hybris API时遇到的错误消息Cannot find user with uid如何解决
102 0
|
Android开发
跨程序共享数据——Content Provider 之 ContentResolver基本用法 & 一个读取系统联系人的Demo
本模块共有四篇文章,参考郭神的《第一行代码》,对Content Provider的学习做一个详细的笔记,大家可以一起交流一下: 跨程序共享数据——Content Provider 之 运行时权限解析以及申请的实现(可完美解决java.
1311 0
|
数据库 Android开发 数据库管理