您的位置:首页 > 其它

手机"用户界面和多媒体"版面有价值问题整理[j2medev.com][0406更新]

2008-04-12 13:49 295 查看
预告:j2medev.com将开始整理各个版面的有价值问题,并以PDF格式集结,敬请期待。
[align=center]
出品商 产品名称 产品版本
J2medev.com 版面有价值的问题合集 0.1
[/align]j2medev.com之“用户界面和多媒体”版面有价值问题的整理[align=center][/align]

历史

Version
Date Creator Description
1.0.0.1 2006-4-4 郑昀 草稿
1.0.0.2 2006-4-6 郑昀 第二稿
 

1 全屏问题

 

全屏/FullCanvas/setFullScreenMode

关键词
详细描述  
SonyEricsson T630 该款手机的参数:索尼爱立信 T630 SonyEricssonT630R401 ProfileMIDP-1.0 ConfigurationCLDC-1.0 “据我所知,不可以实现全屏显示。” --- lulei204  
SonyEricsson K700c k700c  直接用nokiaFullCanvas,可以全屏176 x 220 k700cmidp2.0的那个this.setFullScreenMode(true);也是可以全屏的,176x220。 k700c直接用nokia的FullCanvas全屏好像是176*208,直接拿nokia60上的程序可以直接放进去。键值和60的也是相同的,只是多了一个返回键,我忘了值是多少了。用2.0的GameCanvas大小是176*220。 --- lulei204  
不使用FullCanvas实现全屏的方法 为了用标准的SUN WTK2.1开发能兼容各种机型的MIDP2.0游戏,会遇到一个奇怪的全屏问题,在K700上好好的,到了Nokia上居然死活显示一半,费了一番功夫后,终于不用FullCanvas实现了兼容K700和Nokia的全屏显示,方法如下: 在索爱的K700上,实现全屏很简单,如下写法就可以了: public Canvas1() {         super(false);         this.setFullScreenMode(true);         this.width=getWidth();         this.height=getHeight(); } 得到的屏幕大小是176*220。 Nokia上就比较奇怪了,这种方式取得的width和height居然是176*144。 需要加以下代码修正一下: if(width>=176) {     if(height<208)     {          height=208;     } } 绘图部分都以width和height为基准。 另外canvas1不能继承系统的GameCanvas,因为系统GameCanvas里的缓冲图还是176*144的,画出来就只能是半屏,我用j2me polish里的GameCanvas修改一下后,放到src里代替系统GameCanvas就OK了。 修正过的GameCanvas代码如下: http://www.j2medev.com/bbs/dispbbs.asp? BoardID=19&ID=3218&replyID=&skin=1 ---alexhy
FullCanvas和setFullScreenMode()的区别 setFullScreenMode用于MIDP2.0设备上。com.nokia.mid.ui.FullCanvas是Nokia UI API 1.1的包,用于MIDP2.0设备上,SonyEricsson手机也支持。   “FullCanvas是肯定可以实现全屏幕显示的,但是MIDP2.0里面的setFullScreenMode()只是实现为尽量使用最大的屏幕空间,但是不一定是全屏幕,要看各个手机的实现。” ---mingjava “FullCanvas不能加Command;setFullScreenMode(true)可以加上Command()。只是我加上一个按键时,却不管把它设在哪里,只能是右键响应。” ---风过留痕
FullCanvas和Canvas,GameCanvas分别有什么不同 “FullCanvas是Canvas的子类,实现全屏的功能,而且把按键针对nokia的手机进行了映射。其他没有什么区别。” ---migjava “GameCanvas也是Canvas的子类,自MIDP2.0起提供,专门针对游戏增加了一些功能。在按键和显示各方面的运用都和Canvas有较大的不同。” ---efei
Motorola的MIDP1.0手机 “motorola如果不支持MIDP2.0,应该就没办法实现全屏了。全屏下的菜单很好实现,不用搞得象Command那么复杂,那个Command用起来就是很不爽,还是自己写最好。” ---海标
Nokia S60全屏后的Canvas高度 “canvas. setFullScreenMode(true)后,一定让他被绘制一次,系统会调用sizechange(int w,int h),w、h肯定是全屏的。仅调用setFullScreenMode (true)则好象各系统有不同处理。” ---atchome   “You can call getWidth() getHeight() after Canvas.showNotify(). Then it will return the correct value. eg. 176*208” --- okboy001   “系统第一次回调paint()方法时可以获得正确的屏幕尺寸 原因如atchome所说” --- imshark_jinni   “在Nokia S60真机上这是一个BUG似乎: setFullScreenMode(true);调用之后, getHeight()返回的并不是全屏后的高度,比如他本应该返回208, 但是他却返回144,所以,在真机测试时也要小心nokia s60的这个bug, 不要因为屏幕高度获取不正确,导致fillRect与你预想不一致。   以上这个BUG,起码我的Nokia 7610就是这样。 所以我必须在setFullScreenMode(true);全屏之后 通过下面代码来获取真实的canvas高度:   Code: public abstract class PopupCanvas extends Canvas { 。。。。 /*           * 针对Nokia全屏情况下getHeight的BUG,此函数出自于           * http://discussion.forum.nokia.com/f...?threadid=48826           */          public int getHeight(){                 try{                        if("Nokia".compareTo( System.getProperty("microedition.platform").substring(0,5))  == 0)                               return 208;                        else                               return super.getHeight();                 }                 catch(Exception e){                        return super.getHeight();                 }               } }” ---zhengyun  
 

