BlackBerry 应用程序开发者指南 第二卷:高级--第3章 集成PIM功能


作者:Confach 发表于2006-04-28 22:18 pm
版权信息:可以任意转载, 转载时请务必以超链接形式标明文章原始出处 和作者信息.
http://www.cnblogs.com/confach/articles/387944.html

3

3 集成PIM功能

PIM API

使用地址本

使用任务

使用日历

PIM API

Java个人信息管理(Personal Information Manager,PIM) API(javax.microedition.pim)以及BlackBerry PDAP(Personal Digital Assistant Profile) API(net.rim.blackberry.api.pdap)允许你访问BlackBerry设备上的日历,任务,以及地址本.
:4.0版本里,net.rom.blackberry.api.pim包是不赞成使用的. 现在这个包里的类在javax.microedition.pim and net.rim.blackberry.api.pdap里可以得到.

PIM类是一个抽象类,它提供了访问BlackBerry设备上的PIM数据的方法.

获取一个PIM对象

调用PIM.getInstance().

:当你的应用程序第一次访问PIM API,它将检查一个ControlledAccessException.如果系统管理员使用应用程序控制限制访问PIM API,一个运行时异常将会抛出.为获取更多信息,参看BlackBerry应用程序开发者指南 2:高级 第一卷:基础”.

PIM列表

PIM列的接口代表了所有联系人,事件以及任务列的常用功能.一个列包含0个或多个项,它们是PIMItem的子类.使用PIM列组织相关项,并且获取一些或所有列表的项.
:BlackBerry设备里,每个ContactList,ToDoListEventList实例都会涉及到BlackBerry设备上的本地数据库.第三方应用程序不能创建自定义的列表.

PIM

PIMItem接口代表了一个列项常用的功能.Contact,Event,以及ToDo接口扩展了PIMItem.一个PIM项代表了单个入口的数据集合,例如一个约会或者一个联系人.

当你在一个指定的PIM列表上创建一个PIM项时,自从它存在开始,此项仍保留了和列表的关联.你也可以使用标准的格式,例如iCalvCard,导入或导出PIM项里的数据.

字段

一个PIM项在字段里存储数据.每个PIMItem接口-Contact,Event,ToDo-为每个支持的字段定义了唯一的ID.例如,Contact接口定义字段来存储一个internet消息地址(EMAIL),姓名(FORMATTED_NAME),以及电话号码(TEL).

在你试图设置或获取字段值之前,调用PIMList.isSupportedField(int)来确认是否支持方法.

一个字段可能有一个与之关联的具有描述性的标签显示给用户.为获取这个字段的标签,调用PIMList.getFieldLabel(int).

每个字段都有一个数据类型ID,例如INT,BINARY,DATE,BOOLEAN,STRING.为了得到一个字段的数据类行,调用PIMList.getFieldDataType(int).

数据类型决定了你将使用哪一个方法得到或设置字段数据.例如:

  • 如果字段的数据类型为STRING,为了加入一个值,调用PIMItem.addString(String).
  • 为了改变已经存在的值,调用PIM.setString(String).
  • 为了获取一个字段值,调用PIMItem.getString().

监听者

当列表里的一个项发生变化时,你的PIMListListener接口实现会收到这个通知. PIMListListener接口提供了下面的方法:

方法

描述

itemAdded(PIMItem)

当加入一个项到列表时调用.

item.Removed(PIMItem)

当从列表里删除时调用.

itemUpdated(PIMItem,PIMItem)

当一个项发生变化时调用.

 

ContactList cl = (ContactList)PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.WRITE_ONLY);

((BlackBerryPIMList)cl).addListener(

       new PIMListListener() {

           public void itemAdded(PIMItem item) {

              System.out.println(" ITEM ADDED: " +

                     ((Contact)item).getString(Contact.UID, 0));

              }

          

           public void itemUpdated(PIMItem oldItem, PIMItem newItem) {

              System.out.println(" ITEM UPDATED: " +

                      ((Contact)oldItem).getString(Contact.UID, 0) + " to " +

                     ((Contact)newItem).getString(Contact.UID, 0));

              }

          

           public void itemRemoved(PIMItem item) {

              System.out.println(" ITEM REMOVED: " +

                     ((Contact)item).getString(Contact.UID, 0));

              }

});


:监听者仍然保持和BlackBerry设备数据库的关联,甚至是在相应的PIMList对象已经删除之后.为了删除一个监听者,调用BlackBerryPIMList.removeListener().

远程地址查询

支持远程地址查询的应用程序应该实例化BlackBerryContactList接口.此节口扩展了ContactList接口,并且提供了下面额外的方法:

方法

描述

choose(Contact, int, boolean)

启动地址本以至用户可以选择一个地址.

void lookup(Contact, RemoteLookupListener)

初始化一个远程查询.

void lookup(String, RemoteLookupListener)

初始化一个远程查询.

RemoteLookupListener接口提供了一单个方法,items(),此方法返回一个远程地址查询结果的迭代.

使用地址簿

