読者です 読者をやめる 読者になる 読者になる

PhoneGapでサクッと。加速度センサーを使うサンプルを紹介します。

今回は、PhoneGapを利用してAndroid端末に搭載されている加速度センサーから端末の向きを取得するサンプルを紹介します。加速度センサーから取得できる値については、こちらで説明されていますので参考して下さい。

さて、シグニチャです。

今回は、一定間隔ごとにAndroid端末の向きを取得します。

navigator.accelerometer.watchAcceleration(accelerometerSuccess, accelerometerError,
[accelerometerOptions]);

参考:PhoneGap API Documentation

accelerometerOptions

frequency

加速度センサーからパラメータを取得する間隔を設定します。

設定値 ミリ秒単位で設定(デフォルトは10000)

accelerometerSuccess

取得した向き情報が引数として渡されますので、データの処理を記述します。

function(acceleration){
    // ここに処理を記述
}
acceleration
acceleration.x 端末を正面に見て横(x)軸の傾き。重力方向に対して水平にすることで0。-10~10
acceleration.y 端末を正面に見て縦(y)軸の傾き。重力方向に対して水平にすることで0。-10~10
acceleration.z 端末を正面に見て手前(z)軸の傾き。重力方向に対して水平にすることで0。-10~10
acceleration.timestamp 情報を取得した日時のミリ秒

cameraError

加速度センサーの情報が取得できなかった場合に実行されます。引数はありません。メッセージの表示や代替の処理を記述します。

function(){
    // ここに処理を記述
}

とりあえずサンプルソース

<!DOCTYPE HTML>
<html>
<head>
<title>PhoneGap Showcase</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8"/>
<link rel="stylesheet" href="jquery.mobile-1.0.min.css" type="text/css" media="all">
<link rel="stylesheet" href="jquery.mobile.structure-1.0.min.css" type="text/css" media="all">
<STYLE type="text/css">
<!--
-->
</STYLE>
</head>
<body>
    <div data-role="page">
        <div data-role="header">
            <h1>Accelerometer Showcase</h1>
        </div>
        <div data-role="content">
            <a id="accelerometer_watch" href="#" data-role="button">計測開始</a>
            <div style="width:100%;height:150px;text-align:center;">
                <div id="accelerometer_watch_word" style="line-height:150px;font-size:100px; "></div>
            </div>
            <div id="accelerometer_watch_status"></div>
            <a id="accelerometer_clear" href="#" data-role="button">計測終了</a>
        </div>
    </div>
</body>
<script type="text/javascript" charset="utf-8" src="jquery-1.7.1.min.js"></script>
<script type="text/javascript" charset="utf-8" src="jquery.mobile-1.0.min.js"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.2.0.js"></script>
<script type="text/javascript">
$(function(){
    document.addEventListener("deviceready",
        function(){
            $('#accelerometer_watch').attr('href', 'javascript:watchStartAccelerometer()');
            $('#accelerometer_clear').attr('href', 'javascript:watchStopAccelerometer()');
        },        false);
})
/*
 * 加速度センサー計測開始
 */
var _accelerometer;
function watchStartAccelerometer(){
     _accelerometer = navigator.accelerometer.watchAcceleration(
        function(acceleration){
            // accelerometerSuccess
            $('#accelerometer_watch_status').html(
                      'x:' + acceleration.x + "<br>" +
                      'y:' + acceleration.y + "<br>" +
                      'z:' + acceleration.z + "<br>" +
                      '日付:' + new Date(acceleration.timestamp).toString());
           
            if(Math.abs(acceleration.x)>9){
                $('#accelerometer_watch_word').html("横")
            }else if(Math.abs(acceleration.y)>9){
                $('#accelerometer_watch_word').html("縦")
            }else if(Math.abs(acceleration.z)>9){
                $('#accelerometer_watch_word').html("水平")
            }else{
                 $('#accelerometer_watch_word').html("")
            }
        },
        function(){
            // accelerometerError
            alert('加速度センサーで内部エラーが発生しました');
        },
        {
            frequency : 1000,
        }
    );
}
/*
 * 加速度センサー計測終了
 */
function watchStopAccelerometer(){
     navigator.accelerometer.clearWatch(_accelerometer);
     $('#accelerometer_watch_status').html('');
     $('#accelerometer_watch_word').html('');
}
</script>
</html>

加速度センサーから情報を取得する

加速度センサーからは、端末の傾きと取得日時が取得できます。コンパスと同様に、取得日時があるので取得間隔の変化量で、端末がどの向きに動かされたか求めることもできます。以下のコードでは、引数として受け取った傾きと取得日時を画面に表示します。

/*
 * 加速度センサーから現在の傾きを取得開始
 */
     _accelerometer = navigator.accelerometer.watchAcceleration( // 取得処理を終了させるため、変数 _accelerometerに格納
        function(acceleration){
            // accelerometerSuccess
            $('#accelerometer_watch_status').html(
                      'x:' + acceleration.x + "<br>" +
                      'y:' + acceleration.y + "<br>" +
                      'z:' + acceleration.z + "<br>" +
                      '日付:' + new Date(acceleration.timestamp).toString());
           
            if(Math.abs(acceleration.x)>9){
                $('#accelerometer_watch_word').html("横")
            }else if(Math.abs(acceleration.y)>9){
                $('#accelerometer_watch_word').html("縦")
            }else if(Math.abs(acceleration.z)>9){
                $('#accelerometer_watch_word').html("水平")
            }else{
                 $('#accelerometer_watch_word').html("")
            }
        },
        function(){
            // accelerometerError
            alert('加速度センサーで内部エラーが発生しました');
        },
        {
            frequency : 1000,
        }
    );

端末を水平においた状態
https://lh5.googleusercontent.com/-NvV4CUuLq8Y/Tvhg4PpY-EI/AAAAAAAALCc/QASFTh9UlRo/s800/accelerometer_Horizontal.jpg


端末を縦にした状態
https://lh6.googleusercontent.com/-Ja8yLPQv99k/Tvhg4-AaO0I/AAAAAAAALCg/biD_H4zfoB8/s800/accelerometer_Longitudinal.jpg


端末を横にした状態
https://lh6.googleusercontent.com/-jUX5T34dj_Q/Tvhg5BTxviI/AAAAAAAALCk/Waw0JScaC-8/s800/accelerometer_Landscape.png.jpg

加速度センサーからの情報取得を終了する

情報取得開始時に格納した変数 _accelerometerを引数にして加速度センサーからの情報取得を終了します。終了時に、表示していた情報を消去しています。

     navigator.accelerometer.clearWatch(_accelerometer);
     $('#accelerometer_watch_status').html('');
     $('#accelerometer_watch_word').html('');

まとめ

コンパス同様、簡単に端末の傾きが取得することができます。しかし、加速度センサーの用途として、アクションゲームのコントロールに利用するシーンが考えられますが、シビアなレスポンスを求められる使い方には向かないようです。私が使用しているIS03で動作確認をしたところ、端末の状態が変化してから表示されるまでのタイムラグがありました。原因は、JavascriptからブリッジしてJavaを呼び出し、戻り値を取得するまでの処理コストと考えられます。こういう場合は、やはりネイティブでコーディングすることが必要だと思います。
PhoneGapを利用する場合でも、HTML+Javascript+CSSのみで構築することにこだわらず、ネイティブの利点を生かしながらハイブリットで構築することが大事ですね。