2 Image和ByteArray转换问题

 

Image/byte[]/Convert

关键词
详细描述
Image对象转换为byte[] “image-(getGraphics)->graphic-(setClip, 对每个象素getColor)->原始byte[]” --- rypan   “要是在 J2ME 的话, 看来只有 Image.getRGB() 能帮上: 还有做int[] -> byte[] 的动作, 可以考虑用 ByteArrayOutputStream + DataOutputStream, 把 int[] 用 dos.writeInt 的方法写在 Byte array 上. 当然可以用最老土的方法, 不知道那种快: byteArray[i] = intArray[j] & 0xFF; byteArray[i+1] = (intArray[j] >> 8)& 0xFF; byteArray[i+2] = (intArray[j] >> 16)& 0xFF; byteArray[i+3] = (intArray[j] >> 24)& 0xFF;” --- wapeter   “ public static byte[] getByteArray(Image image) {        int raw[] = new int[image.getWidth() * image.getHeight()];        image.getRGB(raw, 0, image.getWidth(), 0, 0,               image.getWidth(), image.getHeight());        byte rawByte[] = new byte[image.getWidth() * image.getHeight() * 4];        int n = 0;        for(int i = 0; i < raw.length; i++)        {               int ARGB = raw[i];               int a = (ARGB & 0xff000000) >> 24;               int r = (ARGB & 0xff0000) >> 16;               int g = (ARGB & 0xff00) >> 8;               int b = ARGB & 0xff;               rawByte
= (byte)b;               rawByte[n + 1] = (byte)g;               rawByte[n + 2] = (byte)r;               rawByte[n + 3] = (byte)a;               n += 4;        }               raw = null;        return rawByte; }   上面代码进一步的解释:   第一步: 如何获得image对象的int数组呢?这个就简单了可以通过获得RGB数组就可以。Image对象中有直接的getRGB方法,不过这里的参数的位置和J2SE中不太一样: javax.microedition.lcdui.Image.getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height)   第一个是目标数组,第二个是偏移量,第三个是扫描的长度,后两个是起始的位置,最后两个是要取得的宽度和高度。其中扫描的长度一般大于等于获取的宽度。   第二步,把得到的Int数组再生成byte数组。 “   byteArray[i+0] = (rgbArray[i/4] >> 24);    byteArray[i+1] = (rgbArray[i/4] >> 16) & 0x000000FF;    byteArray[i+2] = (rgbArray[i/4] >>  8) & 0x000000FF;    byteArray[i+3] = rgbArray[i/4] & 0x000000FF; ” 第一句,alpha channel; 第二句,red channel; 第三句,green channel; 第四句,blue channel。   为什么有这些东西呢? 我们从一篇文章《介绍MIDP2.0新特性Alpha混合》摘要几句:
在MIDP2.0中新增了Alpha混合特性...MIDP2.0 java doc中关于Alpha Processing的说明:在可修改图片中的每个像素都必须是完全模糊的,在不可修改图片中的每个像素可以是完全透明的,完全模糊的或者介于两者之间的,也就是半透明...
  所以有了上面的Alpha channel。  
数组中的数值形式为0xAARRGGBB,其中AA代表透明度,后面的代表颜色值。
也就是说,AA就是Alpha,RR就是Red,GG就是Green,BB就是Blue。   还有一句话概括的:
444,表示图形格式,好像Nokia S40的机器都是采用444格式表示RGB颜色的。就是红,绿,蓝各用4位表示,至于可以表示透明色ARGB的4444格式,应该是机器硬件实现的。
---zhengyun  
   
 

