AddressBook.java

/*
 * Copyright © 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */ 
package com.nokia.example.bcexchanger;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Enumeration;
import java.util.Vector;

import javax.microedition.pim.Contact;
import javax.microedition.pim.ContactList;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMItem;

/**
 * 
 * This class provides an abstraction of the address book to
 * application. It implements the access to the phone address book and
 * provides information in the form the application needs
 */
public class AddressBook {

    /**
     * This methods get all names from the address book and
     * corresponding uids.
     * <p>
     * This method retrieves full names from the address book and
     * corresponding unique identifiers (uids)
     * 
     * @return two vectors: first is vector of names, second is the
     *         vector of corresponding UIDs
     * @exception Exception -
     *              in case any errors occur while working with address
     *              book
     */
    static public Vector[] getNamesUIDLists() throws Exception {
        Vector[] namesUIDs = new Vector[2];
        namesUIDs[0] = new Vector();
        namesUIDs[1] = new Vector();

        // get the name of the address book
        PIM pim = PIM.getInstance();
        String listNames[] = pim.listPIMLists(PIM.CONTACT_LIST);
        if (listNames.length == 0) {
            throw new RuntimeException("No available Contact lists");
        }

        // list of preferd order of the name fields
        Vector fieldOrder = new Vector();
        fieldOrder.addElement(new Integer(Contact.FORMATTED_NAME)); // For Series40
        fieldOrder.addElement(new Integer(Contact.NAME_FAMILY));
        fieldOrder.addElement(new Integer(Contact.NAME_GIVEN));
        fieldOrder.addElement(new Integer(Contact.NAME)); // fix

        for (int listIndex = 0; listIndex < listNames.length; listIndex++) {
            // opent the address book
            ContactList contactList = (ContactList) pim.openPIMList(
                    PIM.CONTACT_LIST, PIM.READ_ONLY, listNames[listIndex]);

            // verify that the required UID field is supported
            if (!contactList.isSupportedField(Contact.UID)) {
                continue;
            }

            Vector supportedFieldOrder = new Vector();
            // create the supported list
            for (int i = 0; i < fieldOrder.size(); i++) {
                Integer field = (Integer) fieldOrder.elementAt(i);
                if (contactList.isSupportedField(field.intValue())) {
                    supportedFieldOrder.addElement(field);
                }
            }

            // in case none of the names is supported
            if (supportedFieldOrder.isEmpty()) {
                continue;
            }

            // get the list of contacts and uids
            Enumeration items = contactList.items();
            while (items.hasMoreElements()) {
                Contact contact = (Contact) items.nextElement();
                try {
                    // try to obtain any supported name
                    String name = null;
                    Enumeration nameFields = supportedFieldOrder.elements();
                    while (nameFields.hasMoreElements()) {
                        try {
                            int field = ((Integer) nameFields.nextElement()).intValue();

                            if (field == Contact.NAME) {
                                String[] nameArray = contact.getStringArray(field, 0);
                                if (nameArray != null) {
                                    name = nameArray[0];
                                }
                            } else {
                                name = contact.getString(field, 0);
                            }

                            if (name != null && !"".equals(name)) {
                                break;
                            } else {
                                name = null;
                            }
                        } catch (Exception e) {
                            name = null;
                        }
                    }

                    // this contact does not have a suitable name, continue with the next
                    if (name == null) {
                        continue;
                    }
                    String uid = contact.getString(Contact.UID, 0);

                    namesUIDs[0].addElement(name);
                    namesUIDs[1].addElement(uid);
                } catch (IndexOutOfBoundsException e) {
                    // Ignore, this is a malformed contact and we'll omit it
                }
            }
        }

        return namesUIDs;
    }

    /**
     * Get vCard of the address book entry with the particular uid
     * <p>
     * Longer description
     * 
     * @param uid -
     *          unique identifier of the requested address book entry
     * @return byte array which contains a vCard
     * @exception Exception -
     *              in case any error occur
     */
    static public byte[] getVCard(String uid) throws Exception {
        ByteArrayOutputStream os = new ByteArrayOutputStream();

        // create a search pattern (based on uid)
        ContactList contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY);
        Contact searchPattern = contactList.createContact();
        searchPattern.addString(Contact.UID, PIMItem.ATTR_NONE, uid);

        Enumeration e = contactList.items(searchPattern);

        // get the first found contact
        if (e.hasMoreElements()) {
            Contact contact = (Contact) e.nextElement();
            PIM.getInstance().toSerialFormat(contact, os, "UTF-8",
                    "VCARD/2.1");
        } else {
            throw new RuntimeException("No contacts found");
        }

        return os.toByteArray();
    }

    /**
     * Saves a vCard to the address book
     * <p>
     * Creates a new entry based on the information from the vCard in
     * the phones address book
     * 
     * @param vCard -
     *          byte array which contains a vCard
     * @exception Exception -
     *              in case any errors occur
     */
    static public void setVCard(byte[] vCard) throws Exception {
        ByteArrayInputStream in = new ByteArrayInputStream(vCard);

        // get address book entry from the input stream
        PIMItem[] items = PIM.getInstance().fromSerialFormat(in, "UTF-8");

        // takes the first one discards the others
        ContactList contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, /* PIM.WRITE_ONLY */
                PIM.READ_WRITE);
        Contact newContact = contactList.importContact((Contact) items[0]);

        newContact.commit();
    }
}