Реализовать чтение контактов из телефонной книги Используя Hashtable в J2ME - PullRequest
1 голос
/ 06 декабря 2011

Я столкнулся с привязкой, в результате чего мне пришлось сортировать данные, прочитанные с телефонов PIM. При этом я потерял другое, к которому каждое поле контакта было привязано к номеру телефона, потому что я использовал 2 отдельных вектора, как показано ниже
Перед сортировкой

 Nna - +445535533                       
Ex - +373773737                         
Ab - +234575757                         
After sorting.(Which shouldn't be)
 Ab - +445535533
 Ex - +373773737
 Nna  - +234575757

Это приводит к нежелательному поведению, так как сортировка удаляет указатель индекса на указатель векторов, а выбранное имя (в окне с несколькими списками) получит неправильное число.
С другой стороны,
Я использовал хеш-таблицу с намерением использовать имена в качестве ключей и цифры в качестве значений.
Но такое сопряжение означает, что дублирующие имена, используемые в качестве ключей, не будут разрешены. Таким образом, я сделал это, т.е. телефонный номер в качестве ключей вместо. Я не хочу походить на плачущего ребенка, поэтому я останавливаюсь здесь на некоторое время, и поэтому вы код с надеждой, что вы, ребята, поймете это

МОЙ ВОПРОС
1. Есть ли лучший способ / алгоритм для реализации этого?
2. Как мне реализовать getSelectedItems () таким образом, чтобы он захватывал номера выбранных индексов из МНОГОКРАТНОГО СПИСКА ВЫБОРОВ из хеш-таблицы

import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import javax.microedition.lcdui.List;
import javax.microedition.pim.Contact;
import javax.microedition.pim.ContactList;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;

/**
 *
 * @author nnanna
 */
public class LoadContacts implements Operation {

    private boolean available;
    private Vector telNames = new Vector();
    Vector telNumbers = new Vector();
    Hashtable Listcontact = new Hashtable();
    private String[] names;

    public Vector getTelNames() {
        return telNames;
    }

    public Hashtable getListcontact() {
        return Listcontact;
    }

    public void execute() {
        try {
// go through all the lists
            String[] allContactLists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST);

            if (allContactLists.length != 0) {
                for (int i = 0; i < allContactLists.length; i++) {
                    System.out.println(allContactLists[i]);
                    System.out.println(allContactLists.length);
                    loadNames(allContactLists[i]);
                    System.out.println("Execute()");
                }

            } else {
                available = false;
            }
        } catch (PIMException e) {
            available = false;

        } catch (SecurityException e) {
            available = false;

        }
    }

    private void loadNames(String name) throws PIMException, SecurityException {
        ContactList contactList = null;

        try {
            contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY, name);
            // First check that the fields we are interested in are supported(MODULARIZE)
            if (contactList.isSupportedField(Contact.FORMATTED_NAME) && contactList.isSupportedField(Contact.TEL)) {
                Enumeration items = contactList.items();
                Hashtable temp = new Hashtable();
                while (items.hasMoreElements()) {
                    Contact contact = (Contact) items.nextElement();
                    int telCount = contact.countValues(Contact.TEL);
                    int nameCount = contact.countValues(Contact.FORMATTED_NAME);
                    if (telCount > 0 && nameCount > 0) {
                        String contactName = contact.getString(Contact.FORMATTED_NAME, 0);
                        // go through all the phone availableContacts

                        for (int i = 0; i < telCount; i++) {
                            System.out.println("Read Telno");
                            int telAttributes = contact.getAttributes(Contact.TEL, i);
                            String telNumber = contact.getString(Contact.TEL, i);
                            Listcontact.put(telNumber, contactName);
                            temp.put(contactName, telNumber);
                        }
                        names = getSortedList();
//                            Listcontact = temp;
                        System.out.println(temp + "-------");
                        System.out.println(Listcontact + "*******");
                        shortenName(contactName, 20);
                    }
                    available = true;
                }
            } else {
                available = false;
            }
        } finally {
// always close it
            if (contactList != null) {
                contactList.close();
            }
        }
    }

    private void shortenName(String name, int length) {
        if (name.length() > length) {
            name = name.substring(0, 17) + "...";
        }
    }

    public Vector getSelectedItems(List lbx) {
        boolean[] arrSel = new boolean[lbx.size()];
        Vector selectedNumbers = new Vector();
        int selected = lbx.getSelectedFlags(arrSel);
        String selectedString;
        String result = "";
        for (int i = 0; i < arrSel.length; i++) {
            if (arrSel[i]) {
                selectedString = lbx.getString(lbx.getSelectedFlags(arrSel));
                result = result + " " + i;
                System.out.println(Listcontact.get(selectedString));
//                System.out.println(telNumbers.elementAt(i));
            }
        }
        return selectedNumbers;
    }

    private String[] sortResults(String data[]) {
        RecordSorter sorter = new RecordSorter();
        boolean changed = true;
        while (changed) {
            changed = false;
            for (int j = 0; j < (data.length - 1); j++) {
                String a = data[j], b = data[j + 1];
                if (a != null && b != null) {
                    int order = sorter.compare(a.getBytes(), b.getBytes());
                    if (order == RecordSorter.FOLLOWS) {
                        changed = true;
                        data[j] = b;
                        data[j + 1] = a;
                    }
                }
            }
        }
        return data;
    }

    public String[] getNames() {
        return names;
    }
        Vector elements = new Vector();
    private String[] getValueArray(Hashtable value) {

        System.out.println(Listcontact + " c");
        Enumeration e = value.elements();
        while (e.hasMoreElements()) {
            elements.addElement(e.nextElement());
        }
        String[] elementsArray = new String[elements.size()];
        elements.copyInto(elementsArray);
        elements.removeAllElements();
        System.out.println(elementsArray + " k");
        return elementsArray;
    }

    public void getDuplicates(Vector realValue) {
        Vector duplicate = new Vector();
        Enumeration e = realValue.elements();
        for (int i = 0; e.hasMoreElements(); i++) {
            if (duplicate.isEmpty() || !duplicate.elementAt(i).equals(e.nextElement())) {
                break;
            } else {
                duplicate.addElement(e.nextElement());
            }
        }
    }

    public String[] getSortedList() {
        return sortResults(getValueArray(Listcontact));
    }
}