3 getRGB问题

 

getRGB/

关键词
详细描述
getRGB的参数意义 “javax.microedition.lcdui.Image.getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height) 第一个是目标数组,第二个是偏移量,第三个是扫描的长度,后两个是起始的位置,最后两个是要取得的宽度和高度。其中扫描的长度一般大于等于获取的宽度。” -- whycloud   “offset 是指要取的RGB值储存在rgbData数组的起始位置,一般为0。如果offset不为0,使用rgbData数组就不方便了,因为要从offset开始的位置使用。而scanlength不对(如:|scanlength|)的话,就可能造成所取的rgbData值会有重复。   在API文档里面有一个公式,可以让我们理解地更深刻: rgbData[offset + (a - x) + (b - y) * scanlength] = P(a, b)   其中P(a, b)表示在IMAGE数组中位置为(a,b)的像素点。 具体的内容可以参考API文档。 其实MIDP2.0的getRGB()跟NOKIA的getPixels()是类似的。 ” --- xpanda
   
 

4 字符串换行问题

 

drawString/Line Wrap/StringLayout

关键词
详细描述
用g.drawString(); 要显示的文字很多,那应该如何实现在Canvas上换行呢 “StringLayout类可以自动排版,还能上下翻行。 代码在 http://www.j2medev.com/bbs/dispbbs.asp?BoardID=11 &replyID=20309&id=3997&skin=0可以找到。 ” --- sakaipb “自动处理字符串折行显示的封装类Line Wrap 代码以及如何使用的例子都可以从 http://fotomica.astrientlabs.com/downloads/textwrap.jsp 找到。       ” --- zhengyun
   
 

5 字体问题

 

Font/setFont/摩托罗拉

关键词
详细描述
moto系列的手机是不是不支持用setFont来修改字体的大小呢? “motoV360这机器就这德性。 ” --- Lcheer   “好像moto的某些手机里只有一种字体,高度是17x17,而且下面还会被割去几个象素。” -- lulei204   “MOTO中低端机型都只有一种字体,而且是中号字体。” -- summoner  
SonyEricsson S700c 上用g.drawString()方法绘制的汉字为何很大? “索爱S700c上面,Canvas 的drawString()方法绘制的汉字为何很大? 一行最多显示10个字左右。 用了Font的SIZE_SMALL还是一样。” --webgl2005 “有的手机只支持一种字体,用Font的参数都没有效果。” ---magicDragon
怎样为nokia qd设置字体颜色? “不知道为什么在QD上字体就只有黑色.怎么设置也不行. Image offImage    = Image.createImage(SCREEN_WIDTH, SCREEN_HEIGHT) ; Graphics offGraphics = offImage.getGraphics() ; offGraphics.setColor(0xffff00) ; offGraphics.drawString(……) ; 这么写的话,字体永远都是黑色的,但在paint()里直接用g.setColor()却是正常的。” --- 海标 “setColor在非paint中得到的graphics中都无效。这是S60的bug。 ” ---蜡笔小刀  
moto字体移植问题 “有人说moto字体不好看,大小调整上给移植带来很大麻烦,我以前也这么认为。 现在我觉得moto的字体还行。在没有办法的情况下,我们只好在程序上下功夫,让字排列的更美观、更好看。” --lulei204 “moto就是这样,移植的时候狠不得把所有文字都去掉” --topig
  

6 重新播放音乐问题

 

player/stop/start

关键词 详细描述
音乐停止播放后如何从起始位置重新播放? “如果你的音乐自己播放完毕了,而用户手动提交命令要求重新播放,那么你可以直接调用player.play()即可。或者一开始播放音乐的时候就利用player.setLoopCount设定循环播放次数。   如果你希望音乐自动重新播放,那么就必须实现“播放器状态更新事件”: 以下内容为程序代码: // 绑定状态更新事件过程 player.addPlayerListener(this);   /*  * 本类实现了PlayerListener接口。通过这个事件来告知媒体已经播放完毕  */ public void playerUpdate(Player player, String event, Object data){        System.out.println("Enter playerUpdate>>" +                      event);               if(event == PlayerListener.END_OF_MEDIA){               try{                      ....                                      }catch(Exception e){                      e.printStackTrace();               }        }        else if(event == PlayerListener.STOPPED)        {               System.out.println("playerUpdate>>PlayerListener.STOPPED");        }        else if(event == PlayerListener.STARTED)        {               System.out.println("playerUpdate>>PlayerListener.STARTED");        } } ” --- zhengyun  
SonyEricsson K750手机上无法实现暂停,续播功能? “发觉在索爱K750手机上无法实现暂停,续播功能。该功能在MOTO,NOKIA手机上可以使用。” --trysunset  
   
 

