【GAS】ジョギングのお伴にいかが?GASを使ったWEBアプリ「かんたん走行記録」で、GPSの位置情報をスプレッドシートに記録しよう!(6)位置情報の取得を一時スリープさせること、画面をスリープさせないこと
スマートフォンなどから、手軽に入手できる様になったGPS情報を日常生活で活かす例として、自身の位置情報をスプレッドシートに自動記録するWEBアプリを作ってみました。
ジョギングの時の記録に使えそうなので、「かんたん走行記録」アプリと称してみました。
これまでの解説記事です。
①テンプレートにJavaScriptを記載してGPSの位置情報を取得する
②WEBページ上で取得した位置情報をGoogleスプレッドシートに書き込む
③スプレッドシート上で距離計算やGoogleマップの参照URLを生成し、WEBページに戻す
以上で、このWEBアプリの仕組みのあらましを説明しましたが、最後に2つ課題があります。それは、スリープさせる/させないという処理がこのアプリでは必要なことです。
位置情報を取得するJavaScript関数である、watchPosition()関数は、適切な間隔でスリープさせないと、スプレッドシートへの書き込みイベントが頻発し、ブラウザがパンクしてしまいます。つまり、JavaScript関数を時々スリープさせるという課題があります。
また、このアプリを長時間表示させてジョギングすると、スマートフォンがスリープ状態に入ってしまい、その時点で処理が止まってしまいます。つまり、スリープさせないという課題があります。
今回の記事では、この点をご説明します。
watchPosition()関数を定期的にスリープさせて、スプレッドシートへの書き込みイベントがパンクするのを回避するには
本アプリでは、テンプレート内に以下のコードを書くことで、位置情報を得ています。
<script>
・・・・
// ブラウザからgeolocationが使える場合に実行
if (navigator.geolocation) {
// watchPosition関数を使用
var watchId =navigator.geolocation.watchPosition(
// 無名関数を使って位置情報を引数POSに入れて処理
function (pos) {
// タイムスタンプの取得
var 日付 = new Date(pos.timestamp);
// 位置情報を文字列として保存(区切り文字として■を使用)
var 位置情報 ="POS■" + pos.coords.latitude ;//緯度
myPos+= "■" + pos.coords.longitude ;//経度
myPos+= "■" + pos.coords.speed ;//速度
myPos+= "■" + 日付.toLocaleString();//現地時刻
・・・
// スプレッドシートに転送
google.script.run.シート書込み(位置情報,シート名);
・・・
)
}
・・・・
</script>
上記のコードのキーとなる関数が watchPosition()ですが、この関数は頻繁にGPS情報を返し続けるため困ったことが起きてしまいます。
常時データを発生させるとブラウザがフリーズしてしまう
watchPosition()関数は、GPS情報が変わる毎に値を返します。その為、ユーザが移動している最終は、ひっきりなしにデータを発生させることになります。
一旦データが発生すると、その後の、Googleスプレッドシートへの書き込みイベントに進むため、WEB画面とスプレッドシートの間での送受信待ちのデータが溜まり、処理がパンク(ブラウザがフリーズ)していまいます。
これを防ぐには、プログラムのどこかに、関数watchPositionの機能をスリープ(一時停止)させるコードを実装する必要があります。
JavaScriptにはスリープ処理の関数がない
ところが、よく知られた事ですが、JavaScriptにはプログラムをスリープ(一時停止)させる関数がありません。
スリープ機能はプログラマが個々で工夫して、擬似的に実装しているのが実情です。
実装したコード
今回は、途中で以下のコードを挟んで、先回の処理時刻から30秒経過するまでは無駄足を踏ませる(falseを返す)ことで、擬似的に30秒のスリープ機能を実装しました。(PCに負荷のかかる、コスパの悪い方法ではありますが)
var nowTime = ~~( new Date() / 1000 ) ; // ~~は小数の切り捨て演算子
// 前回の書き出し時刻から30秒以上経過していない場合はfalseを返す
if( (LastTime + 30) > nowTime ){
return false ;
}
// 前回の時刻を更新
LastTime = nowTime ;
直前の処理から30秒以上経過した時だけ、スプレッドシートの書き込みへ進むため、ブラウザのフリーズなどは起こらなくなります。
スマートフォン上で長くWEBページを表示させていると、画面がスリープしてしまうのを回避するには
本アプリでは、GASで作ったWEBアプリを表示させたスマートフォンをポケットに入れてジョギングするなどの使い方を想定しています。
ところが、スマートフォンは、ユーザが画面を触らないでいると、デバイスがスリープして止まってしまいます。
直接デバイスのOSを操作するプログラムであれば、こうした現象は回避できますが、このWEBアプリで使っているプログラムであるJavaScriptは、いわばブラウザ上のマクロ言語であり、残念ながら、デバイスそのものの機能を操作することができません。
常時画面を触りながらジョギングするという手もありますが、とても使えたものではありません・・・何とかならないものでしょうか。
スリープ回避の専用ライブラリを使って対応する
JavaScriptのメリットの一つに、多様なライブラリが公開されている点が挙げられますが、有りがたいことに、画面のスリープ回避についても、ライブラリがいくつか無料公開されています。
その一つが、「NoSleep」というライブラリです。
「NoSleep」のライブラリは、CDNという形態で公開されています。
この形態のライブラリは、JavaScriptのプログラム中では、リンク先を指定するだけで利用が可能です。
CDNで公開されたJSライブラリは、テンプレート内で(だいたい)利用できる
有りがたいことに、CDNで参照できるJSライブラリはテンプレート内でも概ね利用可能で、このライブラリもテンプレート内で使う事ができました。
ライブラリの導入は、以下のコードをテンプレート内の<head>セクションに記しておくだけです。
<head>
<!---- NoSleepライブラリ---->
<script src="https://cdnjs.cloudflare.com/ajax/libs/nosleep/0.12.0/NoSleep.min.js"></script>
</head>
ライブラリを導入することで、簡単な関数によって、デバイスのスリープ回避を実装できます。
ブラウザの画面スリープ回避のコード
ブラウザの画面スリープを回避するには、テンプレート内に記述した位置取得の関数内の始めの方に、以下のコードを記しておきます。
var noSleep = new NoSleep();
noSleep.enable(); // スリープ・ロックを有効化
これだけで、関数の稼働中は、ユーザが画面を触っていなくても、ブラウザがスリープすることが無くなります。
スマートフォンをポケットに入れて走っても、WEBアプリは稼働しつづけ、位置情報を記録します。
以上、スリープさせる、させない問題の対応についてのご説明でした。
これで一通りご説明が済みましたので、次回の記事では、このWEBアプリのための、スクリプト、テンプレート、スプレッドシートのひな形をご紹介します。
←前の記事はこちら
次の記事はこちら⇒
←前の記事
この記事が気に入ったらサポートをしてみませんか?