Contact Management

The basic tasks involved in contact management operations are creating and updating contacts, retrieving and deleting persons, and linking contacts and persons. The following sections provide you with the fundamental building blocks for managing contact details in the Contacts database.

Connecting to the Contact Service

To initialize the contact service and use the functions and data types of the Contacts API, you must include the <contacts.h> header file in your application. To be able to access the Contacts database and operations, such as fetching, inserting, or updating, you must also connect to the contact service by calling the contacts_connect() function.

#include <contacts.h>

int error_code;
error_code = contacts_connect();

if (error_code != CONTACTS_ERROR_NONE)
    dlog_print(DLOG_ERROR, LOG_TAG, "failed to connect contacts: error code = %d", error_code);

When you no longer need it, disconnect from the contact service using the contacts_disconnect() function.

Note
To use the Contacts API, your application has to request permission by adding the following privileges to the tizen-manifest.xml file in the application package:

<privileges>
   <privilege>http://tizen.org/privilege/contact.read</privilege>
   <privilege>http://tizen.org/privilege/contact.write</privilege>
</privileges>

Retrieving Persons

You can retrieve person details in many ways:

  • If a person ID is known in your application, you can retrieve the person’s details using the contacts_db_get_record() function, whose first parameter is the _contacts_person._uri view:

    contacts_record_h person = NULL;
    const int person_id = ... /* Get the person ID */
    int error_code;
    
    error_code = contacts_db_get_record(_contacts_person._uri, person_id, &person);
    
    if (error_code != CONTACTS_ERROR_NONE)
        dlog_print(DLOG_ERROR, LOG_TAG, "failed to get record: error code = %d", error_code);
    
  • If you need to retrieve a list of persons matching a search keyword without knowing a specific person ID, you can use the contacts_db_search_records() function. The third parameter is the offset, meaning the record index from which to search, and the fourth parameter sets a limit to the number of results, where 0 means that all the matched records are retrieved.

    The following example shows how to find all person records that contain the keyword “John”.

    contacts_list_h list = NULL;
    
    error_code = contacts_db_search_records(_contacts_person._uri, "John", 0, 0, &list);
    
    if (error_code != CONTACTS_ERROR_NONE)
        dlog_print(DLOG_ERROR, LOG_TAG, "failed to search records: error code = %d", error_code);
    
  • If you have more complex search requirements, you can use queries and filters to retrieve records:

    • Queries are used to retrieve data that satisfies given criteria, for example, an integer property being greater than a given value, or a string property containing a given substring.

    • Filters specify the search conditions for queries. When creating a filter, you must specify the filter type using the _uri property.

      Conditions can be joined by using the logical operators AND and OR. For contact filters, there are enumerations of operators and conditions for each type: contacts_filter_operator_e (in mobile and wearable applications), contacts_match_int_flag_e (in mobile and wearable applications), and contacts_match_str_flag_e (in mobile and wearable applications).

    The following code demonstrates how to retrieve the contacts associated with a person using queries and filters. As a person can be associated with 1 or more contacts, the number of the contact records for the person can be 1 or more.

    To simplify the example code, error handling has been omitted, except for the final check.

    static bool
    _get_associated_contacts(contacts_record_h record, contacts_list_h *associated_contacts)
    {
        int error_code;
        int person_id;
        contacts_query_h query = NULL;
        contacts_filter_h filter = NULL;
    
        /* Retrieve the person ID from the person record */
        error_code = contacts_record_get_int(record, _contacts_person.id, &person_id);
    
        /* Create a contact query with a filter for the person ID */
        error_code = CONTACTS_ERROR_NONE;
        error_code += contacts_query_create(_contacts_contact._uri, &query);
        error_code += contacts_filter_create(_contacts_contact._uri, &filter);
        error_code += contacts_filter_add_int(filter, _contacts_contact.person_id, CONTACTS_MATCH_EQUAL, person_id);
        error_code += contacts_query_set_filter(query, filter);
    
        /* Run the query to retrieve a list of contacts associated with the person ID */
        error_code += contacts_db_get_records_with_query(query, 0, 0, associated_contacts);
    
        /* Destroy the filter and query handles and release all their resources */
        error_code += contacts_filter_destroy(filter);
        error_code += contacts_query_destroy(query);
    
        if (error_code != CONTACTS_ERROR_NONE)
            return false;
    
        return true;
    }
    

    The following example uses queries and filters to retrieve a person’s default phone number. If a person is associated with multiple phone numbers, one of them is defined as the default phone number. To determine the default phone number, you can check the is_primary_default property of the _contacts_person_number view. For the default phone number, the property is set to true.

    static bool
    _get_default_phone_number(contacts_record_h record, char **default_phone_number)
    {
        contacts_query_h query = NULL;
        contacts_filter_h filter = NULL;
        contacts_list_h list = NULL;
        contacts_record_h record_person_number = NULL;
        int person_id;
        int error_code = CONTACTS_ERROR_NONE;
    
        /* Retrieve the person ID from the person record */
        error_code += contacts_record_get_int(record, _contacts_person.id, &person_id);
    
        /*
           Create a phone number query with filters
           for the person ID and default phone number
        */
        error_code += contacts_query_create(_contacts_person_number._uri, &query);
        error_code += contacts_filter_create(_contacts_person_number._uri, &filter);
        error_code += contacts_filter_add_int(filter, _contacts_person_number.person_id, CONTACTS_MATCH_EQUAL, person_id);
        error_code += contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
        error_code += contacts_filter_add_bool(filter, _contacts_person_number.is_primary_default, true);
        error_code += contacts_query_set_filter(query, filter);
    
        /*
           Run the query to retrieve the phone number records
           containing the default phone number
        */
        error_code += contacts_db_get_records_with_query(query, 0, 0, &list);
    
        /* Retrieve the current record from the query list */
        error_code += contacts_list_get_current_record_p(list, &record_person_number);
    
        /* Retrieve the phone number from the phone number record */
        error_code += contacts_record_get_str(record_person_number, _contacts_person_number.number, default_phone_number);
    
        /* Destroy the list, filter, and query handles and release all their resources */
        contacts_list_destroy(list, true);
        contacts_filter_destroy(filter);
        contacts_query_destroy(query);
    
        if (error_code != CONTACTS_ERROR_NONE)
            return false;
    
        return true;
    }
    

