一定時間毎に何かをする例

会社の同僚がたまたま持ってた木南さん本に良い例が出てた。

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> 

こんなカンジで出てきます。
Android Javascript
で、次は 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 付けてみたけどそこにさえ到達していない模様。困った。

一気に

盛り込んでるから微妙なのか、と言いつつ時間切れ。