IV.Cách thức tổ chức dữ liệu của PIM data

4.1.Trường(Field)

PIM items nhóm các field có liên quan với nhau. Các field được xác định bởi kiểu của PIMItem. Ví dụ, một item calendar event gồm có các trường: thời gian event bắt đầu và kết thúc, mô tả event, vị trí và những trường khác. Item address-book gồm các trường như: first name, last name, phone number, address, email address…Các field có một ID, một nhãn(label), các giá trị, các thuộc tính được minh họa như hình 1.
Các field được định danh duy nhất bởi một field ID. Các field IDs là các hằng(constants) được định nghĩa bởi các PIM item: Contact, Event và ToDo. Ví dụ, item Contact định nghĩa các trường như: Contact.NAME, Contact.ADDR…Ngoài ra, các field còn được phân biệt bởi field chuẩn hay mở rộng. Các field chuẩn là các field là các field chung, còn các field mở rộng là các field phát sinh trong quá trình implement PIM.

Để biết được các field được hỗ trợ trên thiết bị, sử dụng phương thức getSupportedField() cho từng PIM list cụ thể. Các field mở rộng cũng có thể dễ dàng xác định thông qua các giá trị field ID, bởi chúng thường lớn hơn hoặc bằng PIMItem.EXTENDED_FIELD_MIN_VALUE.

4.2.Nhãn(Label)

Label của một field là một chuối String dùng để mô tả một field. Để lấy label của một field, sử dụng phương thức getFieldLabel(int fieldID) của lớp PIMList.

4.3.Kiểu dữ liệu(Data type)

Các kiểu dữ liệu của Field bao gồm: INT, BOOLEAN, DATE, STRING_ARRAY hay STRING, được định nghĩa trong PIMList. Để nhận biết kiểu dữ liệu của một trường, sử dụng phương thức PIMList.getFieldDataType(int fieldID).

4.4.Giá trị dữ liệu(Data value)

Các field có thể không có hay có nhiều giá trị dữ liệu. Các field đơn được đặc trưng bởi các kiểu dữ liệu Java tương ứng, trong khi các field multi-value được đặc trưng bởi một mảng, như mảng String hay mảng byte. Một ví dụ về multi-value đó là field NAME, nó gồm có first name, middle name và last name. Để thao tác trên các giá trị của field, trước tiên bạn phải nhận biết kiểu của các field để có các xử lý phù hợp.

4.5.Thuộc tính

Thuộc tính định nghĩa định nghĩa các giá trị dữ liệu. Ví dụ, một trường Telephone có kiểu là PIMItem.STRING, có thể được sử dụng để quy định các thuộc tính địng nghĩa trước, như số điện thoại ở nhà(ADDR_HOME), số điện thoại cơ quan(ADDR_WORK), số di động(ADDR_MOBILE) hay các kiểu số điện thoại khác. Các thuộc tính là tùy chọn(option) và được quy định khi thêm giá trị mới vào field.

4.6.Kiểm tra hỗ trợ PIM trên thiết bị

Để kiểm tra sự hỗ trợ PIM API trên thiết bị, gọi phương thức System.getProperty(String property), trong đó gán tham số property=”microedition.pim.version”. Phương thức này sẽ trả về version của PIM API nếu thiết bị hỗ trợ PIM, ngược lại trả về null.

Ví dụ:

private Form form=null;

private String pimVersion=null;

public PIMMidlet()

{

form = new Form(“PIM version”);

pimVersion = System.getProperty(“microedition.pim.version”);

if (pimVersion!=null)

form.append(pimVersion);

else form.append(“PIM package is not supported”);

Display.getDisplay(this).setCurrent(form);

}

4.7.Kiểm tra PIM database

Để kiểm tra kiểu database như ContactList, EventList, ToDoList có được hỗ trợ trên thiết bị hay không, bạn sử dụng phương thức PIM.openList(int listType, mode).

Ví dụ:

