Nokia 手機對聲音播放支援度不一,依系列採用不同 API。本文整理三大類機型實作方式。
不支援 MIDP 2.0 MMAPI,必須使用 Nokia 私有 API:com.nokia.mid.sound.Sound。
import com.nokia.mid.sound.*;
public class MyCanvas extends Canvas {
private Sound sound = null;
// MIDI 轉換而來的位元組陣列 (以 Nokia Audio Converter 產生)
private byte[] toneData = { 0x02, 0x4a, 0x3a, 0x40, 0x04, 0x00, 0x0b, 0x28,
0x83, 0x28, 0x28, 0xd2, 0x28, 0x00 };
private void playTone() {
if (sound != null) { sound.stop(); sound = null; }
sound = new Sound(toneData, Sound.FORMAT_TONE);
sound.setGain(255); // 音量最大
sound.play(1); // 播放一次
}
}
class.zip,提取 com/nokia/mid/sound/Sound.class 打包進專案 lib,編譯後從 JAR 刪除該類別並更新 JAD 大小。使用標準 javax.microedition.media.Manager 播放 MIDI。
import javax.microedition.media.*;
private Player player = null;
private void playSound(String name) { // name 如 "kill.mid"
try {
if (player != null) { player.close(); player = null; }
player = Manager.createPlayer(getClass().getResourceAsStream("/"+name), "audio/midi");
player.addPlayerListener(this);
player.setLoopCount(1);
player.realize();
player.start();
} catch (Exception e) { e.printStackTrace(); }
}
public void playerUpdate(Player p, String event, Object data) {
Display.getDisplay(midlet).callSerially(() -> updateEvent(p, event, data));
}
private void updateEvent(Player p, String event, Object data) {
if (event.equals(PlayerListener.END_OF_MEDIA)) p.close();
else if (event.equals(PlayerListener.CLOSED)) p = null;
}
// Canvas 端
void stopTone() { if (sound != null) sound.stop(); }
// MIDlet 端
public void pauseApp() {
if (canvas != null && soundEnabled) canvas.stopTone();
}
| 機型系列 | API | 格式 | 備註 |
|---|---|---|---|
| S40 / S60v1 | com.nokia.mid.sound.Sound | Tone (MIDI 轉 byte[]) | 需 Nokia SDK、手動打包類別 |
| S60v2 / S40 3rd+ (如 7610) | javax.microedition.media.Manager | MIDI, AMR, WAV 等 | 標準 MMAPI,支援 PlayerListener |
針對不同 Nokia 平台採用對應 API,並妥善處理生命週期 (pauseApp 停止聲音),可實現跨機型穩定播放。