使用一个ContactList的实例增加或查看BlackBerry设备地址簿的联系人信息.创建Contact对象存储单独的联系人信息,此信息包含姓名,电话号码,Email,以及街道地址.

BlackBerry特定的地址字段

BlackBerryContact接口扩展了Contact,为了访问BlackBerry联系人特定的字段, 它定义了下面的常数:

常量

描述

BlackBerryContact.PIN

访问PIN字段.

BlackBerryContact.USER1 USER4

访问USER1USER4字段.

为了定义USER1USER4字段的标签,调用BlackBerryPIMList.setFieldLabel().

此改变立即生效.你不必要提交改变.
:改变一个标签将影响所有BlackBerry设备上的联系人.

打开一个联系人列表

在你增加联系人之前,你必须创建一个联系人列表.调用PIM.openPIMList().将列表的类型作为参数提供给open(PIM.CONTACT_LIST),并且提供访问模式(READ_WRITE,READ_ONLY,WRITE_ONLY)打开列表.

如果你正在为BlackBerry设备专门编写一个应用程序,将你的联系人列表转化为BlackBerryContactList,因为此接口提供了一个附加的方法来支持远程地址查询.为了让一个应用程序可以跨多个兼容的Java ME BlackBerry设备,使用PDAP实现.

ContactList contactList = null;

try {

    contactList = (ContactList)PIM.getInstance().openPIMList(

                          PIM.CONTACT_LIST, PIM.READ_WRITE);

 }

catch (PimException e) {

    return;

 }

 

:联系人不会加到数据库中,直到你提交它.为获得更多信息,参看30页的保存一个联系人”.

创建一个联系人

调用联系人列表的createContact().

Contact contact = contactList.createContact();

增加联系人信息

Contact类定义了保存数据的字段,例如Contact.Name,Contact.ADDR,以及Contact.TEL.每个字段都有一个特定的数据类型,你可以调用PIMList.getFieldDataType(int)来获取它们.由于依赖字段的数据类型,通过调用下列方法创建一个新值: addString(), addStringArray(), addDate(), addInt(), addBoolean(), addBinary().

在你设置和获取一个字段之前,为了验证列表项是否支持字段,调用:

ContactList.isSupportedField(int)

通过使用属性来区分其值,某些字段可以存储多个值.例如,TEL字段支持ATTR_HOME,ATTR_WORK,ATTRMOBILEATTR_FAX属性存储工作,家庭,移动以及传真号码.

为了判断一个字段最多支持几个值,调用PIMList.maxValues(int field).

此方法返回支持的值的个数,返回-1意味着可以增加任意个数的值.为了验证一个字段是否支持特定的属性,调用isSupportedAttribute(int, int).

// Create string array for name.

try {

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

}

catch (PIMException e)

{  

}

 

Contact contact = contactList.createContact();

String[] name = new String[5]; // 5 name elements

try {

    name[Contact.NAME_PREFIX] = "Mr.";

    name[Contact.NAME_FAMILY] = "McPherson";

    name[Contact.NAME_GIVEN] = "Scott";

    }

catch (IllegalArgumentException iae) {

    // handle exception

}

 

 

// Add name.

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

    contact.addStringArray(Contact.NAME, Contact.ATTR_NONE, name);

}

 

// Create string array for address.

String[] address = new String[7]; // 7 address elements

try {

    address[Contact.ADDR_COUNTRY] = "United States";

    address[Contact.ADDR_LOCALITY] = "Los Angeles";

    address[Contact.ADDR_POSTALCODE] = "632300";

    address[Contact.ADDR_REGION] = "California";

    address[Contact.ADDR_STREET] = "323 Main Street";

    }

catch (IllegalArgumentException iae) {

 // Handle exception.

 }

 

// Add address.

contact.addStringArray(Contact.ADDR, Contact.ATTR_NONE, address);

 

// Add home telephone number.

if (contactList.isSupportedField(Contact.TEL) &&

    contactList.isSupportedAttribute(Contact.TEL, Contact.ATTR_HOME))

{

    contact.addString(Contact.TEL, Contact.ATTR_HOME, "555-1234");

}

 

// Add work telephone number.

if (contactList.isSupportedField(Contact.TEL)) {

    contact.addString(Contact.TEL, Contact.ATTR_HOME, "555-5555");

}

 

// Add work internet messaging address.

if (contactList.isSupportedField(Contact.EMAIL)) {

    contact.addString(Contact.EMAIL,

                     Contact.ATTR_WORK,

                     "aisha.wahl@blackberry.com");

}

修改联系人信息

对于仅支持一个值的字段,调用合适的set方法用一个新值替代一个已存在的值.

:如果你调用一个增加方法,例如addString(),对于已经存在一个值的字段来说,将抛出一个FieldFullException异常.使用相应的set方法,例如setString(),修改一个已经存在的值.

对于包含了一个字符数组的姓名和地址字段,获取此数组,然后将它加入之前,修改一个或多个数组上的索引.

if (contact.countValues(Contact.NAME) > 0) {

    String[] newname = contact.getStringArray(Contact.NAME, 0);

}