7 MediaException问题

 

player/stop/start

关键词 详细描述
播放MIDI时,真机上会爆出MediaException 异常,而在其他机器上可正常播放MIDI? “is = getClass().getResourceAsStream("/title.mid");   if (is != null) {  player_ = Manager.createPlayer(is, "audio/midi");     player_.setLoopCount(-1);     player_.start(); } 这个代码是我用来监测一款机器用的,在播放MIDI时,其真机上会爆出MediaException异常,而在其他机器上可正常播放MIDI!
有意思的是这个代码用来播放WAV则是正常的,由于该PDA机自带播放器,我将MIDI直接传入其中播放时可以播放的,所以应该不会有MIDI格式不兼容的问题!
--- imtrash   “虚拟机不支持MIDI的播放!  我用过的NOKIA6630的手机就是这样的!” --- zgly   “你可以将虚拟机可以播放的音乐类型用下面的代码    public void showForm() {         String[]  protocols, contentTypes;           protocols = Manager.getSupportedProtocols(null);         for (int i = 0; i < protocols.length; i++) {             contentTypes = Manager.getSupportedContentTypes( protocols[i]);             for (int j = 0; j < contentTypes.length; j++) {                 m_errForm.append(protocols[i] + ":" + contentTypes[j]);              }         }     } 将信息显示在一个FORM里!” --- zgly   “必须明确的一点是,我们的MIDlet是运行在Java ME平台环境下的。  不一定设备提供的功能在Java ME平台都得到了实现!” --- mingjava  
在真机测试中, Nokia7610弹出一个错误: “javax. microedition. media. MediaException: -18”? “很明显是nokia 7610上不支持这种媒体格式设置media time,所以抛出了MediaException。 把p.setMediaTime(5 * SECS_TO_MICROSECS);删除即可” -- mingjava  
   
 
“error opening MIDI/tone device”或“fail in writing data to native”? “播放MIDI的代码在k700和6600上都没问题,在moto上不知道怎么回事却报如下异常: javax.microedition.media.MediaException: fail in writing data to native 用e680i的模拟器仍然会报错, 不过报出来的是: javax.microedition.media.MediaException: error opening MIDI/tone device         at com.sun.mmedia.MIDIPlayer.doPrefetch(+19)         at com.sun.mmedia.BasicPlayer.prefetch(+34) 最后找到原因了,moto的机器不能同时有两个midi的player在prefetch()中,即使前面那个player并没有执行start(),后面生成player都会在prefetch()和start()的时候产生上面的异常! 因为我有一个midi player一直在prefetch状态,所以新生成的midi的player都不能start(). 真是个奇怪的现象阿,在其他手机上都不会有这个问题。” ---saltedfish
   
 

8 混音问题

 

player/mixer

关键词 详细描述
Moto真机上如何在播放背景音乐的时候再播放音效? “摩托罗拉V300-V500-V600同时播放音乐的讲究: 唯一支持的同步播放音乐的办法是,midi和wav声音混合播放。 即使是这样,也存在着一个限制: 应用程序必须先播放midi(可以作为背景音乐),然后再播放wav;wav文件还必须是以下的格式: PCM 8000KHZ; 8Bit; Mono。 除了上面这种方法,只要是一个新的media被播放,上一个Player必须被停止而且释放资源。” --moto文档   “MOTO系列手机中JAVA程序播放一个声音文件比较简单,但是用于交互式音效时就有问题了。 根据MOTO的一些资料显示,在MOTO手机中播放声音有下面几条约束: 1、除了同时播放一个MIDI和一个WAV以外,MOTO手机无法同时播放多个声音,而且必须是先播放MIDI然后播放WAV; 2、除了MIDI或音阶序列以外,不能同时实现player的多个实例进入prefetched状态(预读取声音流); 3、播放新的声音之前,前一个player必须停止并释放资源(stop();deallocate())。 如果你遇到以下问题,可以试试我的解决方法: 1)只能播一次,或几次,接着就无法发出声音; 2)播放新的声音时,总是会多播放一次前一个声音。” ---linchangyu
nokia6230i上的MediaException现象 “当一个Player被prefetched,那么其他Player也就不再能够prefetched,除非它们都是midi或都是amr。 如果你没有在start/prefetch一个Player之前把其他的Player停下来,那么你将得到一个MediaException。” --无名  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