zoukankan      html  css  js  c++  java
  • j2medev“用户界面和多媒体”版面问题整理[0407更新]

    出品商

    产品名称

    产品版本

    J2medev.com

    版面有价值的问题合集

    0.1

    j2medev.com之“用户界面和多媒体”版面

    有价值问题的整理

    历史

    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直接用nokiaFullCanvas全屏好像是176*208,直接拿nokia60上的程序可以直接放进去。键值和60的也是相同的,只是多了一个返回键,我忘了值是多少了。用2.0GameCanvas大小是176*220

    --- lulei204

     

    不使用FullCanvas实现全屏的方法

    为了用标准的SUN WTK2.1开发能兼容各种机型的MIDP2.0游戏,会遇到一个奇怪的全屏问题,在K700上好好的,到了Nokia上居然死活显示一半,费了一番功夫后,终于不用FullCanvas实现了兼容K700Nokia的全屏显示,方法如下:

    在索爱的K700上,实现全屏很简单,如下写法就可以了:

    public Canvas1()

    {         super(false);

            this.setFullScreenMode(true);

            this.width=getWidth();

            this.height=getHeight();

    } 得到的屏幕大小是176*220

    Nokia上就比较奇怪了,这种方式取得的widthheight居然是176*144

    需要加以下代码修正一下:

    if(width>=176)

    {     if(height<208)

        {

             height=208;

        }

    } 绘图部分都以widthheight为基准。

    另外canvas1不能继承系统的GameCanvas,因为系统GameCanvas里的缓冲图还是176*144的,画出来就只能是半屏,我用j2me polish里的GameCanvas修改一下后,放到src里代替系统GameCanvasOK了。

    修正过的GameCanvas代码如下:

    http://www.j2medev.com/bbs/dispbbs.asp?

    BoardID=19&ID=3218&replyID=&skin=1

    ---alexhy

    FullCanvassetFullScreenMode()的区别

    setFullScreenMode用于MIDP2.0设备上。com.nokia.mid.ui.FullCanvasNokia UI API 1.1的包,用于MIDP2.0设备上,SonyEricsson手机也支持。

     

    FullCanvas是肯定可以实现全屏幕显示的,但是MIDP2.0里面的setFullScreenMode()只是实现为尽量使用最大的屏幕空间,但是不一定是全屏幕,要看各个手机的实现。”

    ---mingjava

    FullCanvas不能加CommandsetFullScreenMode(true)可以加上Command()。只是我加上一个按键时,却不管把它设在哪里,只能是右键响应。”

    ---风过留痕

    FullCanvasCanvasGameCanvas分别有什么不同

    FullCanvasCanvas的子类,实现全屏的功能,而且把按键针对nokia的手机进行了映射。其他没有什么区别。”

    ---migjava

    GameCanvas也是Canvas的子类,自MIDP2.0起提供,专门针对游戏增加了一些功能。在按键和显示各方面的运用都和Canvas有较大的不同。”

    ---efei

    MotorolaMIDP1.0手机

    motorola如果不支持MIDP2.0,应该就没办法实现全屏了。全屏下的菜单很好实现,不用搞得象Command那么复杂,那个Command用起来就是很不爽,还是自己写最好。”

    ---海标

    Nokia S60全屏后的Canvas高度

    “canvas. setFullScreenMode(true)后,一定让他被绘制一次,系统会调用sizechange(int w,int h)wh肯定是全屏的。仅调用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全屏情况下getHeightBUG,此函数出自于

              * 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 ImageByteArray转换问题

     

    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[n] = (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混合》摘要几句:

    [quote]

    MIDP2.0中新增了Alpha混合特性...MIDP2.0 java doc中关于Alpha Processing的说明:在可修改图片中的每个像素都必须是完全模糊的,在不可修改图片中的每个像素可以是完全透明的,完全模糊的或者介于两者之间的,也就是半透明...

    [/quote]

     

    所以有了上面的Alpha channel

     

    [quote]

    数组中的数值形式为0xAARRGGBB,其中AA代表透明度,后面的代表颜色值。

    [/quote]

    也就是说,AA就是AlphaRR就是RedGG就是GreenBB就是Blue

     

    还有一句话概括的:

    [quote]444,表示图形格式,好像Nokia S40的机器都是采用444格式表示RGB颜色的。就是红,绿,蓝各用4位表示,至于可以表示透明色ARGB4444格式,应该是机器硬件实现的。[/quote]

    ---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|<width)的话,就可能造成所取的rgbData值会有重复。

     

    API文档里面有一个公式,可以让我们理解地更深刻:

    rgbData[offset + (a - x) + (b - y) * scanlength] = P(a, b)

     

    其中P(a, b)表示在IMAGE数组中位置为(a,b)的像素点。

    具体的内容可以参考API文档。

    其实MIDP2.0getRGB()跟NOKIAgetPixels)是类似的。

    --- 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个字左右。

    用了FontSIZE_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中都无效。这是S60bug

    ---蜡笔小刀

     

    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的代码在k7006600上都没问题,在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的机器不能同时有两个midiplayerprefetch()中,即使前面那个player并没有执行start(),后面生成player都会在prefetch()start()的时候产生上面的异常!

    因为我有一个midi player一直在prefetch状态,所以新生成的midiplayer都不能start().

    真是个奇怪的现象阿,在其他手机上都不会有这个问题。”

    ---saltedfish

     

     

     

    8 混音问题

     

    player/mixer

    关键词

    详细描述

    Moto真机上如何在播放背景音乐的时候再播放音效?

    “摩托罗拉V300-V500-V600同时播放音乐的讲究:

    唯一支持的同步播放音乐的办法是,midiwav声音混合播放。

    即使是这样,也存在着一个限制:

    应用程序必须先播放midi(可以作为背景音乐),然后再播放wavwav文件还必须是以下的格式:

    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现象

    “当一个Playerprefetched,那么其他Player也就不再能够prefetched,除非它们都是midi或都是amr

    如果你没有在start/prefetch一个Player之前把其他的Player停下来,那么你将得到一个MediaException。”

    -- 无名

     


    9 CustomItem问题

     

    CustomItem/repaint/traverse

    关键词

    详细描述

    CustomItemrepaint

    repaint()产生重绘事件,在CustomItem里它有两个同名的方法,其中一个有四个参数,用来指定重画区的起始XY坐标,宽度和高度;另外一个没有参数,表示重画CustomItem的整个区域。paint()方法里的后两个参数也是宽度和高度,但是这两个方法的宽度和高度没有任何联系, paint方法里的WHItem内容区域的宽度和高度,并且只有这两个值大于0时,paint()方法才会被调用。”

    --mydeman

     

    repaint()被调用之后会立刻返回,而调用paint()回调函数的工作会有另外一个专门处理UI的线程来完成。因此如果希望得到paint()方法完成后再返回,那么就可以在repaint()之后立刻调用serviceRepaint(),来强制队列中重绘事件快点完成。”

    --- mydeman

    CustomItem上处理过左右上下方向键

    “由于我的CustomItem控件和一个Gauge控件同处于一个Form上,所以按上下左右键的时候,实际上被Form处理了,Form就认为上下左右键是在切换控件的焦点,而不会把这个按键事件传给我的CustomItem了。也就是说,我的写法一样不会得到上下左右键的按键事件。”

    -- zhengyun

     

    “一部手机是否实际支持CustomItem internal traversal,需要向getInteractionModes()方法查询才可知道,因为这是隐含的策略,并不是一定的。听说,在Nokia真机上,traverse好像并不好使用。

    在我这里,这段代码在模拟器上能够使用,在真机上我不敢保证:

     

    以下内容为程序代码:

         protected boolean traverse(int dir,int viewportWidth,

        int viewportHeight,int visRect_inout[])

      {

              System.out.println("Enter traverse");

     

             if(dir == Canvas.UP){

           System.out.println("traverse>>Press Up key!");

                  return true;

              }else if(dir == Canvas.DOWN){

         System.out.println("traverse>>Press Down key!");

                  return true;

              }else if(dir == NONE){

         System.out.println("traverse>>Press None key!");

                  return true;

              }

     

              return false;

      }

         protected void traverseOut(){

             System.out.println("Enter traverse out");

         }

    -- zhengyun

     

    protected boolean traverse(int dir, int viewportWidth, int viewportHeight,   int[] visRect_inout) {

     

      switch (dir) {

      case Canvas.DOWN:

       if (location == UPPER) {

        location = IN;

       } else {

        repaint();

        location = LOWER;

        return false;

       }

       break;

     

      case Canvas.UP:

       if (location == LOWER) {

        location = IN;

       } else {

        repaint();

        location = UPPER;

        return false;

       }

       break;

     

      case Canvas.LEFT:

       System.out.println("LEFT");

       break;

      case Canvas.RIGHT:

       System.out.println("RIGHT");

       break;

      }

      return true;

    }

    实际上在FORM里的左右键事件,也被用来处理焦点,只不过在CUSTOM ITEM里左右键没有响应,用上下键来处理焦点事件了。”

    ---hebaochen

     

    10 Nokia播放Tone音乐问题

     

    Sound/

    关键词

    详细描述

    按键,音乐被中断

    “在Nokia 3650,7650上使用Tone播放声音,如果用户一按键,那么音乐马上被中断。这个问题是已经在Nokia官方开发论坛上得到确认。是Symbian 6.0系统上的一个bug,Symbian 7.0系统的手机(Nokia 7610,6600)上没有这个问题,Nokia 40上也没有这个问题。

    解决之道:这是系统的bug,只有使用其它方式的音乐播放,比如midi格式音乐,否则是没有办法的。”

    --二当家的

     

     

     

  • 相关阅读:
    HDU 5583 Kingdom of Black and White 水题
    HDU 5578 Friendship of Frog 水题
    Codeforces Round #190 (Div. 2) E. Ciel the Commander 点分治
    hdu 5594 ZYB's Prime 最大流
    hdu 5593 ZYB's Tree 树形dp
    hdu 5592 ZYB's Game 树状数组
    hdu 5591 ZYB's Game 博弈论
    HDU 5590 ZYB's Biology 水题
    cdoj 1256 昊昊爱运动 预处理/前缀和
    cdoj 1255 斓少摘苹果 贪心
  • 原文地址:https://www.cnblogs.com/zhengyun_ustc/p/j2medev_ui_multimedia_qas.html
Copyright © 2011-2022 走看看