OpenLayersを無理やり動かす
HTML+JavaScriptに目覚める
単独アプリで地図ビューアを作るには基本的にはDalvikベースだろ、と思っていたけれども、ゆびちずとか見てて(審査を経由しなくて良いから、HTML5に回ったんだそうな)、HTML+JavaScriptも捨てがたいのではないかという思いを持っていました、というか、そこここに転がってる知識が使えるわけですから、これは使った方が良いかも知れない。
あと、HTML, CSS, JavaScriptの各ファイルをassetsに放り込んで
WebView webView = (findViewByIdとかで取ってくる); webView.loadUrl("file:///android_asset/(ファイル名)");
でロードさせる、という変態かも知れない使い方で、単独アプリっぽくなります。
Google Maps v3
Google Maps v3 では、AndroidとかiPhoneとかについては、専用のスクリプトを自動で回してくれます。てことで、HTML, CSS, JavaScript を assets に放り込む方法をとると、キー取得とかandroid.jarとかなく Google Mapsアプリができるはずですが、規約違反の可能性があります。
OpenLayers
問題は、タッチイベントを拾ってくれない点。
調べると、Android添付ブラウザは、タッチイベントは別の名前で拾ってくれます。
http://termat.sakura.ne.jp/javascript/android%E3%81%A7javascript%E3%81%AE%E3%82%BF%E3%83%83%E3%83%81%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F%E3%80%822-android-js/ あたり参照。
addEventHandler()でtouchstart, touchmove, touchendを捕まえればOK。addEventListener()が無ければ無視するようにすれば他のブラウザにも迷惑かけない。
イベントハンドラでは、mousedown, mousemove, mouseupを実行してやれば、万事解決なはずです。OpenLyaersにはMap型はEvents型を持っていて、triggerEventで無理矢理イベントを発生させることができます、この心遣いがありがたい。
ただし、ふつうにtriggerEventを投げても動きませんでした。
evt.xy={...} と evt.button=1 を差し込んで、座標情報は取れてて、かつ左ボタンを押している、と騙す必要があります。
以上をまとめると、つぎのようなかんじになります。
new OpenLayers.Map(...); ... var OLA = { touchstart: function(evt){ evt.xy = {x: evt.pageX, y: evt.pageY}; evt.button = 1; map.events.triggerEvent("mousedown",evt); }, touchmove: function(evt){ evt.xy = {x: evt.pageX, y: evt.pageY}; evt.button = 1; map.events.triggerEvent("mousemove",evt); }, touchend: function(evt){ evt.xy = {x: evt.pageX, y: evt.pageY}; evt.button = 1; map.events.triggerEvent("mouseup",evt); } }; ... var e = map.div; if( e != null && e.addEventListener != null ) { e.addEventListener("touchstart", OLA.touchstart); e.addEventListener("touchmove", OLA.touchmove); e.addEventListener("touchend", OLA.touchend); }
(OLAというハッシュを作っているのは、個人的な趣味でそうやっているものです)