Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Toutes les fonctions  ·  Vues d'ensemble  · 

Contacts

The Contacts API enables a client to request contact data from local or remote backends. This is part of the Qt Mobility Project.

Introduction

Access to the backends is provided by implementations of Qt Contacts manager API. This is achieved by defining generic personal information data abstractions which can sufficiently describe contact data stored on any platform. Due to the cross-platform nature of the API, and the ability for developers to write platform-independent implementations of a QContactManager which may unify one or more platform specific contact backends, it is intended that the semantics and quirks of the underlying datastores on any platform may be entirely opaque from the perspective of Qt-based, cross-platform client applications.

Overview

A contact is the digital representation of a person, group or entity, which is stored in a platform-specific manner. Information pertaining to a single contact may be located across several different datastores, and each datum (or detail) may or may not pertain to a particular context in which that information is valid. A contact may include semantically identical pieces of information that are relevant in different contexts. For example, a contact may have a phone number that is relevant to their "home" context, and another phone number that is relevant to their "work" context. It can be seen that the context of information defines its validity to the user, depending on the context of usage; and as such, the sum of information in a given context can be considered equivalent to a "contextual identity". This allows great flexibility when consolidating data from various sources into a single, cohesive contact.

Each datum (or detail) stored in a contact has defined semantics of usage and storage. The Qt Contacts API allows per-datastore contact detail definitions, allowing a manager to provide clients with this information on demand, and allowing third-party developers to register detail definitions for use by clients. A detail definition includes the fields (and value-types of those fields) which make up the detail, per-contact uniqueness constraints on details of the definition, and access constraints (such as read-only, create-only, etc). Additionally, the fields of a detail definition may also be constrained to be read-only or not.

A detail is a single, cohesive unit of information that is stored in a contact. As explained previously, it is valid for a particular context or set of contexts, and conforms to a particular definition. A detail may have specific metadata associated with it, such as its sub-type, context, and arbitrary, user-defined metadata.

Contacts may participate in relationships with other contacts. The details of any such relationship is stored by the manager which contains the contact. There are several standard relationship types supported by the default schema, and arbitrary relationship types are also allowed. In particular, membership of a contact in a group can be modeled as that group contact participating in a HasMember relationship with the contact.

A manager provides access to zero or more platform-specific datastores. Each datastore may support different capabilities (for example, the ability to store certain datatypes, the ability to natively filter on different details or details of different definitions, the provision of locking mechanisms, the provision of changelog information, etc) which are reported by the manager on request. The manager therefore provides access to detail definitions, contacts, and relationships stored in different datastores, in a platform and datastore independent manner. The engine of a manager may be implemented as a plugin to allow dynamic loading of different engines at run-time.

Using the API

This section provides some examples of common usage of the API.

Synchronous API Usage

The synchronous API provides the simplest way to access or modify the contact information managed by a particular backend. It has the disadvantage that calls block until completion and is therefore most suitable only for applications which interact with local, high-speed datastores.

Saving a new contact to the default manager

The client creates a new contact, adds a name and a phone number, and saves it to the default store of the default manager.

We assume the existence of a specialised leaf-class that allows simple access to details of the definition identified by the "PhoneNumber" identifier, and another that allows simple access to details of the definition identified by the "Name" identifier. These specialised leaf classes may be written by anyone, and simply wrap the functionality provided by QContactDetail in order to allow simpler access to fields supported by a particular definition.

    void addContact(QContactManager* cm)
    {
        QContact alice;

        /* Set the contact's name */
        QContactName aliceName;
        aliceName.setFirst("Alice");
        aliceName.setLast("Jones");
        aliceName.setCustomLabel("Ally Jones");
        alice.saveDetail(&aliceName);

        /* Add a phone number */
        QContactPhoneNumber number;
        number.setContexts(QContactDetail::ContextHome);
        number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
        number.setNumber("12345678");
        alice.saveDetail(&number);
        alice.setPreferredDetail("DialAction", number);

        /* Add a second phone number */
        QContactPhoneNumber number2;
        number2.setContexts(QContactDetail::ContextWork);
        number2.setSubTypes(QContactPhoneNumber::SubTypeLandline);
        number2.setNumber("555-4444");
        alice.saveDetail(&number2);

        /* Save the contact */
        cm->saveContact(&alice);
    }
Filtering by detail definition and value

