Hi,
I'm trying to add sounds to my app but cannot get it to work on iOS devices.
The app keeps crashing after a few sounds have played. (Successive sounds are not played rapidly one after another.)
A crash means the app is moved to background and when moved to foreground it either restarts or hangs.
Playing the sounds works fine in the Simulator and on Android device.
CN1 version is 1.0.77. NetBeans 7.3 & Windows 7.
Devices: iPad/iOS 7.1.2 and iPodTouch/iOS 6.1.6, Nexus7/Android 4.4.4
I've tried several methods, see the code below.
1. with an input stream from resource or from jar - works fine in simulator and on android device, crashes on ios devices
2. as 1, wrapped in a call serially - same result
3. copy wav to Storage and use a uri - could not get this to work anywhere; how does a uri work for Storage files?
4. (re-)use a MediaPlayer and setDataSource(is) - simulator:ok, ipad:crash after few, nexus:NullPointerException
5. built-in sounds and install new - nothing to hear on iPad/iPod (not tested on android)
The functions below are called for instance like this: playSound1("click2.wav");
Please help as I ran out of things to try.
private void playSound1(final String soundFile) {
try {
//final InputStream is = soundres.getData(soundFile);
final InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/" + soundFile);
Media media = MediaManager.createMedia(is, "audio/wave", null);
media.setVolume(SOUND_VOLUME);
media.play();
} catch (IOException ex) {
Dialog.show("Error playing " + soundFile, ex.getMessage(), STR_OK, null);
}
}
private void playSound2(final String soundFile) {
Display.getInstance().callSerially(new Runnable() {
public void run() {
playSound1(soundFile);
}
});
}
private void playSound3(final String soundFile) {
try {
Storage s = Storage.getInstance();
if (!s.exists(soundFile)) {
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/" + soundFile);
OutputStream os = s.createOutputStream(soundFile);
Util.copy(is, os);
}
//String uri = soundFile; // ERROR: resources [...] must start with a '/' character
//String uri = "/" + soundFile; // IllegalArgumentException: uri.getScheme() == null
//String uri = "file://" + soundFile; // IllegalArgumentException
//String uri = "file:///" + soundFile;
// ^ Simulator: IllegalArgumentException
// ^ iPad: no sound, no crash
// ^ Nexus: Error playing click2.wav: open failed: ENOENT (No such file or directory)
// ^ works but not flawless: about 1:10 you hear nothing, and still a crash after 50 times on ipad
Media media = MediaManager.createMedia(uri, false);
media.setVolume(SOUND_VOLUME);
media.play();
} catch (IOException ex) {
Dialog.show("Error playing " + soundFile, ex.getMessage(), STR_OK, null);
}
}
private void playSound4(final String soundFile) {
if (mp == null) {
mp = new MediaPlayer();
}
try {
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/" + soundFile);
if (is != null) {
mp.setDataSource(is, "audio/wave", null);
mp.getMedia().setVolume(SOUND_VOLUME);
mp.getMedia().play();
} else {
Dialog.show("Error", soundFile + " not found", STR_OK, null);
}
} catch (IOException ex) {
Dialog.show("Error playing " + soundFile, ex.getMessage(), STR_OK, null);
}
}
private void playSound5(final String soundFile) {
System.err.println("isBuiltinSoundsEnabled = " + Display.getInstance().isBuiltinSoundsEnabled()); // true
// try standard built-in sound
System.err.println("SOUND_TYPE_ERROR available = " + Display.getInstance().isBuiltinSoundAvailable(Display.SOUND_TYPE_ERROR)); // true
//Display.getInstance().playBuiltinSound(Display.SOUND_TYPE_BUTTON_PRESS); -- nothing
//Display.getInstance().playBuiltinSound(Display.SOUND_TYPE_ALARM); -- nothing
//Display.getInstance().playBuiltinSound(Display.SOUND_TYPE_CONFIRMATION); -- nothing
//Display.getInstance().playBuiltinSound(Display.SOUND_TYPE_ERROR); -- nothing
//Display.getInstance().playBuiltinSound(Display.SOUND_TYPE_INFO); -- nothing
//Display.getInstance().playBuiltinSound(Display.SOUND_TYPE_WARNING); -- nothing
//Display.getInstance().vibrate(500); // doesn't work either
// try to add a sound
String sound = soundFile.substring(0, soundFile.length()-4); // - ".wav"
if (Display.getInstance().isBuiltinSoundAvailable(sound)) {
System.err.println("sound available!");
} else {
System.err.println("install sound...");
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/" + soundFile); // (1)
try {
Display.getInstance().installBuiltinSound(sound, is);
System.err.println("...ok.");
} catch (IOException ex) {
Log.p(ex.getMessage());
}
}
Display.getInstance().playBuiltinSound(sound);
}