出处:http://www.iteye.com/topic/397945
本来不想写J2ME开发的时候要根据不同手机平台适配各种键值这个问题,觉得没撒意思,也没什么技术含量,但是今天看到了一个让我很无语的东西,所以我决定要写出来。稍候再说这个让我不爽的东西,先不要影响我们分享技术的心情。NOW BEGIN …
故事背景:最近要开发一个世界天气在线搜索的软件,先AD一下,这个软件是我们Allove Team开发的有一个生活小软件,开始的定位就是天气搜索,后来我想扩展为“生活小助手”就是不但有世界天气搜索,还有出行参考,还有生活常识之类的东西。正在开发中。 由于,开发过程中需要使用Canvas才能做出很漂亮的界面,所以引发了一个老问题 — 手机键值!
很多人都说,要适配所有手机的键值是不可能的。因为,已是J2ME中没有对手机的左右软键的键值定义,而是很多手机也没定义,再者就是手机多多了,像华为,中兴,联想,诺基亚,摩托罗拉,西门子,索爱,黑莓,多普达等等这些大厂家都没个定数,更别所多如牛毛的山寨机了,所以这种说法也是无可厚非的。 即使你把 左键 -7 , 右键 -6 , OK键 -5 这些都设置好能支持大部分的手机,还是难免有个害群之马啊。 所以, 没有标准导致了这个严重的问题 :要一次性搞定所有手机的键值问题难道非常之大。
但是,天知道我怎么一生下来就是个不信邪的主儿,Google百度了几下发现没有统一键值之后开始思考自己的路了。最后,想了一个办法,目的是我要一次性搞定所有手机的键值。怎么做?让用户手机告诉你呗。思路如下:用户第一次使用时设置键位。
- 用Canvas实现一个键位设置界面,捕获keyPressed事件;
- 在设置界面中以提示性语言引导用户按键;
- 将得到的键值保存到RMS中备用;
- 完成键位设置;
- 在以后要使用按键的Canvas中调用RMS中的数据,完成操作。
下面是完成这个设置的简要代码结构:
-
//首先你需要一个数组:
-
private String[] drawArray = {"左功能键","右功能键","OK键","方向键【上】","方向键【下】","方向键【左】","方向键【右】"} ;
-
//然后你需要两个标志位
-
private boolean config_finished = false ;
-
private boolean firsttime = true ;
-
//再者你需要一点实现逻辑
-
if(drawIndex > 6){
-
config_finished = true ;
-
}
-
if(!config_finished){
-
if(firsttime){
-
g.drawString("【键位设置】",WIDTH / 2 - titleWidht / 2 , startY, Graphics.TOP|Graphics.LEFT);
-
g.drawString(initStr, 5, startY + 1*lineHeight, Graphics.TOP|Graphics.LEFT);
-
g.drawString(prefix + drawArray[drawIndex] , 5, startY + 2*lineHeight, Graphics.TOP|Graphics.LEFT);
-
} else {
-
g.drawString("【键位设置】",WIDTH / 2 - titleWidht / 2 , startY, Graphics.TOP|Graphics.LEFT);
-
g.drawString(initStr, 5, startY + 1*lineHeight, Graphics.TOP|Graphics.LEFT);
-
g.drawString(finished + drawArray[drawIndex - 1] + status, 5, startY + 1*lineHeight, Graphics.TOP|Graphics.LEFT);
-
g.drawString(prefix + drawArray[drawIndex] , 5, startY + 2*lineHeight, Graphics.TOP|Graphics.LEFT);
-
}
-
firsttime = false ;
-
startY = 0 ;
-
initStr = "" ;
-
} else {
-
System.out.println("设置完毕 .... config finished ...");
-
g.setColor(0xff0000);
-
g.drawString("设置成功,请按OK键返回!", 5, startY + 4*lineHeight, Graphics.TOP|Graphics.LEFT);
-
}
-
//接下来我们需要一点控制信心和按键事件的响应
-
protected void keyPressed(int key){
-
if(this.storeKeyValue(WHAT_KEY, key)){
-
drawIndex ++ ;
-
WHAT_KEY ++ ;
-
status = "(成功)" ;
-
} else {
-
drawIndex -- ;
-
WHAT_KEY -- ;
-
prefix = "[重设]" ;
-
status = "(失败)" ;
-
}
-
if(config_finished && key == config.getOK()){
-
System.out.println("read back of OK .. is " + config.getOK());
-
wm.setThisAsCurrent(wm.getMainform());
-
}
-
repaint();
-
}
-
//最后我们需要一个存储的动作
-
private boolean storeKeyValue(int whatkey , int key){}
请注意,上面这个代码片段只是完成按钮设置的框架,而不是完整代码,如果你需要完整代码可以留下信息并且发邮件告诉我。我会分享给你的。
下面说一下上面这段代码的大致思路:
创建一个你希望设置的键位的数组:private String[] drawArray , 里面存放着一些提示信息,这些信息用来引导用户去按键,然后使用paint()在界面上绘制这些信息,但又按键事件的时候系统会调用protected void keyPressed(int key)方法,而我们在这个方法中处理一些事件,不作一些控制。例如改变绘制字符串的指针,例如修改键位设置的执行状态 “成功” 或者 “失败” 。 另外还需要控制的就是设置的完成状态 , 最终目的是把键值写入到RMS中备用 。
下面是键值调用的持久类的完整代码:
-
package org.allove.weather.lib;
-
public class KeyMap {
-
///////////////
-
private static KeyValueRms config = KeyValueRms.getInstance();
-
public static final int key_LeftSoft = config.getLeftSoft() ;
-
public static final int key_RightSoft = config.getRightSoft() ;
-
public static final int key_OK = config.getOK() ;
-
public static final int key_UP = config.getUP() ;
-
public static final int key_DOWN = config.getDown() ;
-
public static final int key_LEFT = config.getLeft() ;
-
public static final int key_RIGHT = config.getRight() ;
-
///////////////
-
}
至于这个KeyValueRms 怎么去实现就不是本文的主要内容了,这是RecordStore的内容,这里就不赘述了 。
总的来说,我觉得这是一个很简单的问题,也很容易想到,应该不到5分钟吧,想到这个解决方案。由于我觉得这个东西很简单,价值也不那么明显,所以导致了我看到一个东西之后很郁闷。今天,无意中搜索键值玩,发现了万方数据里面的一片论文:《一种J2ME软件适配不同手机键值的方法》让我倍感无语。这个方法被人申请专利了,我很无语,这东西也能申请壮丽,我操,早知道我早两年也去申请了。 还说得那么玄乎,很纠结啊。
最后,要来说一下这个可行性和用户体验的问题。
- 其实这东西不是很好,完全依赖于keyPressed方法,如果不支持这个方法呢?
- 在某些手机中按左右软键的时候是没有反应的,比如巨头诺基亚
- 再说用户体验,这个问题有点严重,一旦设置错误可能就需要从新安装软件,这是相当不友好的,因为RMS的数据要卸载才能清除,其实这个到也无所谓啦,你可以在软件里面做一个重新设置的功能,这到不致命
- 然后就是,不是所有用户都能看懂你的引导语言,难免会设置错误,你不能保证每个用户都是聪明的
- 由于手机厂商数目巨大,这个方法的代价是巨大的,慎用
抛弃这种方法之后如何去更快捷的适配不同手机的键值问题呢?也许按手机型号发布软件是一个最简单最直接的方案,局限性就是你必须知道每个平台的键值,希望MIDP3.0不要再有这个问题了。现在,我们就假设,我们已经能够获取到不同手机的键值,那么我们应该如何去写代码呢?在每一个 keyPressed里面设置switch case -6 / -7 / -5 的方法显然是不对的。 我们希望这样操作:
-
package org.allove.weather.lib;
-
-
public class KeyMap {
-
///////////////
-
public static final int key_LeftSoft = -7 ;
-
public static final int key_RightSoft = -6 ;
-
public static final int key_OK = -5 ;
-
public static final int key_UP = -4 ;
-
public static final int key_DOWN = -3 ;
-
public static final int key_LEFT = -2 ;
-
public static final int key_RIGHT = -1 ;
-
/////////////// 请注意 上面的键值只是为了测试 不一定正确
-
}
-
-
/////////////////////////////////////////
-
// ..... Many Other Things ...
-
import package org.allove.weather.lib.KeyMap ;
-
-
public class ACanvas extends Canvas ;
-
// ..... Many Other Things ...
-
protected void keyPressed(int key){
-
if(key == KeyMap.key_LeftSoft){
-
do(.....) ;
-
} else if (key == KeyMap.key_OK){
-
do(.....) ;
-
} else if (key == KeyMap.key_RightSoft){
-
do(......) ;
-
}
-
repaint();
-
}
-
// ..... Many Other Things ...
相信这样的代码结构是可读的,方便维护的,容易移植的 。 当你需要移植平台的时候只需要在KeyMap中修改映射即可。这也许就是OO思想的体现吧 。 好了今天就到这里吧 , 上面的代码基本都是框架,如果你希望得到源码的话可以留言并且发邮件到sunjianyes#gmail.com获取,如果你能记得我们Allove Team那就最好不过了。再如果你能够支持一下我们的发展就更好了,最好的办法就是尝试使用我们的软件: m.Allove.org
如果你在下次看到下面这张图片的时候能想起我们那就是我们最大的成功:
分享到:
相关推荐
在J2ME开发中,你需要了解以下核心概念: 1. **KVM(Java Virtual Machine for Embedded Devices)**:J2ME应用程序运行在KVM上,这是一个专为小型设备优化的虚拟机,它不支持完整的Java Class库,而是采用CLDC...
2. **MIDP API**:这是J2ME开发手机应用的核心,包括用户界面(User Interface)组件,如Canvas和Form,以及网络通信和文件系统访问的类。例如,Canvas允许自定义图形绘制,而Form则用于创建包含文本和按钮的标准...
**J2ME开发大全(中文版)** J2ME,全称Java 2 Micro Edition,是Java平台的一个重要分支,专为嵌入式设备、移动设备和消费电器提供应用程序开发和部署环境。这本书《J2ME开发大全》是针对中文读者的一本详细教程,...
在J2ME开发过程中,有以下几个关键知识点: - **MIDP API**:提供基础的用户界面元素和网络访问功能。 - **CLDC API**:包含基本的Java类库,如集合框架和I/O流。 - **线程管理**:由于设备资源有限,开发者必须有效...
**J2ME开发的名片册** 在移动设备的早期阶段,Java 2 Micro Edition (J2ME) 是一种广泛用于开发手机应用的平台。这个"名片册"项目就是基于J2ME开发的一个实用应用程序,旨在帮助用户管理和存储个人名片信息。通过这...
此外,还需要安装JDK(Java Development Kit)以及特定的SDK(Software Development Kit)以支持J2ME开发。 三、基础语法与编程模型 J2ME遵循Java的面向对象编程原则,但为了适应资源有限的设备,进行了优化。MIDP...
【标题】基于J2ME的输入法开发代码详解 在移动设备早期,Java ME(J2ME)是广泛应用于智能手机和平板电脑上的编程平台,它为开发者提供了在各种设备上构建应用程序的能力,包括输入法软件。J2ME的灵活性使得开发者...
常用的J2ME开发工具有NetBeans、Eclipse和JCreator等,它们都支持J2ME项目的创建和调试。开发者可以利用这些工具的集成开发环境(IDE)进行代码编写、模拟器测试和设备部署。 3. **用户界面设计** J2ME使用WTK...
J2ME,全称Java 2 Micro ...这份题库将帮助你全面复习和巩固以上各方面的知识,通过模拟测试提升你的J2ME开发技能,为取得J2ME认证做好充分准备。记住,理论学习和实践操作相结合,才能更好地理解和掌握J2ME的精髓。
9. **调试与测试**:J2ME开发过程中,WTK模拟器是常用的调试工具,可以模拟各种设备环境进行测试。 10. **优化技巧**:为了提高J2ME应用的性能,需要关注代码优化,如减少对象创建、避免全局变量、使用位运算代替...
同时,可能提到了一些常用的J2ME开发工具,如NetBeans、Eclipse或者J2ME Wireless Toolkit (J2ME WTK),这些工具在调试和测试J2ME应用时十分关键。 【压缩包子文件的文件名称列表】:“game”可能意味着讨论的BUG与...
4. **J2ME开发环境**:常用的J2ME开发工具有NetBeans、Eclipse或JBuilder等,它们提供了编写、编译、模拟和打包J2ME应用程序的功能。 5. **KVM(K Virtual Machine)**:J2ME设备上运行的是KVM,这是一种精简版的...
总之,《J2ME移动软件程序设计》-卢军-源代码是学习J2ME开发的宝贵资源,通过它,你可以掌握移动设备上的Java应用程序设计,包括基本的MIDlet结构、用户界面创建、网络通信以及数据管理等多个方面。实践这些源代码,...
Java ME提供了键盘事件监听机制,开发者需要适配不同的设备键值,确保游戏在各种手机上都能正常运行。 最后,为了增加游戏的趣味性和挑战性,可能还需要引入分数系统、等级升级、道具系统等元素。这些都需要数据库...
J2ME处理按键事件通常通过`keyPressed()`方法,而Android则使用`onKeyDown()`处理物理键盘事件,对于触摸屏,Android提供了`onTouchEvent()`方法来捕获触摸事件,这比J2ME的`pointerPressed()`更复杂,需要适配多种...
J2ME使用RecordStore系统保存数据,这类似于简单的键值对存储。而在Android中,通常使用SQLite数据库来实现更复杂的数据存储和检索功能。因此,数据保存部分的代码需要进行大幅度修改,以适应Android的数据库操作。...