// Change the prefix to Dr. and add the suffix, Jr.

newname[Contact.NAME_PREFIX] = "Dr.";

newname[Contact.NAME_SUFFIX] = "Jr.";

contact.setStringArray(Contact.NAME, 0, Contact.ATTR_NONE, newname);

对于支持多个值的字段,在将另外一个值加入之前,先验证其没有超过值的最大个数。

if (contact.countValues(Contact.EMAIL) < contactList.maxValues(Contact.EMAIL))

 {

    contact.addString(Contact.EMAIL,Contact.ATTR_NONE, aisha.wahl@blackberry.com");

}

保存一个联系人信息

调用commit().在提交修改之前,为判断任何联系人字段自从最后保存以来是否已经发生变化,调用isModified().

if(contact.isModified()) {

    contact.commit();

}

获取联系人信息

调用PIMList.Items()

:当你调用PIMList.Items()获取一个列表项的迭代时,列表项的顺序没有定义.如果必要,你的应用程序必须将它们排序.

对于一个特定的联系人,调用PIMItem.getFields()获取一个拥有数据的字段ID的数组.调用PIMItem.getString()获取字段值.

ContactList contactList = (ContactList)PIM.getInstance().openPIMList(

       PIM.CONTACT_LIST, PIM.READ_WRITE);

Enumeration enum = contactList.items();

while (enum.hasMoreElements()) {

    Contact c = (Contact)enum.nextElement();

    int[] fieldIds = c.getFields();

    int id;

    for(int index = 0; index < fieldIds.length; ++index) {

       id = fieldIds[index];

       if(c.getPIMList().getFieldDataType(id) == Contact.STRING)

       {

           for(int j=0; j < c.countValues(id); ++j) {

              String value = c.getString(id, j);

              System.out.println(c.getPIMList().getFieldLabel(id) + "=" + value);

              }

       }

    }

}

将一个联系人转化为序列化格式

为了导入或导出PIM项数据,使用一个输出写入流将BlackBerry设备中的任务导出为一个支持的序列化格式,例如vCard.

为了获取一个支持的格式的字符串数组,调用PIM.supportedSerialFormats(),并指定列表类型(PIM.Contact_LIST).为了将一个项写到一个支持的序列化格式里,调用toSerialFormat().

:当写到一个输出流时enc参数指定了字符编码格式.支持的字符编码格式包括"UTF8," "ISO-8859-1," "UTF-16BE."此参数不能为空.

ContactList contactList = (ContactList)PIM.getInstance().openPIMList(

       PIM.CONTACT_LIST, PIM.READ_ONLY);

String[] dataFormats = PIM.getInstance().supportedSerialFormats(

       PIM.CONTACT_LIST);

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

Enumeration e = contactList.items();

while (e.hasMoreElements()) {

    Contact c = (Contact)e.nextElement();

    PIM.getInstance().toSerialFormat(c, byteStream, "UTF8", dataFormats[0]);

}

导入一个联系人

为了返回一组PIM,调用fromSerialFormat().使用PIM项为了创建一个新的联系人,调用ContactList.importContact()

:当写到一个输出流时enc参数指定了字符编码格式.支持的字符编码格式包括

"UTF8," "ISO-8859-1," "UTF-16BE."此参数不能为空.

// Import contact from vCard.

ByteArrayInputStream is = new ByteArrayInputStream(outputStream.toByteArray());

PIMItem[] pi = PIM.getInstance().fromSerialFormat(istream, "UTF8");

ContactList contactList = (ContactList)PIM.getInstance()

                        .openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);

Contact contact2 = contactList.importContact((Contact)pi[0]);

contact2.commit();

删除一个联系人

在联系人列表上调用removeContact()方法.

contactList.removeContact(contact);

关闭一个联系人列表

调用close().

try {

    contactList.close();

}

catch(PIMException e) {

    Dialog.alert(e.toString());

}

代码实例

下面的实例描述了如何显示一个屏幕来允许用户增加一个新的联系人到地址本中.在你保存一个联系人之后,打开地址本确认该联系人是否已经保存.


: ContactsDemo.java

/**

* ContactsDemo.java

* Copyright (C) 2002-2005 Research In Motion Limited.

*/

package com.rim.samples.docs.contactsdemo;

import java.io.*;

import java.util.*;

import javax.microedition.pim.*;

import net.rim.device.api.ui.*;

import net.rim.device.api.ui.component.*;

import net.rim.device.api.ui.container.*;

import net.rim.device.api.i18n.*;

import net.rim.device.api.system.*;

import net.rim.device.api.util.*;

import com.rim.samples.docs.baseapp.*;

import net.rim.blackberry.api.pdap.*;

 

public final class ContactsDemo extends BaseApp {

    private ContactScreen _contactScreen;

    public static void main(String[] args) {

       new ContactsDemo().enterEventDispatcher();

    }

    public ContactsDemo() {

       _contactScreen = new ContactScreen();

       pushScreen(_contactScreen);

    }