The client utilises a default manager and asks for any contacts with a particular phone number. The example assumes that the default manager supports the provided QContactPhoneNumber detail leaf class (which implements the default definition for phone number details).

    void matchCall(QContactManager* cm, const QString& incomingCallNbr)
    {
        QContactDetailFilter phoneFilter;
        phoneFilter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName, QContactPhoneNumber::FieldNumber);
        phoneFilter.setValue(incomingCallNbr);
        phoneFilter.setMatchFlags(QContactFilter::MatchExactly);

        QList<QContactLocalId> matchingContacts = cm->contacts(phoneFilter);
        if (matchingContacts.size() == 0) {
            qDebug() << "Incoming call from unknown contact (" << incomingCallNbr << ")";
        } else {
            QContact match = cm->contact(matchingContacts.at(0));
            qDebug() << "Incoming call from"
                     << match.displayLabel()
                     << "(" << incomingCallNbr << ")";
        }
    }
Viewing a specific detail of a contact

The client retrieves the phone numbers of a contact, and displays the first one

    void viewSpecificDetail(QContactManager* cm)
    {
        QList<QContactLocalId> contactIds = cm->contacts();
        QContact a = cm->contact(contactIds.first());
        qDebug() << "The first phone number of" << a.displayLabel()
                 << "is" << a.detail(QContactPhoneNumber::DefinitionName).value(QContactPhoneNumber::FieldNumber);
    }
Viewing all of the details of a contact

The client retrieves all of the details of a contact, and displays them

    void viewDetails(QContactManager* cm)
    {
        QList<QContactLocalId> contactIds = cm->contacts();
        QContact a = cm->contact(contactIds.first());
        qDebug() << "Viewing the details of" << a.displayLabel();

        QList<QContactDetail> allDetails = a.details();
        for (int i = 0; i < allDetails.size(); i++) {
            QContactDetail detail = allDetails.at(i);
            QContactDetailDefinition currentDefinition = cm->detailDefinition(detail.definitionName());
            QMap<QString, QContactDetailDefinitionField> fields = currentDefinition.fields();

            qDebug("\tDetail #%d (%s):", i, detail.definitionName().toAscii().constData());
            foreach (const QString& fieldKey, fields.keys()) {
                qDebug() << "\t\t" << fieldKey << "(" << fields.value(fieldKey).dataType() << ") =" << detail.value(fieldKey);
            }
            qDebug();
        }
    }
Installing a plugin that modifies the definition of one type of detail

The client installs a plugin, which requires a new field to be added to details of the "EmailAddress" definition. It loads the definition from the default manager, modifies it (by adding the new field - a label field), and saves it back.

    void addPlugin(QContactManager* cm)
    {
        /* Find the definition that we are modifying */
        QMap<QString, QContactDetailDefinition> definitions = cm->detailDefinitions();
        QContactDetailDefinition modified = definitions.value(QContactEmailAddress::DefinitionName);

        /* Make our modifications: we add a "Label" field to email addresses */
        QContactDetailDefinitionField newField;
        newField.setDataType(QVariant::String);
        QMap<QString, QContactDetailDefinitionField> fields = modified.fields();
        fields.insert("Label", newField);

        /* Update the definition with the new field included */
        modified.setFields(fields);

        /* Save the definition back to the manager */
        if (cm->saveDetailDefinition(modified))
            qDebug() << "Successfully modified the detail definition!";
        else
            qDebug() << "This backend could not support our modifications!";
    }
Modifying an existing contact and saving the modifications

The client retrieves a contact, modifies one of its details, adds a new detail, and then saves the contact back to the manager. Note that it uses the newly added field of the email address definition!

    void editView(QContactManager* cm)
    {
        QList<QContactLocalId> contactIds = cm->contacts();
        QContact a = cm->contact(contactIds.first());
        qDebug() << "Modifying the details of" << a.displayLabel();

        /* Change the first phone number */
        QList<QContactDetail> numbers = a.details(QContactPhoneNumber::DefinitionName);
        QContactPhoneNumber phone = numbers.value(0);
        phone.setNumber("123-4445");

        /* Add an email address */
        QContactEmailAddress email;
        email.setEmailAddress("alice.jones@example");
        email.setContexts(QContactDetail::ContextHome);
        email.setValue("Label", "Alice's Work Email Address");

        /* Save the updated details to the contact. */
        a.saveDetail(&phone);
        a.saveDetail(&email);

        /* Now we must save the updated contact back to the database. */
        cm->saveContact(&a);
        viewDetails(cm);
    }