Updating Contacts

To update the information for existing contacts, you must retrieve, change, and save the information you want to update:

  1. Retrieve the contact you want to update using the contacts_db_get_record() function with the contact ID as the second parameter. Alternatively, you can retrieve the contact using a search function, such as contacts_db_get_records_with_query().

    int contact_id = ... /* Get the contact ID */
    contacts_record_h contact = NULL;
    
    error_code = contacts_db_get_record(_contacts_contact._uri, contact_id, &contact);
    
  2. Set the properties you want to update:

    • The following example sets a new first name for the contact record by updating a child record:

      contacts_record_h name = NULL;
      /* Retrieve the contact's name record */
      /* Record index is set to 0, since there is only 1 child record of type "name" */
      error_code = contacts_record_get_child_record_at_p(contact, _contacts_contact.name, 0, &name);
      /* Change the first name in the name record */
      error_code = contacts_record_set_str(name, _contacts_name.first, "Mark");
      
    • The following example sets a new birthday event for the contact by updating another child record.

      The example assumes that the birthday is the only event for the contact, meaning that the event record can be retrieved using the contacts_record_get_child_record_at_p() function with index 0 as the second parameter. If the contact has multiple events, you must iterate through them.

      contacts_record_h event = NULL;
      /* Retrieve the contact's birthday event record */
      error_code = contacts_record_get_child_record_at_p(contact, _contacts_contact.event, 0, &event);
      /* Change the date in the event record */
      int new_date = 1990 * 10000 + 6 * 100 + 21;
      error_code = contacts_record_set_int(event, _contacts_event.date, new_date);
      
    • The following example shows the iteration to change the country in all contact addresses, which are child records of the contact. Each address can be traversed by using the contacts_record_get_child_record_at_p() function.

      int contact_id = ... /* Get the contact ID */
      int address_num = 0;
      int i = 0;
      
      contacts_db_get_record(_contacts_contact._uri, contact_id, &contact);
      contacts_record_get_child_record_count(count, _contacts_contact.address, &address_num);
      
      for (i = 0; i < address_num; i++) {
          contacts_record_h address = NULL;
          contacts_record_get_child_record_at_p(contact, _contacts_contact.address, i, &address);
          contacts_record_set_str(address, _contacts_address.country, "Korea");
      }
      
  3. Apply the changes to the database using the contacts_db_update_record() function:

    error_code = contacts_db_update_record(contact);
    
    if (error_code != CONTACTS_ERROR_NONE)
        dlog_print(DLOG_ERROR, LOG_TAG, "failed to update record: error code = %d", error_code);
    

    Note
    The contacts_record_set_XXX() functions only change the data in the memory object, not in the Contacts database. Normally, to update the database, you must update each record separately using the contacts_db_update_record() function. However, if you retrieve a child record using the contacts_record_get_child_record_at_p() function, you only need to update the parent record to the database; the child record is updated automatically with the parent record.

  4. When no longer needed, destroy the contact handle and release all its resources using the contacts_record_destroy() function.

    If you set the second parameter to true, the function destroys any child records automatically, irrespective of how the child records were added (individually or along with their parent record).

    error_code = contacts_record_destroy(contact, true);
    
    if (error_code != CONTACTS_ERROR_NONE)
        dlog_print(DLOG_ERROR, LOG_TAG, "failed to destroy record: error code = %d", error_code);
    

