Contacts: 3 Using a Dedicated Contact

Up: GEOS SDK TechDocs| Up | Prev: 2 Choosing Contacts From a Log | Next: 4 Logging Calls
ContactMatchName(), ContactEnsureField()

Perhaps you're writing a special-purpose application that communicates with just one contact. Perhaps a carry-out restaurant chain has contracted you to write an application that the user can use to place an order over the phone. The program would only need to make contact with one place: the local restaurant's GSM phone number.

In this case, you wouldn't want to provide UI for choosing a contact--your program is only interested in one dedicated contact. Still, it's worthwhile to store the contact in the Contact database--if the restaurant's phone number changes, the user can enter the corrected number using the Contact Manager built-in application.

To find the Contact record for a particular contact, you will need to make sure that your .gp file contains the following lines:

library contdb
library foamdb

Finding the "Stuckey's Snack Shack" Contact, below, shows how you could find a dedicated contact in a Contact database and extract the phone number associated with that contact.

To locate a dedicated contact and extract its phone number, carry out the following steps:

  1. Which of the user's Contact databases do you wish to search? If the user has a memory card installed, there may be several databases to search. Perhaps you want to search all of them. Perhaps you want to ignore databases on the memory card, and only search the device's own database.
  2. For each database, to get the RecordID of the contact's record, call ContactMatchName(). This routine takes a search string (pass the contact's name), a ContdbFieldType (pass CFT_NAME, since we're searching by name), a flag (pass a non-zero value to specify that you're only interested in one matching record), a pointer to a FieldID buffer to fill in and a pointer to a word value to fill in. It returns the RecordID of the contact (or -1 if the contact wasn't found). It also fills in the FieldID buffer with the contact's name field FieldID and fills in the word value with the number of matches found; neither of these values is important to our purpose.
  3. If you're searching multiple databases and the current database doesn't contain the record, go on to the next database.

  4. Get the Contact database's handle. To do this, call ContactGetDBHandle(). This routine takes no arguments and returns the database's handle.
  5. Get the record's handle by calling FoamDBGetRecordFromID(). This routine takes the Contact database's handle and the record's RecordID. It returns the record's memory handle.
  6. Get the FieldID of the record's GSM phone number field. In the example below, we assume that the record has only one phone number field, and that this is the field we want. For a more rigorous approach, we could examine each field to make sure it was named "Tel (GSM)". For an example of how one might examine all the fields of a record, see To Get More Info on a Contact.
  7. For our shortcut, we use the ContactEnsureField() function. This function takes as arguments a record handle, a field name string (in our example, we pass a null optr to specify that we should use the default field name, and the ContdbFieldType of the field to find ( pass CFT_PHONE). The function returns a FieldID.

  8. To extract the phone number data, call FoamDBGetFieldData(). Pass the database handle, the record handle, the FieldID, a buffer to write the name to, and the size of that buffer. The function fills in the buffer with the phone number string, and returns the length of that string. The returned string might not be null-terminated; thus you will either need to keep track of the returned string length, or else terminate the string.
  9. Now that you're done with the record, let the database know by calling FoamDBDiscardRecord(). This routine takes the Contact's database handle and the record's handle as arguments.
  10. Now that you're done with the database, release its handle by calling ContactReleaseDBHandle().

If the contact is not found, there are a couple of approaches the application can take:

Code Display: Finding the "Stuckey's Snack Shack" Contact

@method ContactProcessClass, MSG_CONTACT_PROCESS_SEND_TO_STUCKEYS
{

    TCHAR        nameStr[] = "Stuckey's Snack Shack";
    TCHAR        numStr[] = "+1-800-788-2539";
    VMFileHandle hCDB;
    RecordID     recordID;
    FieldID      fieldID;
    word         numMatches;
    dword        recordIndex;
    word         len;
    MemHandle    hRecord;
    int          dbOverride = TRUE;  
    FileLongName dbName;
    int          numDBs;
    int          dbNumber;
    word         oldOverride;

    /*
     * Check the database on the device and the databases in the memory card.
     */
    /*
     * First try the db on the device.
     */
    oldOverride = ContactSetOverrideDB(CONTACT_DEVICE_DB_NAME);
    hCDB = ContactGetDBHandle();   /* device DB */
    recordID = ContactMatchName( nameStr, CFT_NAME, TRUE,
                                 &fieldID, &numMatches );
    ContactReleaseDBHandle();    /* device DB */

    if ( recordID == LECI_INVALID_CONTACT_ID) {
        /*
         * Now try each db on the memory card.
         */
        numDBs = ContactGetNumDBsOnMemoryCard();
        for (dbNumber = 0 ; dbNumber < numDBs; dbNumber++) {
            ContactGetDBName(dbNumber, dbName);
            ContactSetOverrideDB(dbName);
            hCDB = ContactGetDBHandle();
            recordID = ContactMatchName( nameStr, CFT_NAME, TRUE,
                                     &fieldID, &numMatches );
            ContactReleaseDBHandle();
            if ( recordID != LECI_INVALID_CONTACT_ID) {
                break;
            } 
            /* We didn't find it, loop up and try again. */
        }
        if ( recordID == LECI_INVALID_CONTACT_ID) {
            ContactRestoreOverrideDB(oldOverride);
            dbOverride = FALSE;
        }
    }

    hCDB = ContactGetDBHandle();

    if ( LECI_INVALID_CONTACT_ID == recordID ) {
        /* No such record in contact database -- let's add it. */
        dbOverride = FALSE;
        hRecord = ContactCreateRecordFromTemplate();
        fieldID = ContactEnsureField( hRecord, NullOptr, CFT_NAME );
        FoamDBSetFieldData( hCDB, hRecord, fieldID,
                            nameStr, strlen( nameStr ) );
        fieldID = ContactEnsureField( hRecord, @TelGSMStr, CFT_PHONE );
        FoamDBSetFieldData( hCDB, hRecord, fieldID,
                            numStr, strlen( numStr ) );
        recordIndex = ContactSaveRecord( hRecord );
        hRecord = FoamDBGetVisibleRecord( hCDB, recordIndex );

    }
    else {
        /* Contact exists: get record from ID. */
        hRecord = FoamDBGetRecordFromID( hCDB, recordID );
    }

    /* Record was either found or created: get the GSM phone number. */
    fieldID = ContactEnsureField( hRecord, @TelGSMStr, CFT_PHONE );
    len = FoamDBGetFieldData( hCDB, hRecord, fieldID,
                              numStr, MAX_NUMBER_FIELD_DATA_LEN );
    numStr[len] = '\0';

      /*
       * Here, the application can do something with the contact's data...
       */

    ContactReleaseDBHandle();
    if (dbOverride ) {
        ContactRestoreOverrideDB(oldOverride);
    }


} /* MSG_CONTACT_PROCESS_SEND_TO_STUCKEYS */

To allow the user to edit the contact information for this single contact, use a ContactEdit object. To specify the contact that the user will work with, you will need its handle. Pass the handle as an argument to the MSG_CONTACT_EDIT_DISPLAY_RECORD message. (Don't call ContactSaveRecord(), FoamDBDeleteRecord(), or FoamDBDiscardRecord() when done with this handle; the controller will do so.)


Up: GEOS SDK TechDocs| Up | Prev: 2 Choosing Contacts From a Log | Next: 4 Logging Calls