作者: 邓明轩、王恒进、王志刚
左右软键的处理
很多 j 2 m e MI Dl et 应用 都使 用左右 软键 响应 用户 操作 ,在屏 幕左 下方 和右 下方 分别显 示 左软键 和右 软键 的标 签, 用户根 据左 右软 键的 标签 提示决 定点 击左 软键 还是 右软键 , 由 程序 响应左 右软 键事 件从 而响 应用户 操作 。
但是, 如上 一节 所述 , 在 B la ck Be rry 手机 上并 没有左 右软件 , 所 以需 要对 这样 的操作 进 行适配 。 首先 要明 确的是 如果开 发人 员使 用 “ Com m an d A ct io n ” 添加 操作 , 这 些操作 会被 自 动添加 到 Bla ck B er r y 的菜 单中, 用户 点击 菜单 键的 时候可 以看 到这 些“ Com m an d ” 。对 于这 种情况 则不 需要 调整 原来 的代码 。
如果开 发人 员自 行绘 制左 右软键 , 使 用键 盘事 件侦 听左右 软键 的话 , 则 需要 对程序 进行 调整, 因为 在 Bla c kB er r y 手 机上没 有左 软键 或者 是右 软键的 事件 发生 。 现 在在 公网上 看到 的 一 种简单 的调整 方法是 将全 键盘中 的“ Q ”键 映射为 左软键 ,将“ P ”键映 射为 右软件 。使 用这种 方法 开发 人员 只需 要修改 键盘 侦听 代码, 当 侦听到 “ Q ” 键 点击 事件时 执行左 软键 响 应代码 ,当侦 听到 “ P ”键 点击事 件时执 行右 软键响 应代码 。这种 方法 虽然简 单可行 ,但 是 有一定 的限 制, 比如 在一 个可编 辑的 域被 选中 时不 能工作 , 否 则用 户将 无法 输入 Q 字母 和 P 字母。 另外 ,这 种方 法也 不符 合 Bla ck Be rry 用户的 操作习 惯。
一个较 为合 适的 方法 是将 菜单键 映射 成左 软键 , 将 退出键 映射 为右 软键 。 使 用这种 方法 的做法 是获 取菜 单键 点击 事件和 退出 键单 点事件 , 在 这两个 事件 的响 应代 码中 执行左 软键 的
代码或 者是 右软 键的 代码 。有一 些开 发人 员尝 试使 用标准 的 j 2 m e 方式获 取 B la ck Be rry 上的 菜单键 事件 和退 出键 事件 ,发现 这两 个键 无法 通过 标准的 j 2 m e 方式 获取 。在 这里菜 单键 事 件和退 出键 事件 的获 取成 为关键 。
在 Bla ck Be rry 手机 上, 菜单 键事件 和退 出键 事件 需要 通过 Ke yList ene r 来 实现 。 开发人 员 可以为 一个 应用 添加一 个 K e yList ene r 作 为侦 听器 , 当这个 应用 在运 行同 时有 按键被 点击 时,
该 K e yList en er 侦听 器的 k e yDo wn 方法 会被 执行, 开 发人员 可以 实现这 个 k e yD o wn 方 法, 获 取当前 被点 击的 按键 的键 值, 通 过键 值的 比较 判断 是哪个 键被 按下 , 如 果是 菜单键 或者 是退 出键被 按下 ,则 执行 左软 键或者 是右 软键 的响 应逻 辑。
所开发 的 Ke yList ene r 需要 实现接 口 n et .rim .d ev ic e.ap i .s y s t em. K e yList ener , 如以 下代码所 示:
public class MyKeyListener implements
net.rim.device.api.system.KeyListener
该接口 有几 个键 盘相 关的 方法, 其中 最主 要的 是方 法 k e yDo wn , 对应 按键事 件, 代 码如 下:
public boolean keyDown( int arg0, int arg1) {
其中第 一个 参数 是所 按下 的按键 的键 值, 第二 个值 数是与 上一 次按 键相 隔的 时间, 不做 重复按键处理 的情况下, 一般只需要 使用第一 个参 数。使用键 值的方法 是通 过调用 Ke ypa d
的 k e y 方 法将 键值 转换成 标准值 ,然 后与 K e ypa d 类 中对应 用静 态成 员进 行比 较,如 菜单 键 的标准值 为 K e ypa d. KEY _M ENU , 退 出键 的标 准值 为 K e ypa d. KE Y_ E S CAP E 。 其中 类 K e yP a d 在包 net .rim .d ev ic e.ap i. ui 中, 虽然是 ui 包 中的 类,但 是我们 只使 用静 态方 法和 成员, 并不 使用
ui 包中 的类 进行 展现 ,不 会和 MI Dl et 的 U I 有 冲突 。
此外, 方法 k e yDo wn 有布 尔类型 的返 回值 ,返 回 t ru e 的话 表明 事件 已经 被消 费,系 统 不会再 响应 该事 件, 返回 f als e 的话表 明事 件没 有被 消费, 系统 会继 续响 尖该 事件。 如果 开 发人员 希望 点击 菜单 键响 应左软 键, 同时 系统 不再 处理该 按键 事件 , 则 判断 到菜单 事件 时需 要返 回 t rue 作为 返回 值。
具体请 参考 以下 侦听 器的 样例代 码:
package cn.searb.keymenu;
import net.rim.device.api.ui.Keypad;
public class MyKeyListener implements
net.rim.device.api.system.KeyListener {
public boolean keyChar( char arg0, int arg1, int arg2) {
// TODO Auto -generated method stub
return false ;
}
public boolean keyDown( int arg0, int arg1) {
if (Keypad. key (arg0) == Keypad. KEY_MENU ) {
// 执行菜单响 应代码 , 即 左软键响 应代码
return true ;
} else if (Keypad.key (arg0) == Keypad. KEY_ESCAPE ) {
// 执行退出键 响应代 码 , 即右软键 响应代 码
return true ;
}
return false ;
}
public boolean keyRepeat( int arg0, int arg1) {
// TODO Auto -generated method stub
return false ;
}
public boolean keyStatus( int arg0, int arg1) {
// TODO Auto -generated method stub
return false ;
}
public boolean keyUp( int arg0, int arg1) {
// TODO Auto -generated method stub
return false ;
}
}
开发了 侦听 器类 以后 在系 统启动 时需 要将 侦听 器添 加到应 用中 , 添加 侦听 器需 要调用 应 用的 a dd Ke yList ene r 方 法。 可以 在 MI Dl et 的 构造 函数 中加入 以下 语句 添加 侦听 器。
App li ca t io n. g et App li ca t io n() .a dd K e yList ene r( n ew M yK e yList ener ( ) ) ;
其中方 法 Ap pl ic a t io n. g et App li ca t io n() 用于获 取当 前应 用, a dd K e yList en er 则用于 添加键 盘 侦听器 。
添加以 上代码 后 MI Dl et 就 可以通 过菜 单键 和退 出键 响应左 右软 键了 。有 一点 需要注 意 的是 Bla ck B er r y 用 户习惯 使用退 出键 完成 “退 出” , “取消 ” , “ 关闭” 等否定 性操作 。 所 以在 移植 MI Dl et 的时 候尽 量在 右软键 位置 放置 “退 出” , “取消 ”或 者是 “关 闭” 等操作 ,而 不
要放置 “进 入” , “打 开” , “开始 ”等 肯定 性的 操作 。
滚轮操作的映射
如第一 小节 描述 的, 在较 早的 Bla ck B er r y 机 型上 , 用户通 过滚 轮进 行导 航, 在这些 机型 上没有 单独 的菜 单键 ,用 户通过 点击 滚轮 激活 菜单 。
在这种 机型 上, 要响 应滚 轮点击 事件 需要 实现 额外 的侦听 器, 因为 滚轮 不属 于键盘 的一 部分, 在 Ke yList ene r 中无 法侦听 到。 对于 其它 按键 ,如退 出键 ,各 个字 母键 ,虽然 键盘 分 布和新 型的 机型 有所 不同 ,但是 都可 以使 用上 一节 描述 的 K e yList en er 进行侦 听。
响应滚 轮事 件的 侦听器 为 net .rim .d ev ic e.ap i. s y s t em. T r ac kwhe elLi s t ene r , 开发人 员需要 实
现这个 接口 。 该接口 有滚 轮滚动 , 滚轮 点击等 方法 , 要 响应 滚轮 点击事 件需 要实现 的方法 为
t r ac kwhe elCli ck 。
一个滚 轮侦 听器 的样 例代 码如下 :
package cn.searb.keymenu;
import net.rim.device.api.system .TrackwheelListener ;
public class MyTrackWheelListener implements TrackwheelListener {
public boolean trackwheelClick( int status, int time) {
// 执行滚轮点 击响应 代码
return true ;
}
public boolean trackwheelRoll( int amount, int status, int time) {
// TODO Auto -generated method stub
return false ;
}
public boolean trackwheelUnclick( int status, int time) {
// TODO Auto -generated method stub
return false ;
}
}
发了滚轮 侦听器后 可以通 过应用程 序的 a dd T r ac k wheel List ene r 方法为应 用添 加滚轮
侦听器 ,样 例代 码如 下:
Application.getApplication ().addTrackwheelListener ( new
MyTrackWheelListener());
其中 App li ca t io n. g et App li ca t io n() 用于 获取 当前 应用实 例, a dd T r ac kwh ee lLi s t ene r 用于 添 加侦听 器。
其它按键操作
在 bl ac kB er r y 手 机上 还有 一些其 它的 按键 , 如静音 键, 音量 键等 , 这些 按键 事件可 以通 过标准 的 j 2 m e 方法 ,比 如 Can v a s 的 k e yP re ss e d 方 法获取 。
开发人 员可 以通 过 k e yP r e ss e d 方 法对 这些 按键 进行处 理:
protected void keyPressed( int keyCode)
参数 k e yCod e 为当 时用户 按下的 按键 , 开发 人员可 以通 过 k e yCod e= = 判 断用户 按下的 是 哪个按 键。 在 Bla c kB er r y 包 中有 类 n et .rim .d e vice.a pi .s y s t em. Cha r ac t er s , 包 含了很 多常量 , 其
中 包 括 了 这 些 键 的 键 值 , 如 Cha r ac t er s . C ONTR O L_V OL U ME_U P 为 增 加 音 量 键 的 键 值 , Char ac t er s . C ONTR OL_ V OL U ME_DO W N 为减少音 量键的键 值,开发人员可 以使用这些 常量进 行判断 , 避 免在 代码 中直 接使用 键值 进行 比较 。 不 过测试 发现 的问 题是 这些 常量和 实际 的健 值不符 , 导 致有 些判 断失 效。 所 以, 使用 健值 直接 进行比 较更 加稳 妥一 些, 比如增 大音 量键 的键值 为 -15 0 ,减少 音量键的键 值为 - 1 5 1 ,左快捷键的键 值为 - 2 1 ,右快 捷键的键值 为 -1 9 。
当然, 一个 稳妥 和简 单的 方法是 在开 发过 程中通 过 S y s t em.o ut .p rin t ln () 将键值 打印到 输出 界 面上, 从而 测试 不同 键的 键值。 下面 是按 键检 测的 代码片 段:
protected void keyPressed( int keyCode)
{
if (keyCode== -150)
{
System. out .println( "volume up " );
}
else if (keyCode== -151)
{
System. out .println( "volume down " );
}
}
使用以 上方 法也 可以 对一 般的字 母键 进行 处理 。 不 过, 对于 字母 键的处理 , 建议是 尽量 使用高 级界 面自 带的 功能 , 从而 避免 直接 对键 盘事 件进行 响应 。 比 如多 利用 输入框 编辑 框等 输入文 字, 可以 更好 地利用 平台的 功能 , 如 自带 的输入 法等, 不需 要开 发人 员响应 键盘事 件。 对于特 定的 低级 界面 必须 响应键 盘事 件时 则需 要考 虑不同 的键 盘类型 , 主 要是 全键盘 类型 和
“ S ure T yp e ” 键盘 类型的 差别, 在不 同机 型上 可能 需要对 不同 的键 进行 响应 。
提醒用户
手机应 用的 一个 特点 是充 分和手 机的 功能 集成 , 其中 一个重 要的 功能 就是 通过 手机的 功 能对用 户进 行提 醒。 如一 般常用 的响 铃, 振动 , 闪 灯等提 醒。 在 Bla c kB er r y 平台上 还可 以通 过修改 应用 图标 ,增 加主 屏幕提 醒标 记等 方式 提醒 用户。
通过响铃提醒 用户
响铃是 常用 的用 户提 醒方 式,一 般 j2m e 开 发人 员使 用 P la y er 类 加载 一段 声音 ,当有 事 件发生 需要 提醒 用户 通过 播放声 音的 方式 提醒 用户 。 因为 Bla ck B er r y 平 台支 持标准 的 j 2 m e , 这种使 用 P la ye r 提醒 用户 的方法 可以 在 Bla c kB er r y 平台上 使用 , 不 需要 对代 码进行 修改 。 此 时播放 声音 的大小 , 时 间长 短都由 程序 决定 。 给用 户带 来的影 响是 即使 用户 将场 景设置 为 “静 音” , 即既 不振动 也不 响铃 , 当该 程序 有提 醒时 仍会 “响铃 ” 。 要 改善 这一 点可 以在应 用内 部 为用户 提供 一个 设置 ,设 置这个 应用 本身 是否 启用 声音, 是否 启用 振动 等。
通过振动提醒 用户
在标准 的 j 2 m e 中 ,通 过 Dis pl a y . vi br a t e( ) 的调 用可以 让设备 振动 ,该 方法 在 Bla ck Be rry 设备上 同样 支持 , 有 关振 动的代 码可 以不 加修 改直 接在 Bla ck B er r y 手 机上使 用。 此 时设 备是 否振动 , 振 动时 间多 长完 全由程 序控 制, 不受 系统 设置影 响。 所以 , 这 种方 法与上 一小 节中 提到的 响铃 提示 的方 法有 同样的 问题 ,也 同样 可以 通过相 同的 方法 改善 这个 问题。
通过状态灯提 醒用 户
在 Bla ck B er ry 平台上开发人员还 可以通过闪烁状态灯来提 醒来户,开发人员可以通 过
|
Bla ck Be rr y 手 机上 的状 态灯 位置如 下图 :
用于控 制状 态灯 的类 为 n e t .rim .d ev ic e.ap i. s y s t em.LED ,它包 括几 个静 态方 法, 主要的 方
法为 s etS t a t e , 用于 改变 状态灯 的状 态。 s etS t a t e 方法接 收一 个参 数, 即希 望改变 成的 目标 状态, 该参 数为 in t 类型, 但是只 能接 受以 下常 量中 间的一 个: LED .S T A TE _ON , L ED .S T A TE_ OF F , LED .S T A TE_ BLI NK I NG , L ED .S T A TE_ A U DI O_S Y NC 。常 用 的 为 LED .S T A TE _ON , L ED .S T A TE_ OF F , LED .S T A TE_ BLI NK I NG ,它们 的效果 为:
l LED .S T A TE_ ON 将状 态灯打 开
l LED .S T A TE_ OF F 将状 态灯关闭
l LED .S T A TE_ BLI NK I NG 使状 态灯闪 烁
在调 用 s etS t a t e 之 前, 最好 先通 过 LED .isS up po rte d 方 法判断 当前 设备 是否 支持 状态灯 变 化,判 断是 否支 持状 态灯 变化的 语句 为 if ( LED .isS up p o rt e d(L ED .LED _T YP E_S T A TU S ) )
另外要 注意, s etS t a t e 方法 和 isS up po rt e d 方 法只 能接 受固定 的几 个参 数, 如果 开发人 员 没有控 制好 代码 , 传入 了一 些不能 接受 的参数 , 该 方法 会抛 出 Il leg al Ar g um en t Ex ce pt io n 异常 。
下面为 打开 状态 灯的 代码 片段:
if (LED.isSupported (LED. LED_TYPE_STATUS )) { LED.setState (LED. STATE_ON );
}
通过主屏幕标 记提醒用 户
在 Bla ck Be rr y 手机 上可以 通过主 屏幕 的标 记提 醒用 户。 如 下图 所示 , 在 电池 图标右 边的 是主屏 幕标 记, 第一 个是 系统的 邮件 提示 , 表 示有 1 封 未读 邮件 , 第 二个 也是 系统提 示, 表 示有两 条新 短信 。 开 人员 可以根 据应 用需 要添 加应 用自己 的提 示, 如图 中第 三个标 记是 由程 序添加 的标记 , 开人 人员 可以指 定标 记的 图标 图片 , 可 以指 定什 么时候 显示 该标记 , 还可 以 指定标 记旁 边的 数字 。
主屏幕 标记通 过 App li ca t io nI nd ic a t o rR eg is t ry 和 App li ca t io nI nd ic at o r 进行操作 。 首先要 通
过 App li ca t io nI nd ic a t o rR e g ist ry 注册 本应 用的 标记 , 然 后通 过 App li ca t io nI nd ic a t o r 控 制标 记是 否显示 ,显 示什 么图 标, 显示什 么数 字。
具体的 标记 注册 过程 如下 :
1 . 通 过 App li ca t io nI nd ic a to rR eg is t ry 的 静 态 方 法 g et In s t an ce ( ) 获 得
App li ca t io nI nd ic at o rR eg is t ry 的 实例。
2 . 调用 A pp li ca t io nI nd ic a to rR eg is t ry 实例的 r eg ist e r 方法 注册标 记。
App li ca t io nI nd ic at o rR eg is t ry 实 例 的 r eg ist er 方 法 接 受 三 个 参 数 , 第 一 个 参 数 为 App li ca t io nI c o n , 用于指定标记所 使用的图标, 这个图标在 以后可以通过 程序更换; 第二个 参数为 布尔 类型 , 指 定该 标记是 否只 有图 标; 第三 个参数 也是 布尔 类型 , 用 于指定 该标记 是 否可见 ,标 记是 否可 见在 以后可 以通 过程 序进 行修 改。
下面是 注册 标记 的代 码片 段:
EncodedImage readimage = EncodedImage
.getEncodedImageResource ( "cn/searb/demo/icon/indicator.png" );
ApplicationIndicato rRegistry indicatorRegistry = ApplicationIndicatorRegistry. getInstance ();
ApplicationIcon icon = new ApplicationIcon( readimage );
indicatorRegistry.register(icon, false , false );
在注册 完标 记后 , 应 用程 序在需 要的 时候 就可 以对 标记进 行操作 , 如修 改图 标, 或者 是 修改显 示的 数字 等。 标记 的操作 过程 如下 :
1 . 通 过 App li ca t io nI nd ic a to rR eg is t ry 的 静 态 方 法 g et In s t an ce ( ) 获 得
App li ca t io nI nd ic at o rR eg is t ry 的 实例。
2 . 通过 App li ca t io nI nd ic a t o rR eg is t ry 实例的 g et App li ca t io nI nd ic a t o r 方法获得 当前 应用 的
App li ca t io nI nd ic at o r 实例。
3 . 通过 A pp li ca t io nI nd ic a to r 实例 的 s et V al u e 方 法设置 要显示 的数 字
4 . 通过 A pp li ca t io nI nd ic a to r 实例 的 s et Ic o n 方 法设 置要 显示的 图标
5 . 通过 A pp li ca t io nI ndic a to r 实例 的 s et V is i bl e 方 法设置 该标记 是否 可见
其中 第 3 , 4 , 5 步 没有 依赖关 系,开 发人 员可 以独 立调 用其中 的一 个或 者是 多个 方法。 下面是 标记 操作 的代 码片 段:
ApplicationIndicatorRegistry indicatorRegistry = ApplicationIndicatorRegistry. getInstance ();
ApplicationIndicator indicator =
indicatorRegistry.getApplicationIndicator() ;
ApplicationIcon icon = new ApplicationIcon( readimage );
indicator.setValue(number); indicator.setIcon(icon); indicator.setVisible( true );
BlackBerry SDK下载
相关链接:
如何将MIDlet 应用移植到BlackBerry (一)
如何将MIDlet 应用移植到BlackBerry (二)
如何将MIDlet 应用移植到BlackBerry (三)
如何将MIDlet 应用移植到BlackBerry (四)