Creating a Contact

To create a new contact, you must create a contact handle, set the contact properties, insert the contact into the database, and destroy the handle:

  1. Create a contact handle using the contacts_record_create() function with the _contacts_contact._uri property as the first parameter:

    contacts_record_h contact;
    
    error_code = contacts_record_create(_contacts_contact._uri, &contact);
    
    if (error_code != CONTACTS_ERROR_NONE)
        dlog_print(DLOG_ERROR, LOG_TAG, "failed to create record: error code = %d", error_code);
    

    Remember that records created with the contacts_record_create() function are memory objects, with contacts_record_h type variables as their handles. If you change these objects, the changes are not reflected in the Contacts database until you explicitly insert or update the objects to the database using the contacts_db_insert_record() or contacts_db_update_record() function.

  2. Set the contact properties.

    The following examples set the contact name, image, phone number, and event.

    To simplify the example code, error handling has been omitted.

    • Name

      Create a name record, set the string values, “John” and “Smith”, to the name, and set the name record as a child record of the contact record.

      When creating the name record, the first parameter of the contacts_record_create() function is the _contacts_name._uri property.

      contacts_record_h name;
      
      error_code = contacts_record_create(_contacts_name._uri, &name);
      
      error_code = contacts_record_set_str(name, _contacts_name.first, "John");
      error_code = contacts_record_set_str(name, _contacts_name.last, "Smith");
      
      error_code = contacts_record_add_child_record(contact, _contacts_contact.name, name);
      
    • Image

      Similarly, create an image record, set the values of the property, and add the image record to the contact as a child record:

      • Create the image record with the _contacts_image._uri property.
      • Set the path for the image in the caller_id_path[] variable, which is saved in the _contacts_image.path property by the contacts_record_set_str() function.
      contacts_record_h image;
      
      error_code = contacts_record_create(_contacts_image._uri, &image);
      
      char *resource_path = app_get_resource_path();
      char caller_id_path[1024];
      
      snprintf(caller_id_path, sizeof(caller_id_path), "%s/caller_id.jpg", resource_path);
      free(resource_path);
      
      error_code = contacts_record_set_str(image, _contacts_image.path, caller_id_path);
      
      error_code = contacts_record_add_child_record(contact, _contacts_contact.image, image);
      
    • Phone number

      Similarly again, create a phone number record, set the number, and add the phone number record to the contact as a child record.

      When creating a phone number record, use the _contacts_number._uri property as the second parameter of the contacts_record_create() function.

      contacts_record_h number;
      
      error_code = contacts_record_create(_contacts_number._uri, &number);
      
      error_code = contacts_record_set_str(number, _contacts_number.number, "+8210-1234-5678");
      
      error_code = contacts_record_add_child_record(contact, _contacts_contact.number, number);
      
    • Event

      An event consists of a type, date, and other properties. You can set various types of events, as defined in the contacts_event_type_e enumeration (in mobile and wearable applications). If the event type is CUSTOM, you can set a custom label for the event using the _contacts_event.label property.

      The following example sets a birthday event:

      • In creating an event record, use the _contacts_event._uri property.
      • The event type is set as CONTACTS_EVENT_TYPE_BIRTH in the _contacts_event.type property.
      • When you set the event date, the date is an integer type property (_contact_event.date), calculated as year * 10000 + month * 100 + day.

      Add the event record to the contact as a child record using the contacts_record_add_child_record() function.

      contacts_record_h event;
      
      error_code = contacts_record_create(_contacts_event._uri, &event);
      
      error_code = contacts_record_set_int(event, _contacts_event.type, CONTACTS_EVENT_TYPE_BIRTH);
      
      int year = 1990;
      int month = 5;
      int day = 21;
      int int_date = year * 10000 + month * 100 + day;
      
      error_code = contacts_record_set_int(event, _contacts_event.date, int_date);
      
      error_code = contacts_record_add_child_record(contact, _contacts_contact.event, event);
      

    For other contact properties, you can follow the same steps: create an appropriate record, set the values in the properties, and add the record to the contact as a child record.

  3. Insert the contact into the Contacts database using the contacts_db_insert_record() function. All the child records added to the contact are inserted automatically along with the parent. The second parameter of the function is for the contact ID, which is unique and assigned by the system.

    int id = -1;
    
    error_code = contacts_db_insert_record(contact, &id);
    
  4. Destroy the contact handle and release all its resources using the contacts_record_destroy() function.

    If you set the second parameter to true, the function destroys any child records automatically, irrespective of how the child records were added (individually or along with their parent record).

    error_code = contacts_record_destroy(contact, true);
    