Ответы [ 4 ]

3 голосов
/ 06 декабря 2011

Позвольте мне повторить ваше требование: вам нужен метод, который будет сортировать контакты, прочитанные из родной телефонной книги, а затем отсортировать их по имени в алфавитном порядке.

Ниже приводится подход,

Заменить векторыи хеш-таблицы в вашем коде с одним вектором, скажем, contactListVector, содержащие элементы типа ContactItem, не беспокойтесь, этот класс объясняется ниже.По сути имя контакта и число (а) связаны друг с другом в ContactItem, поэтому вам не нужно беспокоиться о там отображениях, которые уменьшают использование избыточных структур данных.

class ContactItem {
    private String name;
    private String tnumber;  //this can also be a data structure 
                             //for storing multiple numbers

    ContactItem( String name, String tnumber) {
        this.name = name;
        this.tnumber = tnumber;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTnumber() {
        return tnumber;
    }

    public void setTnumber(String tnumber) {
        this.tnumber = tnumber;
    }        
}

Вы можете повторно использовать алгоритм сортировки на contactListVector, сравнивая переменную-член ContactItem.name векторного элемента.Также вы можете использовать различные виды переменных-членов числа и / или имена .Также доступно множество библиотек для JavaME, в которых реализован лучший алгоритм сортировки, если это необходимо, используйте их.

Я бы порекомендовал вам выполнить сортировку один раз для contactListVector элементов в конце вашего метода loadNames(...) возможно, в блоке finally, запускаемом некоторой логической переменной.Текущий вызов сортировки в каждой итерации для перечисления items является дорогим и трудоемким.

Также вы можете сериализовать / десериализовать ContactItem, таким образом, сохранить свой список контактов.

Дайте мне знать, еслиВам нужно подробное объяснение.

1 голос
/ 06 декабря 2011

Это утверждение в вашем коде не имеет смысла:

selectedString = lbx.getString(lbx.getSelectedFlags(arrSel))

За Документация по API списка lcdui выше вернет строку, расположенную в индексе, равном номеру выбранногоэлементы зачем вам это нужно?


Если вам нужно вывести выделенный текст для целей отладки, используйте lbx.getString(i).

Чтобы реализовать getSelectedItems () таким образом, чтобы он захватывал номера выбранных индексов МНОГОКРАТНОГО СПИСКА , действуйте следующим образом:

    public Vector getSelectedItems(List lbx) {
        boolean[] arrSel = new boolean[lbx.size()];
        Vector selectedNumbers = new Vector();
        int selected = lbx.getSelectedFlags(arrSel);
        System.out.println("selected: [" + selected + "] elements in list");
        String selectedString;
        String result = "";
        for (int i = 0; i < arrSel.length; i++) {
            if (arrSel[i]) {
                // here, i is the selected index
                selectedNumbers.addElement(new Integer(i)); // add i to result
                String selectedString = lbx.getString(i);
                System.out.println("selected [" + selectedString
                        + "] text at index: [" + i + "]");
            }
        }
        return selectedNumbers;
    }

Что касается потребностей сортировки, просто отбросьте HashTableи вместо этого используйте Vector правильно спроектированных объектов, как предложено в другом ответе - с вашим собственным алгоритмом сортировки или из какой-либо сторонней библиотеки J2ME.

1 голос
/ 06 декабря 2011

Как насчет вставки имени контакта и номеров в хранилище записей, чтобы впоследствии вы могли выполнить сортировку, создав класс, который реализует RecordComparator.

0 голосов
/ 06 декабря 2011

Я бы предложил вам иметь Contact класс с именем и вектором чисел. И вместо сортировки массива имен сортируйте массив контактов.

...