HTML5 と JavaScript を 利 用 した Android ネイティブアプリの 作 成 東 京 理 科 大 学 理 学 部 物 理 学 科 山 本 研 究 室 1210052 五 木 田 隼 人
目 次 0. はじめに 0-1.はじめに 0-2. 各 種 OS について 0-3.クロスプラットフォームツールの 紹 介 1. 開 発 環 境 の 準 備 Android の 場 合 ios の 場 合 Monaca について 2. アプリの 概 要 概 要 スクリーンショット 3. ソースコードとその 解 説 3-1.HTML JavaScript 3-2.CSS 3-2.ソースコードの 解 説 head 部 分 body 部 分 4. おわりに 5. 参 考 文 献 Web 文 献 Web
0. はじめに 0-1.はじめに Android 1 や iphone 2 に 代 表 される スマートフォン はここ 数 年 で 急 速 に 普 及 し 普 及 率 は 50% 近 くにまで 増 えています (2013 年 6 月 総 務 省 データより) 図 スマートフォン タブレット PC の 普 及 率 の 年 代 別 グラフ( 総 務 省 データ) (http://www.itmedia.co.jp/news/articles/1310/04/news128.html より) 依 然 PC が 97%という 高 い 普 及 率 となっていますが タブレットの 普 及 率 も 20% 近 く に 達 し 若 年 層 を 中 心 に スマーフォン や タブレット は 急 速 に 普 及 しています 私 自 身 も 何 か 簡 単 な 調 べ 物 をしたい 暇 つぶしの 利 用 したい と 考 えたとき PC に 代 わって スマートフォン や タブレット などの 端 末 を 使 用 する 頻 度 が 増 えて いることを 実 感 しています これらの 端 末 は Android や ios 3 などのオペレーティングシステム( 以 下 OS とし ます )が 搭 載 されており マウスを 使 用 しない 直 感 的 な 動 作 で 使 用 できるだけでなく 使 用 用 途 に 合 わせて アプリ(アプリケーション) を 導 入 することによって 手 軽 に ゲームを 楽 しんだり 仕 事 を 効 率 化 したりすることができます アプリケーションの 導 入 は 従 来 の PC 4 でも 勿 論 できますが スマーフォン や タブレット において は 各 社 が OS に 合 わせてアプリを 公 開 している ストア というアプリケーションを 利 1 Android は Google.Inc の 商 標 です 2 iphone は Apple.Inc の 商 標 です 3 ios は Apple.Inc の 商 標 です 4 ここでは Windows 7 以 前 の PC を 指 しています (Windows 8 からストアがインストー ルされています )
用 して 簡 単 に 入 手 することができるため アプリを 入 れる ということが 一 般 的 にな っています アプリを 入 れる ということが 一 般 的 になれば 当 然 アプリケーション を 提 供 する 側 も 増 えます かくして 私 も 卒 業 作 品 に Androidと iphone 両 対 応 のアプリケーションを 作 りたいと 考 えました しかし スマートフォン 向 けのアプリを 開 発 する 場 合 Android アプリの 場 合 は Java iphone アプリの 場 合 は Objective-C という 言 語 で 開 発 するのが 一 般 的 で プログラミング 初 心 者 である 私 が 複 数 言 語 を 取 得 し アプリを 開 発 するまでのレベル になるには 期 間 的 に 無 理 があると 考 えました そこで HTML や JavaScript などの Web 技 術 を 使 って 複 数 OS に 対 応 したクロスプラットフォーム 5 のアプリを 作 成 す ることにしました アプリと 一 口 にいっても 様 々なものがあります メール マップ ゲーム 仕 事 効 率 化 etc その 中 でも 私 はスマートフォンの 特 徴 でもある GPS を 使 ったマップアプ リを 作 成 したいと 考 えました 今 回 Web アプリではなく Web 技 術 でネイティブアプリを 作 るために Phone Gap(Cordova) 6 というフレームワークを 利 用 して 開 発 を 行 います 参 考 にできる 書 籍 も 少 ない 上 に 私 自 身 がプログラミングに 不 慣 れであることで 薄 い 内 容 になって いますが どうぞご 了 承 下 さい 0-2. 各 種 OS について 現 在 スマートフォンに 搭 載 されている OS は Android と ios が 有 名 ですが 開 発 中 で 市 場 に 投 入 されていないものも 含 めると 多 くの OS が 存 在 します 簡 単 に 有 名 な OS を 紹 介 します Android Google によってスマートフォンやタブレットなどの 携 帯 端 末 を 主 なターゲット として 開 発 されたプラットフォーム OS であり 2013 年 9 月 時 世 界 日 本 に おいてスマートフォン OS のシェアは1 位 オープンソースであり Apache v2 ライセンス 7 で 配 布 されています 2014 年 1 月 現 在 Android 4.4 KitKat が 最 新 版 アプリは Java と Google の 提 供 するライブラリィを 用 いて 開 発 されます Android Developer: http://developer.android.com/index.html 5 異 なるプラットフォーム(OS 等 )で 同 じ 仕 様 のものを 動 かすことのできるプログラムの ことです 6 0-3.クロスプラットフォームツールの 紹 介 を 参 照 してください 7 Apache ソフトウェア 財 団 によるソフトウェア 向 けライセンス 規 定 ソースコードはオー プンソースだけでなくクローズドソースの 開 発 にも 使 用 できます
ios アップル 社 が 開 発 提 供 する OS アプリの 開 発 に 基 本 的 には Objective-C を 使 用 します 一 部 はオープンソースですが 基 本 的 にはプロプライエタリソフトウ ェア 8 となっています Windows Phone マイクロソフト 社 が 開 発 提 供 しているモバイル OS 2014 年 1 月 現 在 の 最 新 バージョンが Windows Phone 8 日 本 では1 機 種 だけ 発 売 されています クロー ズドソースでアプリ 開 発 は C, C#, C++で 行 われます Firefox OS ブラウザで 有 名 な Firefox の Mozilla が 提 供 する OS 一 部 は Android を 母 体 と していますが アプリの 開 発 言 語 は C++, HTML, JavaScript, CSS となっていま す 日 本 ではまだ 市 場 に 投 入 されていませんが ブラジル スペインなどでは 既 に 発 売 されています オープンソースであり Web 技 術 を 用 いたアプリ 開 発 が 可 能 な 点 が 特 徴 的 です Firefox OS : http://www.mozilla.jp/firefoxos/ BrackBerry OS ブラックベリー 社 が 開 発 している BrackBerry シリーズのスマートフォン 向 け の OS 2014 年 1 月 現 在 最 新 バージョンは 7.1 クローズドソースで アプリ 開 発 には 主 に Java が 使 用 されています Tizen(タイゼン) LiMo Foundation, Linux Foundation, インテル 社 が 主 導 する Tizen プロジェク トの OS 日 本 企 業 としては NEC NTT ドコモなどが 参 加 しています OS 自 体 はオープンソースで 配 布 され アプリの 開 発 には HTML, JavaScript, C, C++など を 使 用 します 2014 年 1 月 現 在 商 用 として 発 売 されていません Tizen: https://www.tizen.org/ja 8 ソフトウェアの 配 布 者 が 利 用 者 の 持 つ 権 利 を 制 限 的 にすることで 自 身 の 利 益 を 保 持 しよ うとするソフトウェアを 指 します
Fire OS Amazon.com が 販 売 するタブレット Kindle Fire, Kindle Fire HD, Kindle Fire HDX などに 搭 載 されている OS Android がベースになっており Kindle アプリ の 開 発 環 境 言 語 は 基 本 的 に Android と 同 様 です 紹 介 しきれないほど 数 多 くの OS が 存 在 しており 1つ1つに 対 応 するアプリを 開 発 することは 個 人 では 困 難 になります さらには HTML, JavaScript などで 開 発 したい と 考 えた 場 合 OS 自 体 がこれらの 言 語 でのアプリ 開 発 に 対 応 していなければ 開 発 する ことはできず 対 応 する 言 語 の 取 得 は 必 須 となります それを 解 決 するために 登 場 し たのが クロスプラットフォームツールです 0-3.クロスプラットフォームツールの 紹 介 それぞれのツールがどのようなものか 簡 単 に 説 明 します Phone Gap(Cordova) まず 名 前 についてですが Cordova とはオープンソースの 製 品 名 で Phone Gap とは Adobe 社 が Cordova を 配 布 するときの 名 前 です (ここからは Phone Gap で 統 一 します )Phone Gap を 利 用 すれば アプリ 内 にブラウザの 機 能 を 埋 め 込 むことができるため HTML, JavaScript, CSS などをそのまま 使 用 してネイティ ブアプリの 開 発 することができます Phone Gap で 開 発 する 問 題 点 として アプ リの 動 作 が Java(Android の 場 合 )で 開 発 した 場 合 より 遅 くなる 点 があります この 辺 りは Web アプリの 動 作 がネイティブアプリに 比 べて 遅 くなることと 同 じ 理 由 です 今 回 はこちらを 利 用 して 開 発 しました 配 布 先 :http://phonegap.com/install/ 図 Phone Gap
Unity 3D コンテンツも 作 成 できるゲーム 開 発 プラットフォームで Web や ios, Android だけでなく Windows Mac Wii PlayStation Xbox 360 に 対 応 して 書 き 出 しすることができます JavaScript でコーディングして プラットフォー ムに 対 応 してコンパイルしてくれるツールです 基 本 的 にはゲームを 作 るための ツールです 配 布 先 :http://japan.unity3d.com/unity/ 図 Unity Titanium Appcelerator 社 が 開 発 提 供 しているスマートフォンアプリの 開 発 環 境 です JavaScript でコーディングして OS に 合 わせて Titanium がコンパイルします コンパイルするという 点 が PhoneGap との 大 きな 違 いです 配 布 先 :http://www.appcelerator.com/platform/appcelerator-platform/ 図 Titanium
1. 開 発 環 境 の 準 備 通 常 Phone Gap を 使 用 する 場 合 以 下 のツールやソフトウェアをインストールしな ければなりません Android の 場 合 Android SDK Eclipse Classic ADT Plugin Phone Gap 設 定 方 法 : http://docs.phonegap.com/jp/2.2.0/guide_getting-started_android_index.md.ht ml#getting%20started%20with%20android ios の 場 合 XCode Phone Gap 当 然 インストールするだけでなく PATH などの 様 々な 設 定 が 必 要 になります 通 常 これだけの 準 備 が 必 要 ですが Monaca という PC のブラウザ 上 で Phone Gap を 使 ったアプリを 作 成 できる 環 境 がありますので そちらを 利 用 します Monaca について HTML5 と JavaScript を 使 って Android, ios, Windows 8 のネイティブアプ リを 同 時 開 発 することができるクラウドサービスで 統 合 開 発 環 境 とデバッカー など 開 発 に 必 要 なものが 全 て 揃 っています アプリを 利 用 して 実 機 上 (Android などの 端 末 )でデバックすることもできます 会 員 登 録 が 必 要 でプロジェクトの 数 などで 異 なりますが 基 本 的 に 無 料 です 使 用 方 法 については 割 愛 しますが Eclipse などの 一 般 的 な 統 合 開 発 環 境 とほぼ 同 様 です 日 本 語 に 対 応 しており モバイルアプリ 開 発 に 特 化 しているため 非 常 に 扱 いやすくクラウドであることを 感 じさせない 程 利 用 し 易 いと 感 じました Monaca:http://monaca.mobi/ja/
図 Monaca 図 Monaca の 使 用 画 面 図 ライブプレビュー 画 面 ( 搭 載 されているエミュレータ)
図 実 機 でデバックを 行 うためのアプリ 実 際 の 画 面
2. アプリの 概 要 概 要 HTML5, JavaScript, CSS, jquery 9, Phone Gap を 用 い 端 末 の GPS を 利 用 し て 位 置 情 報 を 追 跡 するアプリです 追 跡 開 始 停 止 軌 跡 の 削 除 軌 跡 の 保 存 保 存 した 軌 跡 の 呼 び 出 し のボタンを 備 え 自 分 が 移 動 した 軌 跡 を 表 示 す るだけでなく 軌 跡 の 情 報 を LocalStorage に 保 存 し 復 元 することもできます ま た Monaca に 標 準 装 備 されている Phone Gap のテンプレートにもリンクしてい ます Phone Gap を 利 用 してアクセスできる 端 末 内 の 機 能 (GPS バイブレーシ ョン 加 速 器 など)を 体 感 できるものになっています 図 Phone Gap のテンプレート 9 JavaScript をより 容 易 に 記 述 するために 設 計 されたウェブブラウザ 用 の 軽 量 な JavaScript ライブラリィです
スクリーンショット 図 アイコン 画 面 図 起 動 中 画 面 起 動 後 画 面
図 追 跡 開 始 追 跡 停 止 画 面 図 削 除 画 面 削 除 後
図 保 存 画 面 保 存 後 図 呼 び 出 し 呼 び 出 し 後
3. ソースコードとその 解 説 3-1.HTML JavaScript 1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" /> 6 <script src="jquery-1.8.2.min.js" type="text/javascript" ></script> 7 <script src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=true" type="text/javascript" ></script> 8 <link rel="stylesheet" type="text/css" href="css.css"> 9 <title>trace Your Position</title> 10 </head> 11 12 <body> 13 <div id="map" ></div> 14 <ul> 15 <li id="current" class="tool"></li> 16 <li id="tracking" class="tool"></li> 17 <li id="delete" class="tool"></li> 18 <li id="save" class="tool"></li> 19 <li id="load" class="tool"></li> 20 </ul> 21 22 <script type="text/javascript"> 23 $(function() { 24 var map, marker, poly, watchid; 25 var istracking = false; 26 27 // 地 図 の 作 成 28 createmap(); 29 getcurrentposition(); 30
31 //GPS の 設 定 32 var geooptions = { 33 enablehighaccuracy: true, 34 timeout: 60000, 35 maximumage: 0 36 }; 37 38 // 継 続 的 な 位 置 の 取 得 の 開 始 39 function startpositiontracking(){ 40 watchid = navigator.geolocation.watchposition(updatemap, null, geooptions); 41 istracking = true; 42 } 43 44 // 継 続 的 な 位 置 の 取 得 の 停 止 45 function stoppositiontracking(){ 46 navigator.geolocation.clearwatch(watchid); 47 istracking = false; 48 } 49 50 // 位 置 の 取 得 51 function getcurrentposition(){ 52 navigator.geolocation.getcurrentposition(updatemap, null, geooptions); 53 } 54 55 // 地 図 の 更 新 56 function updatemap(position){ 57 var latlng = new google.maps.latlng(position.coords.latitude, position.coords.longitude); 58 map.setcenter(latlng); 59 marker.setposition(latlng); 60 poly.getpath().push(latlng); 61 } 62 63 // 地 図 の 作 成 64 function createmap(){ 65 var mapoptions = {
66 zoom: 15, 67 center: new google.maps.latlng(35.696802, 139.814136), 68 maptypeid: google.maps.maptypeid.roadmap 69 }; 70 map = new google.maps.map($('#map')[0], mapoptions); 71 72 var image = new google.maps.markerimage( 73 'img/marker.png', null, null, 74 new google.maps.point( 8, 8 ), 75 new google.maps.size( 17, 17 ) 76 ); 77 marker = new google.maps.marker({ 78 position: new google.maps.latlng(35.696802, 139.814136), 79 map: map, 80 icon: image, 81 82 optimized: false, 83 title: 'marker' 84 }); 85 86 var polylineoptions = { 87 strokeweight: 3, 88 strokecolor: '#4682B4', 89 strokeopacity: 0.8 90 }; 91 poly = new google.maps.polyline(polylineoptions); 92 poly.setmap(map); 93 } 94 95 // 軌 跡 の 削 除 96 function deletepath() { 97 var path = poly.getpath(); 98 while (path.getlength()) { 99 path.pop(); 100 } 101 }
102 103 // 軌 跡 の 保 存 104 function savepath() { 105 var path = poly.getpath(); 106 for (var i=0; i<path.getlength(); i++) { 107 localstorage[i] = path.getat(i).tostring(); 108 } 109 } 110 111 // 軌 跡 の 復 元 112 function loadpath() { 113 for(var i=0; i<localstorage.length; i++){ 114 var latlng = localstorage[i].replace(/\( \)/g,'').split(','); 115 poly.getpath().push(new google.maps.latlng(latlng[0], latlng[1])); 116 } 117 } 118 119 // 監 視 開 始 ボタンのイベント 120 $('#current').bind('click', function() { 121 istracking = true; 122 startpositiontracking(); 123 $('#current').hide(); 124 $('#tracking').show(); 125 $('#delete').addclass('disabled'); 126 $('#save').addclass('disabled'); 127 $('#load').addclass('disabled'); 128 $('div.gmnoprint[title="marker"]').addclass('pulse'); 129 }); 130 131 // 監 視 停 止 ボタンのイベント 132 $('#tracking').bind('click', function() { 133 istracking = false; 134 stoppositiontracking(); 135 $('#current').show(); 136 $('#tracking').hide(); 137 $('#delete').removeclass('disabled');
138 $('#save').removeclass('disabled'); 139 $('#load').removeclass('disabled'); 140 $('div.gmnoprint[title="marker"]').removeclass('pulse'); 141 }); 142 143 // 消 去 ボタンのイベント 144 $('#delete').bind('click', function() { 145 if(!istracking){ 146 if(confirm(' 消 去 しますか?')){ 147 deletepath(); 148 } 149 } 150 }); 151 152 // 保 存 ボタンのイベント 153 $('#save').bind('click', function() { 154 if(!istracking){ 155 if(confirm(' 保 存 しますか?')){ 156 localstorage.clear(); 157 savepath(); 158 } 159 } 160 }); 161 162 // 復 元 ボタンのイベント 163 $('#load').bind('click', function() { 164 if(!istracking){ 165 if(confirm(' 復 元 しますか?')){ 166 deletepath(); 167 loadpath(); 168 } 169 } 170 }); 171 }); 172 </script> 173
174 </body> 175 </html> 3-2.CSS 1 @charset "utf-8"; 2 3 * { 4 margin: 0px; 5 padding: 0px; 6 } 7 8 body { 9 padding: 9px; 10 } 11 12 #map { 13 width:300px; 14 height:280px; 15 border: solid #CCC 1px; 16 } 17 18 ul{ 19 height: 60px; 20 } 21 22 li { 23 float: left; 24 margin: 4px; 25 width: 50px; 26 height: 50px; 27 border: 1px solid #ccc; 28 border-radius: 5px; 29 list-style-type: none; 30 } 31
32 #current { 33 background-image:url("img/icon_current.png"); 34 } 35 36 #tracking { 37 background-image:url("img/icon_tracking.png"); 38 display: none; 39 } 40 41 #delete { 42 background-image:url("img/icon_eraser.png"); 43 } 44 45 #save { 46 background-image:url("img/icon_save.png"); 47 } 48 49 #load { 50 background-image:url("img/icon_load.png"); 51 } 52 53.disabled { 54 background-color: #ccc; 55 } 56 57 @-webkit-keyframes pulsate { 58 from { 59 -webkit-transform: scale(2.0); 60 opacity: 1.0; 61 } 62 to { 63 -webkit-transform: scale(4.0); 64 opacity: 0; 65 } 66 } 67
68 div.gmnoprint[title="marker"] img { 69 display:none; 70 } 71 72.pulse { 73 -webkit-animation: pulsate 1.5s ease-in-out infinite; 74 border: 1pt solid #4682B4; 75 border-radius: 100px; 76 background-color: rgba(0,100,255, 0.1); 77 } 3-3.ソースコードの 解 説 1 <!DOCTYPE HTML> HTML5 で 記 述 することを 宣 言 します head 部 分 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" /> 6 <script src="jquery-1.8.2.min.js" type="text/javascript" ></script> 7 <script src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=true" type="text/javascript" ></script> 8 <link rel="stylesheet" type="text/css" href="css.css"> 9 <title>trace Your Position</title> 10 </head> Google Maps API JavaScript, 関 連 ファイルとのリンクを 行 います
body 部 分 13 <div id="map" ></div> 14 <ul> 15 <li id="current" class="tool"></li> 16 <li id="tracking" class="tool"></li> 17 <li id="delete" class="tool"></li> 18 <li id="save" class="tool"></li> 19 <li id="load" class="tool"></li> 20 </ul> ユーザーインターフェース 部 分 を HTML で 記 述 しています 13 行 目 の div タグ 内 がマッ プの 部 分 に 相 当 します ul 要 素 は 上 (アプリ 内 では 左 )から 順 に 追 跡 開 始 停 止 軌 跡 の 削 除 軌 跡 の 保 存 保 存 した 軌 跡 の 呼 び 出 し のボタンに 相 当 します 図 アプリの 画 面 とボタン 配 置 12 #map { 13 width:300px; 14 height:280px; 15 border: solid #CCC 1px; 16 } CSS で 表 示 するマップの 大 きさを 指 定 します
18 ul{ 19 height: 60px; 20 } 21 22 li { 23 float: left; 24 margin: 4px; 25 width: 50px; 26 height: 50px; 27 border: 1px solid #ccc; 28 border-radius: 5px; 29 list-style-type: none; 30 } CSS で ul 要 素 が 横 に 並 ぶように 設 定 しておきます 32 #current { 33 background-image:url("img/icon_current.png"); 34 } 35 36 #tracking { 37 background-image:url("img/icon_tracking.png"); 38 display: none; 39 } 40 41 #delete { 42 background-image:url("img/icon_eraser.png"); 43 } 44 45 #save { 46 background-image:url("img/icon_save.png"); 47 } 48 49 #load { 50 background-image:url("img/icon_load.png"); 51 } 52
53.disabled { 54 background-color: #ccc; 55 } 追 跡 開 始 停 止 軌 跡 の 削 除 軌 跡 の 保 存 保 存 した 軌 跡 の 呼 び 出 し のボタ ンを CSS で 設 定 します 最 後 の disabled によって 現 在 位 置 取 得 中 に 軌 跡 の 削 除 軌 跡 の 保 存 保 存 した 軌 跡 の 呼 び 出 し のボタンが 使 用 できないことを 表 すため 背 景 色 を 変 更 しています 図 ボタンの 色 の 変 更 24 var map, marker, poly, watchid; 使 う 変 数 を 宣 言 します 25 var istracking = false; istracking は 現 在 位 置 情 報 を 取 得 しているかを 判 定 するものです 初 期 値 は 停 止 状 態 にするため false としています 27 // 地 図 の 作 成 28 createmap(); 29 getcurrentposition(); createmap は 実 際 に 地 図 を 作 成 する 関 数 です getcurrentposition は 現 在 位 置 を 取 得 し て 地 図 を 更 新 するための 関 数 です これらにより 地 図 を 初 期 化 します
31 //GPS の 設 定 32 var geooptions = { 33 enablehighaccuracy: true, 34 timeout: 60000, 35 maximumage: 0 36 }; geooption は 現 在 位 置 を 取 得 するオプションです 60 秒 でタイムアウトするように 設 定 しています 38 // 継 続 的 な 位 置 の 取 得 の 開 始 39 function startpositiontracking(){ 40 watchid = navigator.geolocation.watchposition(updatemap, null, geooptions); 41 istracking = true; 42 } 現 在 位 置 の 取 得 するための 関 数 です この 関 数 が 実 行 されると watchid に 取 得 開 始 時 に 返 される ID を 格 納 し istracking を ture で 更 新 します また コールバック 関 数 とし て updatemap が 実 行 されて 地 図 が 更 新 されます 44 // 継 続 的 な 位 置 の 取 得 の 停 止 45 function stoppositiontracking(){ 46 navigator.geolocation.clearwatch(watchid); 47 istracking = false; 48 } 現 在 位 置 の 取 得 を 停 止 する 関 数 です 最 後 に 取 得 した watchid をもとに 停 止 し istracking 関 数 を false で 更 新 します 50 // 位 置 の 取 得 51 function getcurrentposition(){ 52 navigator.geolocation.getcurrentposition(updatemap, null, geooptions); 53 } この 関 数 によって 現 在 位 置 を 一 度 だけ 取 得 し コールバック 関 数 として updatemap を 実 行 し 現 在 位 置 に 地 図 を 更 新 します
55 // 地 図 の 更 新 56 function updatemap(position){ 57 var latlng = new google.maps.latlng(position.coords.latitude, position.coords.longitude); 58 map.setcenter(latlng); 59 marker.setposition(latlng); 60 poly.getpath().push(latlng); 61 } 地 図 の 更 新 を 実 行 する 部 分 です 引 数 として 渡 された 位 置 情 報 をもとに 画 面 に 表 示 され ている 地 図 の 中 心 とマーカーの 位 置 を 更 新 します poly の path に GPS で 取 得 した latlng ( 緯 度 軽 度 の 値 )を 配 列 として 格 納 して 軌 跡 を 描 きます 63 // 地 図 の 作 成 64 function createmap(){ 65 var mapoptions = { 66 zoom: 15, 67 center: new google.maps.latlng(35.696802, 139.814136), 68 maptypeid: google.maps.maptypeid.roadmap 69 }; 70 map = new google.maps.map($('#map')[0], mapoptions); 71 72 var image = new google.maps.markerimage( 73 'img/marker.png', null, null, 74 new google.maps.point( 8, 8 ), 75 new google.maps.size( 17, 17 ) 76 ); 77 marker = new google.maps.marker({ 78 position: new google.maps.latlng(35.696802, 139.814136), 79 map: map, 80 icon: image, 81 82 optimized: false, 83 title: 'marker' 84 }); 85 86 var polylineoptions = {
87 strokeweight: 3, 88 strokecolor: '#4682B4', 89 strokeopacity: 0.8 90 }; 91 poly = new google.maps.polyline(polylineoptions); 92 poly.setmap(map); 93 } 実 際 に 地 図 を 作 成 する 部 分 です 軌 跡 を 初 期 化 するために 各 種 プロパティを 持 った polylineoptions を 作 成 しています strokeweight は 軌 跡 の 線 幅 strokecolor は 軌 跡 の 色 strokeopacity は 軌 跡 の 透 明 度 を 指 定 しています こちらの 詳 しい 説 明 は Web サイトを 参 照 してください URL:http://www.rs.kagu.tus.ac.jp/yamalab/2013/gokita/map1.html 57 @-webkit-keyframes pulsate { 58 from { 59 -webkit-transform: scale(2.0); 60 opacity: 1.0; 61 } 62 to { 63 -webkit-transform: scale(4.0); 64 opacity: 0; 65 } 66 } 67 68 div.gmnoprint[title="marker"] img { 69 display:none; 70 } 71 72.pulse { 73 -webkit-animation: pulsate 1.5s ease-in-out infinite; 74 border: 1pt solid #4682B4; 75 border-radius: 100px; 76 background-color: rgba(0,100,255, 0.1); 77 }
marker.png をただ 表 示 するだけでなく CSS でマーカー 周 りを 波 紋 が 広 がるようにアニ メーションを 付 けています 図 波 紋 が 広 がるアニメーション 95 // 軌 跡 の 削 除 96 function deletepath() { 97 var path = poly.getpath(); 98 while (path.getlength()) { 99 path.pop(); 100 } 101 } 軌 跡 を 削 除 するための 関 数 です 消 しゴムボタンを 押 すと 実 行 され poly に 格 納 されて いる 位 置 情 報 の 要 素 を 削 除 します 103 // 軌 跡 の 保 存 104 function savepath() { 105 var path = poly.getpath(); 106 for (var i=0; i<path.getlength(); i++) { 107 localstorage[i] = path.getat(i).tostring(); 108 } 109 } 位 置 情 報 の 軌 跡 を LocalStorage に 保 存 する 関 数 です 保 存 ボタンを 押 すと 実 行 され poly に 格 納 されている 位 置 情 報 を 取 り 出 し 文 字 列 として 保 存 します
111 // 軌 跡 の 復 元 112 function loadpath() { 113 for(var i=0; i<localstorage.length; i++){ 114 var latlng = localstorage[i].replace(/\( \)/g,'').split(','); 115 poly.getpath().push(new google.maps.latlng(latlng[0], latlng[1])); 116 } 117 } LocalStorage に 保 存 した 位 置 情 報 の 軌 跡 を 復 元 するための 関 数 です 復 元 ボタンを 押 す と 実 行 され ストレージのデータを poly に 格 納 し 保 存 した 軌 跡 を 表 示 します 119 // 監 視 開 始 ボタンのイベント 120 $('#current').bind('click', function() { 121 istracking = true; 122 startpositiontracking(); 123 $('#current').hide(); 124 $('#tracking').show(); 125 $('#delete').addclass('disabled'); 126 $('#save').addclass('disabled'); 127 $('#load').addclass('disabled'); 128 $('div.gmnoprint[title="marker"]').addclass('pulse'); 129 }); 130 131 // 監 視 停 止 ボタンのイベント 132 $('#tracking').bind('click', function() { 133 istracking = false; 134 stoppositiontracking(); 135 $('#current').show(); 136 $('#tracking').hide(); 137 $('#delete').removeclass('disabled'); 138 $('#save').removeclass('disabled'); 139 $('#load').removeclass('disabled'); 140 $('div.gmnoprint[title="marker"]').removeclass('pulse'); 141 }); 追 跡 開 始 停 止 ボタンのイベント 動 作 を 記 述 しています 前 述 の 関 数 が 実 行 される ように 設 定 されています
143 // 消 去 ボタンのイベント 144 $('#delete').bind('click', function() { 145 if(!istracking){ 146 if(confirm(' 消 去 しますか?')){ 147 deletepath(); 148 } 149 } 150 }); 軌 跡 の 削 除 ボタンを 押 すと delete 関 数 が 実 行 されるように 設 定 されています 図 消 しゴムボタンを 押 した 際 の 画 面 152 // 保 存 ボタンのイベント 153 $('#save').bind('click', function() { 154 if(!istracking){ 155 if(confirm(' 保 存 しますか?')){ 156 localstorage.clear(); 157 savepath(); 158 } 159 } 160 }); 161
162 // 復 元 ボタンのイベント 163 $('#load').bind('click', function() { 164 if(!istracking){ 165 if(confirm(' 復 元 しますか?')){ 166 deletepath(); 167 loadpath(); 168 } 169 } 170 }); 171 }); 軌 跡 の 保 存 保 存 した 軌 跡 の 呼 び 出 し ボタンを 押 した 際 のイベントを 記 述 してい ます それぞれ 前 述 した 関 数 を 実 行 するように 設 定 しています 図 それぞれのボタンを 押 した 際 の 画 面
4. おわりに HTML5 と JavaScript を 使 ってネイティブアプリを 作 成 することは 一 般 的 になりつ つありますが 動 作 が 遅 いことやバックグラウンドアプリの 作 成 に 適 さないことなど 様 々な 問 題 が 残 っています 2014 年 1 月 現 在 スマートフォンを 始 めとする 携 帯 端 末 は 一 昔 前 のパソコン 程 のスペックを 持 つ 程 までになっており 動 作 が 遅 い 点 は 解 決 さ れていくと 思 われます また バックグラウンドアプリに 適 さないという 問 題 は 今 回 用 いた Phone Gap というツールがブラウザの 様 な 機 能 を 利 用 して HTML5 と JavaScript を 動 かしている 点 に 依 る 部 分 が 大 きいため 0-3 項 で 紹 介 した Unity や Titanium のように JavaScript をコンパイルしてネイティブアプリ 化 するツールを 用 いることで 解 決 することは 可 能 です 以 上 のことからも これから 益 々HTML5 や JavaScript などの Web 技 術 を 使 ったネイティブアプリが 増 えていくと 思 います プログラミングの 知 識 は 全 くなく 結 果 としてお 粗 末 なアプリを 作 り 上 げて 終 わっ てしまいましたが まだ 殆 ど 書 籍 化 もされていない 最 新 の 技 術 に 触 れることができた こと 何 よりプログラミングだけでなく PC 関 連 のものに 対 してアレルギーが 全 くなく なったことが 非 常 に 有 益 でした 一 年 間 という 短 い 期 間 でしたが 山 本 教 授 研 究 室 のメンバー( 海 江 田 さん 小 池 君 佐 藤 さん 鈴 木 君 )にこの 場 を 借 りて 御 礼 させて 頂 きます ありがとうございました 作 成 したアプリはサイトに 貼 ってありますので 自 由 にダウロードしてください 使 用 する 際 は GPS へのアクセスを 許 可 してください ダウンロード 後 はじめての Monaca アプリ というアプリでインストールされてしまう 場 合 がありますが 起 動 す るともとに 戻 るはずです ( 初 期 値 がそうなっていたため) 図 GPS の 許 可 (タップして 許 可 ) ダウンロード:http://www.rs.kagu.tus.ac.jp/yamalab/2013/gokita/map2.html
5. 参 考 文 献 Web 文 献 1. HTML5 と JavaScript による iphone / Android 両 対 応 アプリ 開 発 ガイド( 翔 泳 社 ) 2. ゼロからわかる JavaScript 超 入 門 楽 しいプログラミング( 技 術 評 論 社 ) 3. はじめての Android アプリ 作 成 HTML5 入 門 ( 日 経 BP 社 ) Web 1. スマートフォン タブレット PC の 普 及 率 の 年 代 別 グラフ http://www.itmedia.co.jp/news/articles/1310/04/news128.html 端 末 の 普 及 のデータを 拝 借 しました 2. Android Developer http://developer.android.com/index.html アプリ 開 発 全 般 で 参 考 にさせて 頂 きました 3. Phone Gap Fan http://phonegap-fan.com/ PhoneGap のインストールを 始 めとして 使 用 方 法 等 で 参 考 にさせて 頂 きま した 4. Unity 関 連 の 記 事 http://www.atmarkit.co.jp/ait/articles/1204/04/news112.html 5. Titanium について http://gihyo.jp/dev/serial/01/titanium/0001 6. Phone Gap の API リファレンス http://docs.phonegap.com/jp/2.2.0/index.html 7. Monaca http://monaca.mobi/ja/