    protected void onExit() {

    }

   

// Inner class. Creates a Screen to add a contact.

public static final class ContactScreen extends MainScreen {

    private EditField _first, _last, _email, _phone, _pin;

    private SaveMenuItem _saveMenuItem;

   

    private class SaveMenuItem extends MenuItem {

       private SaveMenuItem() {

           super(null, 0, 100000, 5);

           }

      

       public String toString() {

           return "Save";

           }

       public void run() {

           onSave();

           }

       }

   

    public ContactScreen() {

       _saveMenuItem = new SaveMenuItem();

       setTitle(new LabelField("Contacts Demo",

              LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH));

       _first = new EditField("First Name: ", "");

       add(_first);

       _last = new EditField("Last Name: ", "");

       add(_last);

       _email = new EditField("Email Address: ", "",

              BasicEditField.DEFAULT_MAXCHARS, BasicEditField.FILTER_EMAIL);

       add(_email);

       _phone = new EditField("Work Phone: ", "",

              BasicEditField.DEFAULT_MAXCHARS, BasicEditField.FILTER_PHONE);

       add(_phone);

       _pin = new EditField("PIN:", "", 8, BasicEditField.FILTER_HEXADECIMAL);

       add(_pin);

       }

   

    protected boolean onSave() {

       String firstName = _first.getText();

       String lastName = _last.getText();

       String email = _email.getText();

       String phone = _phone.getText();

       String pin = _pin.getText();

      

       // Verify that a first or last name and email has been entered.

       if ((firstName.equals("") && lastName.equals("")) || email.equals("")) {

           Dialog.inform("You must enter a name and an email address!");

           return false;

           }

       else {

           try {

              ContactList contactList = (ContactList)PIM.getInstance().

                            openPIMList(PIM.CONTACT_LIST, PIM.WRITE_ONLY);

              Contact contact = contactList.createContact();

              String[] name = new String[contactList.stringArraySize(Contact.NAME)];

             

              // Add values to PIM item.

             

              if (!firstName.equals("")) {

                  name[Contact.NAME_GIVEN] = firstName;

                  }

              if (!lastName.equals("")) {

                  name[Contact.NAME_FAMILY] = lastName;

                  }

              contact.addStringArray(Contact.NAME, Contact.ATTR_NONE, name);

              contact.addString(Contact.EMAIL, Contact.ATTR_HOME, email);

              contact.addString(Contact.TEL, Contact.ATTR_WORK, phone);

              if (contactList.isSupportedField(BlackBerryContact.PIN)) {

                  contact.addString(BlackBerryContact.PIN, Contact.ATTR_NONE, pin);

                  }

             

              // Save data to address book.

              contact.commit();

              // Reset UI fields.

              _first.setText("");

              _last.setText("");

              _email.setText("");

              _phone.setText("");

              _pin.setText("");

              return true;

              }

           catch (PIMException e) {

              return false;

              }

           }

       }

   

    protected void makeMenu(Menu menu, int instance) {

       menu.add(_saveMenuItem);

       super.makeMenu(menu, instance);

       }

    }

}


<!--[if !vml]--><!--[endif]-->

使用任务

使用一个ToDoList类的实例来存储任务或计划项的列表. 为每个任务创建一个或多个ToDo对象来存储数据,例如主题(summary),优先级,持续的时间以及状态.

打开一个任务列表

调用PIM.openPIMList(),将列表的类型作为open (PIM.TODO_LIST)的参数

,并且指定访问的模式(READ_WRITE, READ_ONLY,WRITE_ONLY)打开列表.

ToDoList todoList = null;

try {

    todoList = (ToDoList)PIM.getInstance().openPIMList(PIM.TODO_LIST, PIM.READ_WRITE);

}

catch (PimException e) {

    //an error occurred

    return;

}

创建一个任务

调用任务列表上的createToDo().

ToDo task = todoList.createToDo();

toSerialFormat().

<!--[if !vml]--><!--[endif]-->:新增加的任务不会存到数据库,直到你提交它.为获得更多信息,参看35页的保存一个任务”.

增加任务信息

ToDo类定义字段来存储数据,例如SUMMARY,PRIORITY以及DUE.每个字段都有一个特定的数据类型,你可以使用PIMList.getFieldDataType(int)调用它们.因为取决于字段的数据类型,调用以下方法设置数据:

addString(), addDate(), addInt(), addBoolean(), addBinary().

为获得更多关于字段的信息,参看25页的”PIM API”.

在你设置或获取一个字段之前, 调用isSupportedField(int)来验证此项是否支持字段.

if (todoList.isSupportedField(ToDo.SUMMARY)) {

    task.addString(ToDo.SUMMARY, ToDo.ATTR_NONE, "Create project plan");

}

if (todoList.isSupportedField(ToDo.DUE)) {

    Date date = new Date();

    task.addDate(ToDo.DUE, ToDo.ATTR_NONE, (date + 17280000));

}

if (todoList.isSupportedField(ToDo.NOTE)) {

    task.addString(ToDo.NOTE, ToDo.ATTR_NONE, "Required for meeting");

}