Deleting a Person

By using the contacts_db_delete_record() function, you can delete a person record from the database with related child records. The person ID is given to the function as the second parameter.

int person_id = ... /* Get the person ID */

error_code = contacts_db_delete_record(_contacts_person._uri, person_id);

Linking and Unlinking Persons and Contacts

A person can be associated with multiple contacts, so you need to know how to manage the associations between a person and its contacts: linking and unlinking.

When you create a contact, it is automatically linked to a person:

  • You can link the new contact to an existing person by setting the _contacts_contact.link_mode property as CONTACTS_CONTACT_LINK_MODE_NONE.

    Linking is determined based on the contact properties for phone numbers and email addresses (_contacts_number.number and _contacts_email.email). If an existing person has the same phone number or email address, but in a different address book, the contact is automatically linked to that person. However, if the phone number or email address leads to an existing contact in the same address book, the linking does not work.

  • If the contact cannot be linked to any existing person, a new person is automatically created and linked to the contact.

contacts_record_h contact = NULL;

error_code = CONTACTS_ERROR_NONE;
error_code += contacts_record_create(_contacts_contact._uri, &contact);
error_code += contacts_record_set_int(contact, _contacts_contact.link_mode, CONTACTS_CONTACT_LINK_MODE_NONE);

contacts_record_h name = NULL;
error_code += contacts_record_create(_contacts_name._uri, &name);
error_code += contacts_record_set_str(name, _contacts_name.first, "John");
error_code += contacts_record_add_child_record(contact, _contacts_contact.name, name);

contacts_record_h number = NULL;
error_code += contacts_record_create(_contacts_number._uri, &number);
error_code += contacts_record_set_str(number, _contacts_number.number, "+8210-1234-5678");
error_code += contacts_record_add_child_record(contact, _contacts_contact.number, number);

/*
   Contact is linked automatically if an existing person has the same number
   in a different address book
*/
error_code += contacts_db_insert_record(contact, NULL);

contacts_record_destroy(contact, true);

You can modify the contact and person linking, as needed:

  • To merge existing contacts into 1 person, use the contacts_person_link_person() function to link the contacts of one person to another person. The first parameter of the function is the ID of the person to be merged, and the second parameter is the ID of the person who will have all the merged contacts. After the linking, the former is deleted from the Contacts database. The latter person is left with both their original contacts and the other person’s contacts.

    int person_id1 = ... /* Get the person ID whose contacts are merged elsewhere */
    int person_id2 = ... /* Get the person ID to which contacts are merged */
    
    error_code = contacts_person_link_person(person_id1, person_id2);
    

    The following figure illustrates the process of linking a person. Even though the contacts have different address books, they can be linked to the same person. After linking, the person2 record is destroyed automatically.

    Figure: Linking a person

    Linking a person

  • To separate (unlink) a contact record from the person record, use the contacts_person_unlink_contact() function. The function removes the contact from the person, creates a new person, and links the contact to the new person.

    int person_id = ... /* Get the person ID */
    int contact_id = ... /* Get the contact ID */
    int unlinked_person_id;
    
    error_code = contacts_person_unlink_contact(person_id, contact_id, &unlinked_person_id);
    

    The following figure illustrates the process of unlinking a contact. After unlinking, the person3 record is newly created.

    Figure: Unlinking a contact

    Unlinking a contact