/* * Notify.java * * Created on 22 ������ 2007 �., 17:17 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package jimm.modules; // #sijapp cond.if modules_ANDROID is "true" # import ru.net.jimm.sound.SoundPlayer; // #sijapp cond.else # import javax.microedition.media.*; import javax.microedition.media.control.*; // #sijapp cond.end # import java.io.InputStream; import jimm.*; import jimm.comm.Util; import jimmui.view.base.Popup; import jimm.util.*; /** * * @author vladimir */ // #sijapp cond.if modules_SOUND is "true" # public class Notify implements Runnable // #sijapp cond.if modules_ANDROID isnot "true" # , PlayerListener // #sijapp cond.end # { private static Notify _this = new Notify(); public static Notify getSound() { return _this; } /* Notify notification typs */ public static final int NOTIFY_MESSAGE = 0; public static final int NOTIFY_ONLINE = 1; public static final int NOTIFY_TYPING = 2; public static final int NOTIFY_MULTIMESSAGE = 3; public static final int NOTIFY_ALARM = 4; public static final int NOTIFY_RECONNECT = 5; public static final int NOTIFY_BLOG = 6; private static final int VIBRA_OFF = 0; private static final int VIBRA_ON = 1; private static final int VIBRA_LOCKED_ONLY = 2; private String nextMelody = null; private long nextPlayTime = 0; private int playingType = 0; private static String[] files = {null, null, null, null, null, null, null}; private static String fileVibrate = null; /** * Creates a new instance of Notify */ private Notify() { } private String getMimeType(String ext) { if ("mp3".equals(ext)) { return "audio/mpeg"; } if ("mid".equals(ext) || "midi".equals(ext)) { return "audio/midi"; } if ("amr".equals(ext)) { return "audio/amr"; } if ("mmf".equals(ext)) { return "audio/mmf"; } if ("imy".equals(ext)) { return "audio/iMelody"; } if ("aac".equals(ext)) { return "audio/aac"; } if ("m4a".equals(ext)) { return "audio/m4a"; } return "audio/X-wav"; // wav } private void vibrate(int duration) { Jimm.getJimm().getDisplay().getNativeDisplay().vibrate(duration); } private int getVolume() { return Options.getInt(Options.OPTION_NOTIFY_VOLUME); } // Play a sound notification private boolean isSoundNotification(int notType) { switch (notType) { case NOTIFY_MESSAGE: return 0 < Options.getInt(Options.OPTION_MESS_NOTIF_MODE); case NOTIFY_ONLINE: return 0 < Options.getInt(Options.OPTION_ONLINE_NOTIF_MODE); case NOTIFY_BLOG: return Options.getBoolean(Options.OPTION_BLOG_NOTIFY); case NOTIFY_MULTIMESSAGE: return false; } return true; } private boolean isCompulsory(int notType) { switch (notType) { case NOTIFY_MESSAGE: case NOTIFY_MULTIMESSAGE: case NOTIFY_ALARM: case NOTIFY_BLOG: return true; } return false; } private void playNotify() { int notType = playingType; int vibrate = 0; if (NOTIFY_ALARM == notType) { vibrate = 1500; } else { int vibraKind = Options.getInt(Options.OPTION_VIBRATOR); if ((VIBRA_LOCKED_ONLY == vibraKind) && !Jimm.getJimm().isLocked()) { vibraKind = VIBRA_OFF; } if ((VIBRA_OFF != vibraKind) && ((NOTIFY_MESSAGE == notType) || (NOTIFY_MULTIMESSAGE == notType))) { vibrate = Jimm.getJimm().isPaused() ? 700 : 200; } } boolean play = !Options.getBoolean(Options.OPTION_SILENT_MODE) && isSoundNotification(notType); String file = play ? files[notType] : null; if (0 < vibrate) { // #sijapp cond.if modules_ANDROID isnot "true" # if (null != fileVibrate) { if (null != file) { nextMelody = file; } safePlay(fileVibrate); return; } // #sijapp cond.end# vibrate(vibrate); } if (null != file) { safePlay(file); // #sijapp cond.if modules_ANDROID isnot "true" # } else if (play && (NOTIFY_MESSAGE == notType)) { try { Manager.playTone(ToneControl.C4, 750, getVolume()); } catch (Exception e) { } // #sijapp cond.end# } } private void closePlayer() { // #sijapp cond.if modules_ANDROID is "true" # if (null != androidPlayer) { androidPlayer.close(); androidPlayer = null; } // #sijapp cond.else # closePlayer(j2mePlayer); // #sijapp cond.end # } public void run() { try { playNotify(); } catch (OutOfMemoryError err) { } } private void playNotification(int notType) { final long now = System.currentTimeMillis(); long next = nextPlayTime; if (!isCompulsory(playingType) && isCompulsory(notType)) { next = 0; } if (now < next) { return; } if (NOTIFY_ALARM == notType) { if (!Options.getBoolean(Options.OPTION_ALARM)) { return; } next = now + 3000; } else { next = now + 2000; } nextPlayTime = next; playingType = notType; new Thread(this).start(); } public void playSoundNotification(int notType) { synchronized (syncObject) { playNotification(notType); } } private final Object syncObject = new Object(); // #sijapp cond.if modules_ANDROID isnot "true" # private Player j2mePlayer; // #sijapp cond.else# private SoundPlayer androidPlayer; // #sijapp cond.end# // #sijapp cond.if modules_ANDROID isnot "true" # public void playerUpdate(final Player player, final String event, Object eventData) { if (PlayerListener.END_OF_MEDIA.equals(event)) { closePlayer(player); String next = nextMelody; if (null != next) { nextMelody = null; safePlay(next); } } } private void closePlayer(final Player p) { if (p == j2mePlayer) { j2mePlayer = null; } if (null != p) { try { p.stop(); } catch (Exception e) { } try { p.close(); } catch (Exception e) { } } } // #sijapp cond.end # private void safePlay(String file) { try { closePlayer(); createPlayer(file); play(); } catch (Exception e) { closePlayer(); } catch (OutOfMemoryError err) { closePlayer(); } } private boolean testSoundFile(String source) { try { createPlayer(source); return true; } catch (Exception e) { return false; } finally { closePlayer(); } } /* Creates player for file 'source' */ private void createPlayer(String source) throws Exception { // #sijapp cond.if modules_ANDROID isnot "true" # /* What is file extention? */ String ext = source.substring(source.lastIndexOf('.') + 1); InputStream is = jimm.Jimm.getResourceAsStream(source); if (null == is) throw new Exception(); j2mePlayer = Manager.createPlayer(is, getMimeType(ext)); j2mePlayer.addPlayerListener(this); // #sijapp cond.else # androidPlayer = new SoundPlayer(); androidPlayer.play(source, getVolume()); // #sijapp cond.end # } private void play() throws Exception { // #sijapp cond.if modules_ANDROID isnot "true" # j2mePlayer.realize(); try { int volume = getVolume(); VolumeControl c = (VolumeControl) j2mePlayer.getControl("VolumeControl"); if ((null != c) && (0 < volume)) { c.setLevel(volume); } } catch (Exception e) { } j2mePlayer.prefetch(); j2mePlayer.start(); // #sijapp cond.else # androidPlayer.start(); // #sijapp cond.end # } private String selectSoundType(String name) { /* Test other extensions */ String[] exts = Util.explode("mp3|wav|mid|midi|mmf|amr|imy|aac|m4a", '|'); for (int i = 0; i < exts.length; ++i) { String testFile = name + exts[i]; if (testSoundFile(testFile)) { return testFile; } } return null; } public void changeSoundMode(boolean showPopup) { boolean newValue = !Options.getBoolean(Options.OPTION_SILENT_MODE); closePlayer(); Options.setBoolean(Options.OPTION_SILENT_MODE, newValue); Options.safeSave(); if (showPopup) { String text = newValue ? "#sound_is_off" : "#sound_is_on"; new Popup(JLocale.getString(text)).show(); } vibrate(newValue ? 0 : 100); } public void initSounds() { files[NOTIFY_ONLINE] = selectSoundType("/online."); files[NOTIFY_MESSAGE] = selectSoundType("/message."); files[NOTIFY_TYPING] = selectSoundType("/typing."); files[NOTIFY_ALARM] = selectSoundType("/alarm."); files[NOTIFY_RECONNECT] = selectSoundType("/reconnect."); files[NOTIFY_BLOG] = selectSoundType("/blog."); if (testSoundFile("/vibrate.imy")) { fileVibrate = "/vibrate.imy"; } } public boolean hasAnySound() { for (int i = 0; i < files.length; ++i) { if (null != files[i]) { return true; } } return false; } } // #sijapp cond.end #