Asynchronous API Usage

The asynchronous API provides a flexible and powerful method of accessing and modifying the contact information managed by a particular backend in an asynchronous manner. Use of the asynchronous API is slightly more complex than use of the synchronous API, but offers the programmer greater flexibility when requesting information from remote or slow, local datastores.

Requesting Contacts

The client sets up a request for contacts matching a specific criteria from a particular manager.

Results from the request will be displayed to the user as they are received.

    void RequestExample::performRequest()
    {
        // retrieve any contact whose first name is "Alice"
        QContactDetailFilter dfil;
        dfil.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirst);
        dfil.setValue("Alice");
        dfil.setMatchFlags(QContactFilter::MatchExactly);

        m_fetchRequest->setFilter(dfil);
        connect(m_fetchRequest, SIGNAL(progress(QContactFetchRequest*,bool)), this, SLOT(printContacts(QContactFetchRequest*,bool)));
        if (!m_fetchRequest->start()) {
            qDebug() << "Unable to request contacts!";
            QCoreApplication::exit(0);
        } else {
            qDebug() << "Requested contacts; awaiting results...";
        }
    }

    void RequestExample::printContacts(QContactFetchRequest* request, bool appendOnly)
    {
        QList<QContact> results = request->contacts();
        if (appendOnly) {
            // we know that the results are still in the same order; just display the new results.
            for (m_previousLastIndex += 1; m_previousLastIndex < results.size(); m_previousLastIndex++) {
                qDebug() << "Found another Alice:" << results.at(m_previousLastIndex).displayLabel();
            }
        } else {
            // the order of results has changed; display them all.
            for (m_previousLastIndex = 0; m_previousLastIndex < results.size(); m_previousLastIndex++) {
                qDebug() << "Found another Alice:" << results.at(m_previousLastIndex).displayLabel();
            }
        }

        // once we've finished retrieving results, stop processing events.
        if (request->status() == QContactAbstractRequest::Finished || request->status() == QContactAbstractRequest::Cancelled) {
            QCoreApplication::exit(0);
        }
    }
Other Asynchronous Operations

All other asynchronous operations are performed in a similar manner to the previous example. A request of the desired type (which is derived from QContactAbstractRequest) is created, certain criteria are set which determine the result of the request, and the progress signal of the request is connected to a slot which deals with the result. The request can then be started.

Any operation that may be performed using the synchronous API may also be performed using the asynchronous API. It is recommended for most applications that the asynchronous API be used where possible.

Manager Settings And Configuration

Users of the contacts API can define which backend they wish to access if a manager for that backend is available. The list of available managers can be queried programmatically at run-time, and the capabilities of different managers can be ascertained by inspecting a QContactManager instance. Furthermore, some managers can be constructed with parameters which affect the operation of the backend.

Loading the manager for a specific backend

In this example, the client loads a manager for a specific backend. While this could be found and retrieved using a more advanced plugin framework (such as the Qt Service Framework), this code assumes that the client has prior knowledge of the backend in question.

    void loadManager()
    {
        QContactManager* cm = new QContactManager("KABC");
        QList<QContactLocalId> contactIds = cm->contacts();
        if (!contactIds.isEmpty()) {
            QContact a = cm->contact(contactIds.first());
            qDebug() << "This manager contains" << a.displayLabel();
        } else {
            qDebug() << "This manager contains no contacts";
        }

        delete cm;
    }

Loading a manager with specific parameters

The client loads a manager with specific parameters defined. The parameters which are available are backend specific, and so the client had to know that the "Settings" parameter was valid for the particular backend, and what argument it took. In this example, the client tells the backend to load detail definitions saved in a particular settings file.

    void loadManagerWithParameters()
    {
        QMap<QString, QString> parameters;
        parameters.insert("Settings", "~/.qcontactmanager-kabc-settings.ini");
        QContactManager* cm = new QContactManager("KABC", parameters);
        QMap<QString, QContactDetailDefinition> definitions = cm->detailDefinitions();

        qDebug() << "This backend currently supports the following detail definitions:";
        QList<QContactDetailDefinition> allDefinitions = definitions.values();
        foreach (const QContactDetailDefinition& defn, allDefinitions) {
            QMap<QString, QContactDetailDefinitionField> fields = defn.fields();
            foreach (const QString& fieldKey, fields.keys()) {
                QList<QVariant> allowableValues = fields.value(fieldKey).allowableValues();
                qDebug() << "\t" << fieldKey << "(" << fields.value(fieldKey).dataType() << "):";
                if (allowableValues.isEmpty()) {
                    qDebug() << "\t\tAny Value Permitted";
                } else {
                    qDebug() << allowableValues;
                }
            }
        }

        delete cm;
    }