private PIM pim=null;
    private EventList eventList=null;
    public PIMMidlet() {
        pim = PIM.getInstance();
        try {
            eventList = (EventList) pim.openPIMList(PIM.EVENT_LIST, PIM.READ_WRITE);
        }
            catch (SecurityException ex)
             {
                 ex.printStackTrace();
            }
           catch (PIMException ex) {
                 ex.printStackTrace ();
             } finally {
             if (eventList != null) {
                try {
                    eventList.close();
                } catch (PIMException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

Nếu kiểu danh sách chỉ định listType không hỗ trợ, thì khi gọi phương thức PIM.openList() sẽ ném một ngoại lệ PIMException. Nếu MIDlet không được quyền sử dụng PIM API, thì một ngoại lệ SecurityException sẽ được ném ra. Thông thường thì cả 3 kiểu database đều được tìm thấy trên thiết bị, và có nhiều list có thể tồn tại cho mỗi kiểu list.

Ví dụ: một vài thiết bị hỗ trợ nhiều Event lists, như meetings, reminders, calls, memos và birthday.

4.8.Quyền truy cập vào PIM API

Để mở PIM list ở chế độ đọc hoặc ghi, quyền(permission) đọc hoặc ghi PIM là bắt buột. Truy cập vào tài nguyên PIM mà không có quyền thích hợp sẽ ném một ngoại lệ java.lang.SecurityException.

Ví dụ: Khi bạn mở một PIM list ở dạng EventList, bạn phải thêm quyền như minh họa bên dưới vào file JAD.

MIDlet-Permissions: javax.microedition.pim.EventList.read,
                   javax.microedition.pim.EventList.write

4.9.Kiểm tra các trường được hỗ trợ

Không phải tất cả implementation của PIM đều hỗ trợ tất cả các trường hay thuộc  tính được định nghĩa trong đặc tả PIM API. Trước khi sử dụng một trường hay thuộc tính, bạn nên kiểm tra xem nó có được hỗ trợ hay không, nếu không hỗ trợ, nó sẽ ném một ngoại lệ UnsupportedFieldException hay IllegalArgumentException.

Để kiểm tra một field cụ thể có được hỗ trợ hay không, gọi phương thức:

PIMList.isSupportedField(int fieldID)

Ví dụ:

...
  if (eventList.isSupportedField(Event.LOCATION))
     form.append("Field is supported");
  else
     form.append("Field not supported");
...

Để kiểm tra một field STRING_ARRAY được hỗ trợ hay không, gọi phương thức:

PIMList.isSupportedArrayElement(int stringArrayFieldID, int arrayElement)

Để kiểm tra một thuộc tính cụ thể của một field cụ thể có được hỗ trợ hay không, gọi phương thức:

PIMList.isSupportedAttribute(int fieldID, int attributeID)

Để kiểm tra một field RepeatRule được hỗ trợ theo một tần số theo định kỳ, gọi phương thức:

EventList.getSupportedRepeatRuleFields(int requency)

5.Một số ví dụ

Ví dụ 1: Ví dụ này chỉ cho bạn cách để thêm một contact mới vào một address book để xử lý các field được hỗ trợ. Trong ví dụ này, việc thiết lập toàn bộ Contact sẽ bị từ chối nếu các field không được hỗ trợ trong danh sách cài đặt cụ thể.

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.pim.PIM;
import javax.microedition.pim.ContactList;
import javax.microedition.pim.Contact;
import javax.microedition.pim.PIMException;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.pim.PIMItem;
import java.lang.Runnable;
import java.lang.Thread;
import javax.microedition.pim.UnsupportedFieldException;

public class MainMidlet extends MIDlet implements CommandListener {

    private Display display = null;
    private final Command cmd_Exit = new Command("Exit", Command.EXIT, 1);
    private final Command cmd_Commit = new Command("Commit",
    Command.SCREEN, 2);
    private Form form = null;
    private ContactList contactList = null;
    private Contact contact = null;
    private String field_Name[] = null;
    private String field_Addr[] = null;
    private PIM pim = null;
    private TextField name,  familyName,  country,  locality,  postalCode,  street,
    telephone,  email_id;

    public MainMidlet() {

        init();
    }

    public void startApp() {

        display.setCurrent(form);

        if (contactList.isSupportedField(Contact.NAME) == true) {

            field_Name = new String[contactList.stringArraySize(Contact.NAME)];
            name = new TextField("NAME:", null, 40,
                    TextField.ANY);
            form.append(name);

            familyName = new TextField("FAMILY NAME:", null, 40,
                    TextField.ANY);
            form.append(familyName);

        }

        if (contactList.isSupportedField(Contact.ADDR)) {
            field_Addr = new String[contactList.stringArraySize(Contact.ADDR)];

            country = new TextField("COUNTRY:", null, 40,
                    TextField.ANY);
            form.append(country);

            locality = new TextField("LOCALITY:", null, 40,
                    TextField.ANY);
            form.append(locality);

            postalCode = new TextField("POSTALCODE:", null,
                    40, TextField.DECIMAL);
            form.append(postalCode);

            street = new TextField("STREET:", null, 40,
                    TextField.ANY);
            form.append(street);

            telephone = new TextField("TELEPHONE:", null, 40, TextField.DECIMAL);
            form.append(telephone);

            email_id = new TextField("EMAIL-ID", null, 40, TextField.ANY);
            form.append(email_id);
        }


    }

    public void pauseApp() {
    }

    public void destroyApp(boolean flag) {
    }

    public void init() {

        display = Display.getDisplay(this);
        form = new Form("Contact List Demo...");
        form.addCommand(cmd_Exit);
        form.addCommand(cmd_Commit);
        form.setCommandListener(this);
        try {
            pim = PIM.getInstance();
            contactList = (ContactList) pim.openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE, "Contacts");
        } catch (PIMException ex) {
            ex.printStackTrace();
        }

        if (contactList != null) {
            contact = contactList.createContact();
        }
    }

    public void commandAction(Command cmd, Displayable dis) {

        if (cmd == cmd_Exit) {
            destroyApp(true);
            notifyDestroyed();
        } else {
            new Thread(new Runnable() {

                public void run() {
                    try {
                        if (name.getString() != null) {
                            System.out.println();
                            field_Name[Contact.NAME_GIVEN] = name.getString();
                        }
                        if (familyName.getString() != null) {
                            field_Name[Contact.NAME_FAMILY] = familyName.getString();
                        }
                        if (country.getString() != null) {
                            field_Addr[Contact.ADDR_COUNTRY] = country.getString();
                        }
                        if (locality.getString() != null) {
                            field_Addr[Contact.ADDR_LOCALITY] = locality.getString();
                        }
                        if (postalCode.getString() != null) {
                            field_Addr[Contact.ADDR_POSTALCODE] = postalCode.getString();
                        }
                        if (street.getString() != null) {
                            field_Addr[Contact.ADDR_STREET] = street.getString();
                        }
                        if (field_Name != null) {
                            contact.addStringArray(Contact.NAME, PIMItem.ATTR_NONE, field_Name);
                        }
                        if (field_Addr != null) {
                            contact.addStringArray(Contact.ADDR, Contact.ATTR_HOME, field_Addr);
                        }
                        if (telephone.getString() != null) {
                            contact.addString(Contact.TEL, Contact.ATTR_HOME, telephone.getString());
                        }
                        if (email_id.getString() != null) {
                            contact.addString(Contact.EMAIL, Contact.ATTR_HOME | Contact.ATTR_PREFERRED,
                                    email_id.getString());
                        }
                        contact.commit();
                        Alert alert = new Alert("info ", "Data added to PIM", null, AlertType.CONFIRMATION);
                        alert.setTimeout(2000);
                        display.setCurrent(alert, form);
                    } catch (UnsupportedFieldException e) {
                        e.printStackTrace();
                    } catch (PIMException ex) {
                        ex.printStackTrace();
                    } finally {
                        try {
                            contactList.close();
                        } catch (PIMException ex) {
                            ex.printStackTrace();
                        }


                    }
                }
            }).start();

        }
    }
}

Ví dụ 2:

PIM API cung cấp một số phương thức để import và export PIM data sử dụng các định dạng trao đổi dữ liệu chuẩn. Để nhận biết các định dạng trao đổi dữ liệu được hỗ trợ, gọi phương thức supportedSerialFormats(PIMListType).

private Display display=null;
    private PIM pim = null;
    private String supportedFormats[] = null;
    private static final Command cmd_Exit = new Command("Exit",Command.EXIT,1);
    private Form   form;

    public PIM2_Midlet()  {

            display = Display.getDisplay(this);
            form = new Form("PIM supported Format");
            pim = PIM.getInstance();
            if(pim != null)
            {
                //EVENT_LIST //CONTACT_LIST//
                supportedFormats = pim.supportedSerialFormats(PIM.CONTACT_LIST);
            }
            if(supportedFormats.length > 0)
            {
                for(int i=0;i<supportedFormats.length;i++)
                {
                    form.append("\n"+supportedFormats[i]);
                }
            }
            form.addCommand(cmd_Exit);
            form.setCommandListener(this);
            display.setCurrent(form);
    }

Ví dụ 3:

Để nhận biết các kiểu định dạng trao đổi dữ liệu PIM lists, chỉ cần thay thế PIM.CONTACT_LIST cho PIM.EVENT_LIST hay PIM.TODO_LIST. Ví dụ này sẽ mô phỏng cách export calendar event vào một file trong định dạng xác định.

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Command;
import java.lang.Runnable;
import java.lang.Thread;
import javax.microedition.lcdui.List;
import java.util.Vector;
import javax.microedition.pim.PIM;
import javax.microedition.pim.EventList;
import javax.microedition.pim.Event;
import javax.microedition.pim.PIMException;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import java.util.Enumeration;
import javax.microedition.pim.PIMItem;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.Connector;
import java.io.OutputStream;
import java.util.Date;
import javax.microedition.lcdui.DateField;
import javax.microedition.pim.PIMList;

public class PIMExportMidlet extends MIDlet implements CommandListener{

    private Display display=null;
    private static final Command cmd_Exit = new Command("Exit",Command.EXIT,1);
    private static final Command cmd_Export = new
                                                    Command("ExportEvent",Command.SCREEN,2);
    private List event_implicitList=null;
    private Vector eventVector=null;
    private PIM pim=null;
    private EventList eventList=null;
    private final String FILE_PATH="file://localhost/root1/";
    private final String FILE="exportEvent.txt";
    private final String exportEncoding = "UTF-8";
    private DateField startDateField;
    private DateField endDateField;

    public PIMExportMidlet()
    {
        if(System.getProperty("microedition.pim.version")!=null)
             init();
        else
             exitMidlet();
    }

    public void startApp() {

        new Thread(new Runnable()
        {
            public void run()
            {
                try {
                    pim = PIM.getInstance();
                    eventList = (EventList)
                        pim.openPIMList(PIM.EVENT_LIST,PIM.READ_WRITE);
                    if(eventList==null)
                    {
                        alertBox("Event List is not supported");
                    }
                    addEvent();
                    if(eventList.isSupportedField(Event.SUMMARY))
                    {
                           Enumeration e = eventList.items();
                           while(e.hasMoreElements())
                           {
                                Event event =(Event)e.nextElement();
                                eventVector.addElement(event);
                                String field_String =
                                     event.getString(Event.SUMMARY,PIMItem.ATTR_NONE);
                                event_implicitList.append(field_String,null);
                           }
                           eventList.close();
                           display.setCurrent(event_implicitList);
                    }
                    else
                    {
                         alertBox("Field SUMMARY not supported");
                    }
                } catch (PIMException ex) {
                    ex.printStackTrace();
                }
            }
        }
        ).start();
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
    private void init()
    {
        display = Display.getDisplay(this);
        eventVector = new Vector();
        event_implicitList = new List("Event List...",List.IMPLICIT);
        event_implicitList.addCommand(cmd_Exit);
        event_implicitList.addCommand(cmd_Export);
        event_implicitList.setCommandListener(this);
    }
    private void alertBox(String data)
    {
        Alert alert = new Alert("Information",data,null,
        AlertType.INFO);
        alert.setTimeout(Alert.FOREVER);
        alert.addCommand(cmd_Exit);
        alert.setCommandListener(this);
        display.setCurrent(alert);
    }
    private void addEvent()
    {

            Event event = eventList.createEvent();
            if(eventList.isSupportedField(Event.SUMMARY) == true) {
                String summary = "Export Event";
                event.addString(Event.SUMMARY, PIMItem.ATTR_NONE, summary);
            }
            if(eventList.isSupportedField(Event.START) == true) {
                startDateField = new DateField("Start date",DateField.DATE_TIME);
                startDateField.setDate(new Date());
                long startDate = startDateField.getDate().getTime();
                event.addDate(Event.START, PIMItem.ATTR_NONE, startDate);
            }
            if(eventList.isSupportedField(Event.END) == true) {
                endDateField = new DateField("End date", DateField.DATE_TIME);
                endDateField.setDate(new Date());
                long endDate = endDateField.getDate().getTime();
                event.addDate(Event.END, PIMItem.ATTR_NONE, endDate);
            }
        try {
            event.commit();
        } catch (PIMException ex) {
            ex.printStackTrace();
        }

    }
    private void exportPIMEvent()
    {

        if(System.getProperty("microedition.io.file.FileConnection.version") == null)
        {
            alertBox("File Connection is not supported");
        }
        final String supported_format[] = pim.supportedSerialFormats(PIM.EVENT_LIST);
        if(supported_format.length>0)
        {
            int eventIndex = event_implicitList.getSelectedIndex();
            final Event event = (Event)eventVector.elementAt(eventIndex);
            new Thread(new Runnable(){
            public void run()
            {
                FileConnection fileConn=null;
                OutputStream outPut=null;
                    try {
                            fileConn = (FileConnection) Connector.open(FILE_PATH+FILE,Connector.READ_WRITE);
                        if(!fileConn.exists())
                            fileConn.create();
                            outPut = fileConn.openOutputStream();
                        pim.toSerialFormat(event, outPut, exportEncoding, supported_format[0]);
                    } catch (PIMException ex) {
                    ex.printStackTrace();
                    } catch (UnsupportedEncodingException ex) {
                    ex.printStackTrace();
                    }catch (IOException ex) {
                        ex.printStackTrace();
                    }
                finally{
                        try {

                            outPut.close();
                            fileConn.close();
                            alertBox("Data successfully exported to file...");
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                }
            }
            }).start();

        }
    }
    private void exitMidlet()
    {
        destroyApp(true);
        notifyDestroyed();
    }
    public void commandAction(Command cmd,Displayable dis)
    {
        if(cmd == cmd_Exit)
            exitMidlet();
        else
        {
            exportPIMEvent();
        }

    }
}

Ví dụ 4:

Ví dụ này sẽ mô phỏng cách import một Contact.

 
import java.io.IOException;
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Alert;

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

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;

import java.util.Enumeration;
import java.io.InputStream;

public class PIMImportMidlet extends MIDlet implements CommandListener  {

    private Display display;
    private List importContactList;
    private final  Command cmd_Exit= new Command("Exit",Command.EXIT,1) ;
    private final Command cmd_Import= new Command("Import contact", Command.SCREEN,2);
     private final String importEncoding = "UTF-8";
    private final String FILE_PATH = "file://localhost/root1/";
    private final String FILE = "5.vcf";
    private FileConnection fileConn=null;
    private InputStream inPutStream=null;

    public PIMImportMidlet() {
        if(System.getProperty("microedition.pim.version")==null) {
            exitMIDlet();
        }
        init();
    }

    private void init() {

        display = Display.getDisplay(this);
        importContactList = new List("contacts", List.IMPLICIT);
        importContactList.addCommand(cmd_Import);
        importContactList.addCommand(cmd_Exit);
        importContactList.setCommandListener(this);
        addContactsToListCtrl();
    }

    private void addContactsToListCtrl() {
        try {

            ContactList contactList = (ContactList)PIM.getInstance().openPIMList( PIM.CONTACT_LIST, PIM.READ_WRITE);

            if(contactList.isSupportedField(Contact.NAME) == false) {
                showMsg("Info", "Contact.Name not supported");
            }
            if(contactList.isSupportedField(Contact.ADDR) == false)  {

                showMsg("Info", "Contact.ADDR not supported");
            }
            importContactList.deleteAll();
            Enumeration contacts = contactList.items();
            while(contacts.hasMoreElements() == true) {
                Contact contact = (Contact)contacts.nextElement();
                String[] name = contact.getStringArray(Contact.NAME,
                        PIMItem.ATTR_NONE);
                String
                 address[]=contact.getStringArray(Contact.ADDR,PIMItem.ATTR_NONE);
                String family = name[Contact.NAME_FAMILY];
                String nameGiven = name[Contact.NAME_GIVEN];
                String country = address[Contact.ADDR_COUNTRY];
                String locality = address[Contact.ADDR_LOCALITY];
                String postalCode = address[Contact.ADDR_POSTALCODE];
                String street = address[Contact.ADDR_STREET];
                importContactList.append(family, null);
                importContactList.append(nameGiven, null);
                importContactList.append(country, null);
                importContactList.append(locality, null);
                importContactList.append(postalCode, null);
                importContactList.append(street, null);

            }
            contactList.close();

        } catch(PIMException e) {
            e.printStackTrace();
        } catch(SecurityException e) {
            e.printStackTrace();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private boolean importContact() {

        if(System.getProperty("microedition.io.file.FileConnection.version")!=null)
            return false;
        try {
        fileConn = (FileConnection)Connector.open(FILE_PATH+FILE,Connector.READ_WRITE);

        if(fileConn.exists() == false) {
            throw new Exception("File for importing was not found.");
        }

         inPutStream = fileConn.openInputStream();
        PIMItem[] items = PIM.getInstance().fromSerialFormat(inPutStream,importEncoding);

        if(items.length > 0) {
            ContactList contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);
            Contact newcontact = contactList.importContact((Contact)items[0]);
            newcontact.commit();
            contactList.close();
        }

        showMsg("Info", "Contact was imported from file.");

        } catch(Exception e) {
            showMsg("Error", e.getMessage());
            return false;
        }
        finally{
            try {
                inPutStream.close();
                fileConn.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return true;
    }

    private void showMsg(String title, String message) {
        Alert alert = new Alert(title);
        alert.setString(message);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
    }

    public void startApp() {
        display.setCurrent(importContactList);
    }

    public void pauseApp() {

    }

    public void destroyApp(boolean unconditional) {

    }

    private void exitMIDlet() {
        notifyDestroyed();
    }

    public void commandAction(Command command, Displayable displayable) {

        if(command == cmd_Import) {
            if(importContact()== true) {
                new Thread(new Runnable(){
                public void run()
                {
                    addContactsToListCtrl();
                }
                }).start();

            }
        }
        else if(command == cmd_Exit) {
            exitMIDlet();
        }
    }
}

Bạn thấy bài viết này thế nào?

Các bài liên quan:
Managing Personal Information(PIM) – JSR 75-Phan1