if (todoList.isSupportedField(ToDo.PRIORITY)) {

    task.addInt(Todo.PRIORITY, ToDo.ATTR_NONE, 2);

}

设置任务状态

使用PIM扩展字段ToDo.EXTENDED_FIELD_MIN_VALUE + 9.

常量

STATUS_NOT_STARTED

1

STATUS_IN_PROGRESS

2

STATUS_COMPLETED

3

STATUS_WAITING

4

STATUS_DEFERRED

5

 

task.addInt(ToDo.EXTENDED_FIELD_MIN_VALUE + 9, ToDo.ATTR_NONE, 2);

修改任务信息

为了用一个新值替换一个存在的值,调用合适的set方法,例如setString().为了判断一个字段已经设置其值,调用countValues().

:如果你调用一个增加方法,例如addString(),当一个值存在时,将抛出一个FieldFullException异常.使用相应的set方法,setString()改变一个存在的值.

if (task.countValues(ToDo.SUMMARY) > 0) {

    task.setString(ToDo.SUMMARY, 0, ToDo.ATTR_NONE, "Review notes");

}

保存一个任务

调用commit()方法.在你保存之前,为了决定自从上一次保存任务之后任何字段是否发生变化,调用isModified().

if(task.isModified())

{

    task.commit();

}

获取任务信息

获取一个迭代

调用任务列表上的PIMList.items().

ToDoList todoList = (ToDoList)PIM.getInstance().openToDoList(

       PIM.TODO_LIST, PIM.READ_ONLY);

Enumeration enum = todoList.items();

 

获取一个任务的字段ID以及值

对于某个特定的ToDo,为获取一组包含其数据的字段ID,调用PIMItem.getFields().

为获取字段值,调用PIMItem.getString().

while (enum.hasMoreElements()) {

    ToDo task = (ToDo)enum.nextElement();

}

int[] fieldIds = task.getFields();

int id;

for(int index = 0; index < fieldIds.length; ++index) {

    id = fieldIds[index];

    if(task.getPIMList().getFieldDataType(id) == STRING) {

       for(int j=0; j < task.countValues(id); ++j) {

           String value = task.getString(id, j);

           System.out.println(task.getFieldLable(id) + "=" + value);

           }

       }

}

将一个任务转化为序列化格式

为了导入或导出PIM项数据,使用一个输出写入流将BlackBerry设备中的任务导出为一个支持的序列化格式,例如vCard.

为了获取一个支持的格式的字符串数组,调用PIM.supportedSerialFormats(),并指定列表类型(PIM.TODO_LIST).

:当写到一个输出流时enc参数指定了字符编码格式.支持的字符编码格式包括"UTF8," "ISO-8859-1," "UTF-16BE."此参数不能为空.

ToDoList todoList = (ToDoList)PIM.getInstance().openPIMList(

       PIM.TODO_LIST, PIM.READ_ONLY);

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

String[] dataFormats = PIM.getInstance().supportedSerialFormats(PIM.TODO_LIST);

Enumeration e = todoList.items();

while (e.hasMoreElements()) {

    ToDo task = (ToDo)e.nextElement();

    PIM.getInstance().toSerialFormat(task, byteStream, "UTF8", dataFormats[0]);

}

导入一个任务

为返回一组PIMItem对象,调用fromSerialFormat().

使用PIM项创建一个新的任务,调用ToDoList.importToDo().

:当写到一个输出流时enc参数指定了字符编码格式.支持的字符编码格式包括"UTF8," "ISO-8859-1," "UTF-16BE."此参数不能为空.

String[] dataFormats = PIM.toDoSerialFormats();

 

// Write task to serial format.

ByteArrayOutputStream os = new ByteArrayOutputStream();

PIM.getInstance().toSerialFormat(task, os, "UTF8", dataFormats[0]);

// Import task from serial format.

ByteArrayInputStream is = new ByteArrayInputStream(outputStream.toByteArray());

PIMItem[] pi = PIM.getInstance().fromSerialFormat(is, "UTF8");

ToDoList todoList = (ToDoList)PIM.getInstance().openPIMList(

       PIM.TODO_LIST, PIM.READ_WRITE);

ToDo task2 = todoList.importToDo((ToDo)pi[0]);

提示: importToDo()方法保存一个任务,因此你不必要调用commit()方法.

删除一个任务

调用任务列表上的removeToDo().

todoList.removeToDo(task);

关闭一个任务列表

调用todoList.close().务必捕捉应用的异常:

try {

    todoList.close();

    }

catch (PimException e) {

    // Handle exception.

}

代码实例


: TaskDemo.java

/**

* TaskDemo.java

* Copyright (C) 2002-2005 Research In Motion Limited.

*/

package com.rim.samples.docs.taskdemo;

import java.io.*;

import java.util.*;

import javax.microedition.pim.*;

import net.rim.device.api.ui.*;

import net.rim.device.api.ui.component.*;

import net.rim.device.api.ui.container.*;

