PhoneGapで音を鳴らす（Android対応版）


PhoneGapはHTML5アプリをモバイルアプリに変換してくれる。
つまり、HTML5アプリを作れば、iOSアプリもAndroidアプリもそのまま作れちゃう。

ところが、HTML5の以下の様な音の再生ができない。

```
var audio = new Audio("./hoge.ogg");
audio.play();
```

代わりに、PhoneGapのPluginのmediaを使う必要がある。
Androidの場合は、soundファイルへのアクセスの仕方に癖があるのでメモ。

## 公式サイト

https://github.com/apache/cordova-plugin-media/blob/b2e92f93964f76bbec667dfdfe15caec435932b6/doc/index.md

## オーソドックスなやり方

例えば、次のサイトが参考になる。

http://docs.monaca.mobi/cur/ja/sampleapp/tips/media/

Mediaの第2引数は成功時のfunction、第3引数は失敗時のfunctionを入れる。

```
var src = 'sample.mp3';
media = new Media (getPath() + src , onSuccess, onError);

//Androidではプロジェクト中にあるmp3ファイルを読み込ませるために絶対パスを指定します。そのための関数です。
function getPath() {
    var str = location.pathname;
    var i = str.lastIndexOf('/');
    return str.substring(0,i+1);
}
```

これでいいのだけれど、PhoneGap Builderのデバッガーでは動作しない。
（インストールすると動く）
これはとても不便。

## 別のやり方（正しいのかはわからない）

以下のように、`location.pathname`を`location.href`にすると、PhoneGap Builderのデバッガーでも動作する。

```
var src = 'sample.mp3';
media = new Media (getPath() + src , onSuccess, onError);

//Androidではプロジェクト中にあるmp3ファイルを読み込ませるために絶対パスを指定します。そのための関数です。
function getPath() {
    var str = location.href;
    var i = str.lastIndexOf('/');
    return str.substring(0,i+1);
}
```

## 参考

結局、こんな感じにしました。

```
var src = 'sounds/alarm.mp3';
audio = getAudio(src);
audio.play();

function getAudio(src){
    // Phonegap media
    if (device.platform.toLowerCase() === 'android'){
        // Android needs the search path explicitly specified
        src = getPath() + src;
    }
    return new Media(src, null, function(error){ alert(src + ':' + JSON.stringify(error)); });
}

function getPath() {
    var str = location.href;
    var i = str.lastIndexOf('/');
    return str.substring(0, i + 1);
}
```

## ブラウザアプリとmobileアプリで同じコードに

ブラウザアプリのときとmobileアプリのときで書き直すとかは最悪。
ということで、こんな風にしてみました。

要はHTML5のAudioが使えるかどうか。
ところが、mobileのときでも一応Audioは関数として取得できている。
苦肉の策でAudio関数を文字列にしてHTMLAudioElementが含まれているかで判断。

ちなみに、止め方をAudioとMediaで分けているのは、次の記述が気になるため。

https://github.com/apache/cordova-plugin-media/blob/b2e92f93964f76bbec667dfdfe15caec435932b6/doc/index.md

> Releases the underlying operating system's audio resources. This is particularly important for Android, since there are a finite amount of OpenCore instances for media playback. Applications should call the release function for any Media resource that is no longer needed.

```
var is_html5_audio, audio;
var src = 'sounds/alarm.mp3';

$(function() {
    is_html5_audio = (String(Audio).indexOf('HTMLAudioElement') > 0);
    
    $('#start').click(function() {
       audio = getAudio(src);
		audio.play();
    });

    $('#stop').click(function(){
        if(is_html5_audio){
            audio.pause();
        } else{
            audio.stop();
            audio.release();
        }
    });
	
});

function getAudio(src){
    // HTML5
    if(is_html5_audio){
        return new Audio(src);
    }
    // Phonegap media
    if (device.platform.toLowerCase() === 'android'){
        // Android needs the search path explicitly specified
        src = getPath() + src;
    }
    return new Media(src, null, function(error){ alert(src + ':' + JSON.stringify(error)); });
}

function getPath() {
    var str = location.href;
    var i = str.lastIndexOf('/');
    return str.substring(0, i + 1);
}
```

ただ、ブラウザアプリのとき、index.htmlの`<script type="text/javascript" src="cordova.js"></script>`の読み込みエラーはでてしまう。。。