Building and compiling

This library requires Qt 4.5 to be installed.

To build the library, run qmake and make.

Reference documentation

Main classes

QContactActionInterface for performing an action on a QContact or QContactDetail
QContactDetailAccess to a single, complete detail about a contact

"Contact Details" Leaf Classes

Several subclasses of QContactDetail are provided as part of the Qt Mobility Project Contacts API. They are general in design but are intended to fulfil specific use-cases. Please note that certain backends may choose not to support one or more of these subclasses as they appear here; they may offer their own which provide similar functionality.

Each of these subclasses provide access to information stored in fields which are listed in the schema.

Asynchronous Requests

Clients may use either the synchronous or asynchronous API to access functionality provided by a manager backend. The asynchronous API is offered through subclasses of the QContactAbstractRequest class:

QContactDetailDefinitionFetchRequestAllows a client to asynchronously request detail definitions from a contacts store manager
QContactDetailDefinitionRemoveRequestAllows a client to asynchronously request that certain detail definitions be removed from a contacts store
QContactDetailDefinitionSaveRequestAllows a client to asynchronously request that certain detail definitions be saved in a contacts store
QContactFetchRequestAllows a client to asynchronously request contacts from a contacts store manager
QContactLocalIdFetchRequestAllows a client to asynchronously request a list of contact ids from a contacts store manager
QContactRelationshipFetchRequestAllows a client to asynchronously request relationships from a contacts store manager
QContactRelationshipRemoveRequestAllows a client to asynchronously request that certain relationships be removed from a contacts store
QContactRelationshipSaveRequestAllows a client to asynchronously request that certain groups be saved to a contacts store
QContactRemoveRequestAllows a client to asynchronously request that certain contacts be removed from a contacts store
QContactSaveRequestAllows a client to asynchronously request that certain contacts be saved to a contacts store

Contact Selection

Clients may select a contact by specifying a unique contact id, or by supplying a QContactFilter which matches the contact or contacts they wish to select. The various derivatives of QContactFilter allow for fine-grained and flexible selection of contacts according to various criteria:

QContactActionFilterFilter based around an action availability criterion
QContactChangeLogFilterFilter based around a contact timestamp criterion
QContactDetailFilterFilter based around a detail value criterion
QContactDetailRangeFilterFilter based around a detail value range criterion
QContactIntersectionFilterFilter which intersects the results of other filters
QContactInvalidFilterMatches no contacts
QContactLocalIdFilterFilter based around a list of contact ids
QContactRelationshipFilterFilter based around relationship criteria
QContactUnionFilterFilter which unions the results of other filters

A client can also request that the results of such a selection be sorted, by passing a QContactSortOrder (or list of sort orders) to the manager.

Actions

Clients can perform actions on contacts which support them. Actions are things like "Send Email" or "Dial", and can be provided from various sources including Qt Plugins or the Qt Mobility Service Framework. Every action implementation is uniquely identified by a combination of its name, the name of the vendor which provided the implementation, and the version of the implementation according to the vendor. These pieces of data may be encapsulated in a QContactActionDescriptor which can be used to retrieve an instance of the implementation from a QContactActionFactory.

When an instance of a QContactAction is created, the caller takes ownership of the instance, and must delete it after use.

Implementing Backends

A manager backend may be implemented by subclassing QContactManagerEngine, and providing a QContactManagerEngineFactory which can instantiate it when required.

Manager information and functionality reporting

Different backends have different capabilities and offer different functionality. In order to allow clients to query the provided functionality at runtime, every backend must be capable of reporting their functionality and implementation version. They are reported to clients through various functions provided by the QContactManager class.

Synchronization and Serialization

The contacts API is used by another Qt Mobility module: the Versit* module. It allows serialization of a QContact into a vCard document, and vice versa.

[*] Versit is a trademark of the Internet Mail Consortium.

Examples

Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. Qt qtmobility-1.0-tp
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP !
 
 
 
 
Partenaires

Hébergement Web