import net.rim.device.api.i18n.*;

import net.rim.device.api.system.*;

import net.rim.device.api.util.*;

import com.rim.samples.docs.baseapp.*;

 

public final class TaskDemo extends BaseApp {

    private TaskScreen _taskScreen;

    public static void main(String[] args) {

       new TaskDemo().enterEventDispatcher();

       }

   

    private TaskDemo() {

       _taskScreen = new TaskScreen();

       pushScreen(_taskScreen);

       }

   

    protected void onExit() {

      

    }

   

    public final static class TaskScreen extends MainScreen {

       // Members.

       private EditField _summary, _note;

       private DateField _due;

       private ObjectChoiceField _priority, _status;

       private SaveMenuItem _saveMenuItem;

       private class SaveMenuItem extends MenuItem {

           private SaveMenuItem() {

              super(null, 0, 100000, 5);

              }

           public String toString() {

              return "Save";

              }

           public void run() {

              onSave();

              }

       }

      

       public TaskScreen() {

           _saveMenuItem = new SaveMenuItem();

           setTitle(new LabelField("Tasks Demo",

                  LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH));

           _summary = new EditField("Task Summary: ", "");

           add(_summary);

          

           // In TODO.Priority, 0 to 9 is highest to lowest priority.

           String[] choices = {"High", "Normal", "Low"};

           _priority = new ObjectChoiceField("Priority: ", choices, 1);

           add(_priority);

           String[] status = { "Not Started", "In Progress", "Completed",

                              "Waiting on someone else", "Deferred" };

           _status = new ObjectChoiceField("Status: ", status, 0);

           add(_status);

           _due = new DateField("Due: ", System.currentTimeMillis() + 3600000,

                  DateField.DATE_TIME);

           add(_due);

           _note = new EditField("Extra Notes: ", "");

           add(_note);

       }

      

       protected boolean onSave() {

           try {

              ToDoList todoList = (ToDoList)PIM.getInstance().

              openPIMList(PIM.TODO_LIST, PIM.WRITE_ONLY);

              ToDo task = todoList.createToDo();

              task.addDate(ToDo.DUE, ToDo.ATTR_NONE, _due.getDate());

              task.addString(ToDo.SUMMARY, ToDo.ATTR_NONE, _summary.getText());

              task.addString(ToDo.NOTE, ToDo.ATTR_NONE, _note.getText());

              task.addInt(ToDo.PRIORITY, ToDo.ATTR_NONE,

                     _priority.getSelectedIndex());

             

              // ToDo.EXTENDED_FIELD_MIN_VALUE + 9 represents status.

              // Add 1 to selected index so that values are correct.

              // See the RIM Implementation Notes in the API docmentation for ToDo.

              task.addInt(ToDo.EXTENDED_FIELD_MIN_VALUE + 9, ToDo.ATTR_NONE,

                     _status.getSelectedIndex() + 1);

             

              // Save task to handheld tasks.

              task.commit();

              _summary.setText("");

              _note.setText("");

              _due.setDate(null);

              _priority.setSelectedIndex(1); // Reset to “Normal” priority.

              _status.setSelectedIndex(0); // Reset to “Not Started” status.

              return true;

              }

           catch (PIMException e) {

              return false;

               }

           }

      

       protected void makeMenu(Menu menu, int instance) {

           menu.add(_saveMenuItem);

           super.makeMenu(menu, instance);

           }

       }

}


使用日历

使用一个EventList接口的实例访问日历.为一个约会创建一个或多个对象存储信息.对于每个事件.你可以存储类似主题,地点,开始和结束事件,以及提醒通知的数据.

打开一个事件列表

在可以增加事件之前你必须创建一个EventList.调用PIM.openPIMList().

 

调用PIM.openPIMList(),将列表的类型作为open (PIM.EVENT_LIST)的参数

,并且指定访问的模式(READ_WRITE, READ_ONLY,WRITE_ONLY)打开列表.

EventList eventList = null;

try {

    eventList = (EventList)PIM.getInstance().openPIMList(

           PIM.EVENT_LIST, PIM.READ_WRITE);

}

catch (PimException e) {

    // Handle exception.

}

创建一个约会

调用一个事件列表上的createEvent().

Event event = eventList.createEvent();

:约会不会加到数据库中,直到你提交它.为获得更多信息,参看41页的保存一个约会”.

增加约会信息

Event类定义了存储数据的字段,例如SUMMARY, LOCATION, START, END, 以及 ALARM.每个字段都有一个指定的类型,你可以调用PIMList.getFieldDataType(int)获得数据类型.

因为取决于字段的数据类型,调用以下方法设置数据:

addString(), addDate(), addInt(), addBoolean(), addBinary().

在你设置或获取一个字段之前, 调用isSupportedField(int)来验证此项是否支持字段.

if (event.isSupportedField(Event.SUMMARY)) {

    event.addString(Event.SUMMARY, Event.ATTR_NONE, "Meet with customer");

}

if (event.isSupportedField(Event.LOCATION)) {

    event.addString(Event.LOCATION, Event.ATTR_NONE, "Conference Center");

}

