In My case i have scanning app with phone gap.
and it vibrates and beep fail when scan fails via our API scanning ticket.
and there is success sound without vibration via our API scanning ticket.
After 35 to 40 times it fails to either vibrate or play sound.
Code Before Fix:
In HTML
<audio id="successSound"
src="/android_asset/www/audio/correct.mp3"
type="audio/mpeg">
</audio>
var my_media = null;
var mediaTimer = null;
function playAudio(id) {
var audioElement = document.getElementById(id);
var src = audioElement.getAttribute('src');
// Create Media object from src
// alert(src);
// alert(getPathMedia());
my_media = new Media(src, onSuccess, onError);
// Play audio
my_media.play();
// Update my_media position every second
if (mediaTimer == null) {
mediaTimer = setInterval(function() {
// get my_media position
my_media.getCurrentPosition(
// success callback
function(position) {
if (position > -1) {
setAudioPosition((position) + " sec");
}
},
// error callback
function(e) {
console.log("Error getting pos=" + e);
setAudioPosition("Error: " + e);
}
);
}, 1000);
}
}
// Pause audio
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
// Stop audio
function stopAudio() {
if (my_media) {
my_media.stop();
}
clearInterval(mediaTimer);
mediaTimer = null;
}
// onSuccess Callback
//
function onSuccess() {
// alert('success');
}
// onError Callback
function onError(error) {
switch(error.code){
case MediaError.MEDIA_ERR_ABORTED:
alert('MEDIA_ERR_ABORTED code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NETWORK:
alert('MEDIA_ERR_NETWORK code: ' + error.code);
break;
case MediaError.MEDIA_ERR_DECODE:
alert('MEDIA_ERR_DECODE code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NONE_SUPPORTED:
alert('MEDIA_ERR_NONE_SUPPORTED code: ' + error.code);
break;
default:
{
alert('Un Known: ' + error.code);
navigator.notification.vibrate(2000);
playAudio("errorSound");
}
}
}
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
Code After Fix:
var failCounter = 0;
var successCounter = 0;
var srcSuccess = "/android_asset/www/audio/correct.mp3";
var srcFail = "/android_asset/www/audio/error_long.mp3";
var my_media_success = null;
var my_media_fail = null;
function playAudioSuccess() {
// stopAudio(my_media);
if (my_media_success != null) {
my_media_success.release();
}
successCounter = successCounter + 1;
// Create Media object from src
// alert(src);
// alert(getPathMedia());
try {
my_media_success = new Media(srcSuccess, onSuccess, onError);
// my_media.setVolume('1.0');
// if (successCounter >= 35) {
// alert("success count " + successCounter + " total counting " + ( successCounter + failCounter));
// }
// Play audio
my_media_success.play();
} catch (err) {
alert(err);
}
}
function playAudioFail() {
try {
// stopAudio(my_media);
if (my_media_fail != null) {
my_media_fail.release();
}
failCounter = failCounter + 1;
// Create Media object from src
// alert(src);
// alert(getPathMedia());
my_media_fail = new Media(srcFail, onSuccess, onError);
// my_media_fail.setVolume('1.0');
// if (failCounter >= 35) {
// alert("fail count " + failCounter + " total counting " + ( successCounter + failCounter));
// }
// Play audio
my_media_fail.play();
} catch (err) {
alert(err);
}
}
// Pause audio
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
// Stop audio
function stopAudio(my_media) {
if (my_media) {
my_media.stop();
}
// clearInterval(mediaTimer);
// mediaTimer = null;
}
// onSuccess Callback
//
function onSuccess() {
// alert('success');
}
// onError Callback
function onError(error) {
switch(error.code){
case MediaError.MEDIA_ERR_ABORTED:
alert('MEDIA_ERR_ABORTED code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NETWORK:
alert('MEDIA_ERR_NETWORK code: ' + error.code);
break;
case MediaError.MEDIA_ERR_DECODE:
alert('MEDIA_ERR_DECODE code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NONE_SUPPORTED:
alert('MEDIA_ERR_NONE_SUPPORTED code: ' + error.code);
break;
default:
{
alert('Un Known: ' + error.code);
navigator.notification.vibrate(1000);
setTimeout(function() {
playAudioFail();
}, delayInMilliseconds);
}
}
}
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
After lot of try and error and alerts here and there !
1) I avoided getElementById
to get the src path i just defined it as global variable.
2) I separated the methods of success and fail ( refactoring )
3) I made the variables local as much as possible to avoid any memory leaks and overlapping and exceed stack etc.. stuff.
4) I removed the setAudioPosition
method because its not used and called without a reason.
( lesson learned) when you take your code from internet be carefull of what you really need.
5) I noticed when i added alerts it worked but when i removed them it did not work , so my
MAIN SOLUTION was adding Timeoutbetween vibrate which is called first , and the play method at critical section like this
navigator.notification.vibrate(1000);
setTimeout(function() {
playAudioFail();
}, delayInMilliseconds);
6) I added release method , but
(leasson learned) be aware where to put it
so I put it before calling the play it self on correct reference to same variable ofcourse.
if (my_media_fail != null) {
my_media_fail.release();
}
7) Last advice as its javascript you can use try and catch just in case ))
Try catch W3School