一定時間毎に何かをする例
会社の同僚がたまたま持ってた木南さん本に良い例が出てた。
Handler 使ってます
Handler#postDelayed() 手続きを使って 3 秒毎に Runnable#run() を起動する例。
- Service#onStart() にて Handler#postDelayed() を呼び出し
- Runnable#run() の中でも Haldler#postDelayed() を呼び出し
というナニによって Handler#postDelayed() に渡す時間毎に、な形を取ってます。具体的には onCreate() にて
if (! mRunning) { mHandler.postDelayed(this, TIMER_PERIOD); mRunning = true; }
みたいなカンジで起動。あとは run で以下なカンジでした。
public void run() { Log.i("HelloService", "run "+mCounter); if (! mRunning) { Log.i("HelloService", "run after destroy"); return; } else if (--mCounter <= 0) { Log.i("HelloService", "stop Service id = "+mStartId); stopSelf(mStartId); } else { mHandler.postDelayed(this, TIMER_PERIOD); } }
上記のサンプルは一定の時間毎 (TIMER_PERIOD) 限定された回数ログを出力する例です。
てーコトは
一定時間毎に GPS な座標を取得する事は可能なので、この値を javascript に渡すにはどうすりゃ良いか、を調べりゃ良いのか。
Android 側から javascript へのナニ
とりあえず adamrocker さんのここ (Android と JavaScript を連携させる方法) を参考に色々試してみます。試しに現在地を setCenter() するようなソレを書いてみるか。
まず第一歩てきな地図を表示する実装が以下。
package jp.shuri.yamanetoshi.javascriptsample; import android.app.Activity; import android.os.Bundle; import android.webkit.WebView; public class JavaScriptSample extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WebView webView = new WebView(this); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("file:///android_asset/index.html"); setContentView(webView); } }
assets/index.html が以下。
<html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript"> function initialize() { var latlng = new google.maps.LatLng(26.19,127.67); var myOptions = { zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); } </script> </head> <body onload="initialize()"> <div id="map_canvas" style="width:100%; height:100%"></div> </body> </html>
で、AndroidManifest.xml に以下を追加。
<uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest>
こんなカンジで出てきます。
で、次は GPS で取得したナニを javascript に渡すソレを盛り込めば良いのか。流れてきには
- onCreate() にて
- GPS な Lat Lng 取得して
じゃないな。JavaScript との i/f なクラス側で GPS な Lat Lng 取得して戻せば良いの? なんか賢いヤリ方無いかなぁ。とりあえずコンストラクタでナニしといて Lat と Lng 戻す手続きをでっち上げる方向で以下?
class JsObj { private Context con; Private LocationManager locman; Private Location loc; public JsObj(Context con) { this.con = con; locman = (LocationManager)con.getSystemService(Context.LOCATION_SERVICE); loc = locman.getCurrentLocation("gps"); } public double getLat() { return loc.getLatitude(); } public double getLng() { return loc.getLongtitude(); } }
で、以下なカンジで i/f をナニしといて
JsObj jo = new JsObj(this); wv.addJavascriptInterface(jo, "roid");
javascript 側を以下なカンジにすれば良い?
function initialize() { var latlng = new google.maps.LatLng(roid.getLat(), roid.getLng());
試してみます。
って
盛り込んで動作確認したら以前の挙動のママ。おかしいな、と思ったら assets な html を修正し忘れていました。再度確認してみたらこんどは i/f をナニ、な部分がスルーになってて roid って何だば、って叱られる始末。(とほほほ
しかもその後、原因不明でオチてたんですが、permission が追加になってる模様。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
上は実機で下が emulator らしい。で、盛り込んでみたんですが動かん。onCreate() で breakpoint 付けてみたけどそこにさえ到達していない模様。困った。
一気に
盛り込んでるから微妙なのか、と言いつつ時間切れ。