Date start = new Date(System.currentTimeMillis() + 8640000);

if (event.isSupportedField(Event.START)) {

    event.addDate(Event.START, Event.ATTR_NONE, start);

}

if (event.isSupportedField(Event.END)) {

    event.addDate(Event.END, Event.ATTR_NONE, start + 72000000);

}

if (event.isSupportedField(Event.ALARM)) {

    if (event.countValues(Event.ALARM) > 0) {

        event.removeValue(Event.ALARM,0);

       event.setInt(Event.ALARM, 0, Event.ATTR_NONE, 396000);

       }

}

创建一个重复发生(recurring)的约会

为了定义一个重复发生的约会,使用一个RepeatRule对象.RepeatRule类为你可以设置的属性和值定义了字段,例如COUNT, FREQUENCY, INTERVAL.

为了获取一组支持的字段,调用RepeatRule.getFields().

定义重复模式

调用新的RepeatRule对象上的setInt(int, int) setDate(int, int, int, long).

RepeatRule recurring = new RepeatRule();

recurring.setInt(RepeatRule.FREQUENCY, RepeatRule.MONTHLY);

recurring.setInt(RepeatRule.DAY_IN_MONTH, 14);

指派约会一个重复模式

调用一个事件上的setRepeat(RepeatRule).

EventList eventList = (EventList)PIM.getInstance().openPIMList(

PIM.EVENT_LIST, PIM.READ_WRITE);

Event event = eventList.createEvent();

event.setRepeat(recurring);

修改约会信息

为使用一个新值代替已经存在的值,调用合适的set方法,例如setString().

为判断一个字段是否已经设置了一个值,调用countValues().
:当一个值已经存在时,如果你调用一个增加方法,抛出一个FieldFullException.使用相应的set方法,例如setString(),来修改一个已经存在的值.

if (event.countValues(Event.LOCATION) > 0) {

    event.setString(Event.LOCATION, 0, Event.ATTR_NONE, "Board Room");

}

保存一个约会

提示: importEvent()方法保存一个约会,因此你没有必要调用commit().

调用commit()方法.在你保存之前,为了决定自从上一次保存任务之后任何字段是否发生变化,调用isModified().

if(event.isModified()) {

    event.commit();

}

获取约会信息

获取一个约会的迭代

调用PIMList.items().

EventList eventList = (EventList)PIM.getInstance().openPIMList(

       PIM.EVENT_LIST, PIM.READ_ONLY);

Enumeration e = eventList.items();

 

获取字段的ID和值

对于某个特定的ToDo,为获取一组包含其数据的字段ID.调用PIMItem.getFields().

获取字段值,调用PIMItem.getString().

while (e.hasMoreElements()) {

    Event event = (Event)e.nextElement();

    int[] fieldIds = event.getFields();

    int id;

    for(int index = 0; index < fieldIds.length; ++index) {

       id = fieldIds[index];

       if(e.getPIMList().getFieldDataType(id) == STRING) {

           for(int j=0; j < event.countValues(id); ++j) {

              String value = event.getString(id, j);

              System.out.println(event.getFieldLable(id) + "=" + value);

              }

           }

       }

}

将约会转化为一个序列化格式

为了导入或导出PIM项数据,使用一个输出写入流将BlackBerry设备中的任务导出为一个支持的序列化格式,例如iCal.

为了获取一个支持的格式的字符串数组,调用PIM.supportedSerialFormats(),并指定列表类型(PIM.EVENT_LIST).

将一个项写为序列化格式

调用toSerialFormat().

EventList eventList = (EventList)PIM.getInstance().openPIMList(

       PIM.EVENT_LIST, PIM.READ_ONLY );

ByteArrayOutputStream bytestream = new ByteArrayOutputStream();

  :当写到一个输出流时enc参数指定了字符编码格式.支持的字符编码格式包括"UTF8," "ISO-8859-1," "UTF-16BE."此参数不能为空.

Enumeration e = eventList.items();

while (e.hasMoreElements()) {

    Event event = (Event)e.nextElement();

    PIM.getInstance().toSerialFormat(event, byteStream, "UTF8", dataFormats[0]);

}

导入一个约会

为了返回一组PIMItem对象,调用fromSerialFormat(java.io.InputStream is, java.lang.String enc).

为了新增一个约会,调用EventList.importEvent().

:当写到一个输出流时enc参数指定了字符编码格式.支持的字符编码格式包括"UTF8," "ISO-8859-1," "UTF-16BE."此参数不能为空.

// Convert an existing appointment into a iCal and then import the iCal as a new

// appointment.

String[] dataFormats = PIM.eventSerialFormats();

// Write appointment to iCal.

ByteArrayOutputStream os = new ByteArrayOutputStream();

PIM.getInstance().toSerialFormat(event, os, "UTF8", dataFormats[0]);

// Import appointment from iCal.

ByteArrayInputStream is = new ByteArrayInputStream(outputStream.toByteArray());

PIMItem[] pi = PIM.getInstance().fromSerialFormat(is, "UTF8");

EventList eventList = (EventList)PIM.getInstance().openPIMList(

       PIM.EVENT_LIST, PIM.READ_WRITE);

Event event2 = eventList.importEvent((Event)pi[0]);

关闭一个事件列表

调用 close().

try {

    eventList.close();

}

catch (PimException e) {

    // Handle exception.

}

代码实例

下面的实例显示了一个屏幕,它允许用户在日历中创建一个新的,重复的约会.你可以将此例和ContactsDemo.java结合起来允许用户邀请参与者到这个会议中.为获取更多信息,参看31页的”ContactsDemo.java”.


:EventDemo.java

/**

* EventDemo.java

* Copyright (C) 2002-2005 Research In Motion Limited.

*/

package com.rim.samples.docs.eventdemo;

import java.io.*;

import java.util.*;

import javax.microedition.pim.*;

import net.rim.device.api.ui.*;

import net.rim.device.api.ui.component.*;

import net.rim.device.api.ui.container.*;

import net.rim.device.api.i18n.*;

import net.rim.device.api.system.*;

import net.rim.device.api.util.*;

import com.rim.samples.docs.baseapp.*;

 

public final class EventDemo extends BaseApp {

    private EventScreen _eventScreen;

    public static void main(String[] args) {

       new EventDemo().enterEventDispatcher();

       }

   

    private EventDemo() {

       _eventScreen = new EventScreen();

       pushScreen(_eventScreen);

       }

   

    protected void onExit() {

      

    }

   

    public final static class EventScreen extends MainScreen {

       private EditField _subject, _location;

       private SaveMenuItem _saveMenuItem;

       private DateField _startTime, _endTime;

       private ObjectChoiceField _repeat;

       private Event event;

      

       private class SaveMenuItem extends MenuItem {

           public SaveMenuItem() {

              super(null, 0, 100000, 5);

              }

           public String toString() {

              return "Save";

              }

           public void run() {

              onSave();

              }

       }

      

       public EventScreen() {

           _saveMenuItem = new SaveMenuItem();

           setTitle(new LabelField("Event Demo", LabelField.ELLIPSIS |

                  LabelField.USE_ALL_WIDTH) );

           _subject = new EditField("Subject: ", "");

           add(_subject);

           _location = new EditField("Location: ","");

           add(_location);

           _startTime = new DateField("Start: ", System.currentTimeMillis() +

                  3600000, DateField.DATE_TIME);

           _endTime = new DateField("End: ", System.currentTimeMillis() +

                  7200000, DateField.DATE_TIME);

           add(new SeparatorField());

           add(_startTime);

           add(_endTime);

           add(new SeparatorField());

           String[] choices = {"None", "Daily", "Weekly", "Monthly", "Yearly"};

           _repeat = new ObjectChoiceField(“Recurrence: “, choices, 0);

           add(_repeat);

           }

      

       protected boolean onSave() {

           try {

              EventList eventList = (EventList)PIM.getInstance().

              openPIMList(PIM.EVENT_LIST, PIM.WRITE_ONLY);

              event = eventList.createEvent();

              event.addString(Event.SUMMARY, PIMItem.ATTR_NONE,

                     _subject.getText());

              event.addString(Event.LOCATION, PIMItem.ATTR_NONE,

                     _location.getText());

              event.addDate(Event.END, PIMItem.ATTR_NONE, _endTime.getDate());

              event.addDate(Event.START, PIMItem.ATTR_NONE,startTime.getDate());

              if(_repeat.getSelectedIndex() != 0) {

                  event.setRepeat(setRule());

                  }

             

              // Save the appointment to the Calendar.

              event.commit();

              //reset fields on screen

              _subject.setText("");

              _location.setText("");

              _endTime.setDate(null);

              _startTime.setDate(null);

              _repeat.setSelectedIndex(0);

              return true;

              }

           catch (PIMException e) {

               System.err.println(e);

              }

           return false;

           }

      

       private RepeatRule setRule() {

           RepeatRule rule = new RepeatRule();

           int index = _repeat.getSelectedIndex();

           if (index == 0) {

              rule.setInt(RepeatRule.FREQUENCY, RepeatRule.DAILY);

              }

           if (index == 1) {

              rule.setInt(RepeatRule.FREQUENCY, RepeatRule.WEEKLY);

              }

           if (index == 2) {

              rule.setInt(RepeatRule.FREQUENCY, RepeatRule.MONTHLY);

              }

           if (index == 3) {

              rule.setInt(RepeatRule.FREQUENCY, RepeatRule.YEARLY);

              }

           return rule;

           }

      

       protected void makeMenu(Menu menu, int instance) {

           menu.add(_saveMenuItem);

           menu.addSeparator();

           super.makeMenu(menu, instance);

           }

       }

}


Updated History:

  • Last Updated:2007年1月24日
  • Last Updated:2006年4月28日
posted @ 2006-04-28 22:18  张太国  阅读(3918)  评论(9编辑  收藏  举报