2009年7月8日

androidで位置情報を取得する

Filed under: Java,android — admin @ 6:34 PM

7/10にHT-03Aの発売が決まってにわかに活気づいてきました。但し、まだまだ日本語文献が少ないですな。特にリファレンスは厳しいな。

■ソースコード

package org.example.locationtest;

import java.util.List;
import android.app.Activity;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.widget.TextView;

public class LocationTest extends Activity implements LocationListener {
    private static final String[] A = {
        "n/a",
        "fine",
        "coarse"
    };
    private static final String[] P = {
        "n/a",
        "low",
        "medium",
        "high"
    };
    private static final String[] S = {
        "out of service",
        "temporarily unavailable",
        "available"
    };
    private LocationManager mgr;
    private TextView output;
    private String best;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
        output = (TextView) findViewById(R.id.output);

        log("Location providers:");
        dumpProviders();

        Criteria criteria = new Criteria();
        best = mgr.getBestProvider(criteria, true);
        log("\nBest Provider is: " + best);

        log("\nLocations (starting with last known):");
        Location location = mgr.getLastKnownLocation(best);
        dumpLocation(location);
    }

    @Override
    protected void onResume(){
    	super.onResume();
    	mgr.requestLocationUpdates(best, 15000, 1, this);
    }
    @Override
    protected void onPause(){
    	super.onPause();
    	mgr.removeUpdates(this);
    }

    public void onLocationChanged(Location location){
    	dumpLocation(location);
    }
    @Override
    public void onProviderDisabled(String provider) {
        log("\nProvider disabled:" + provider);
    }
    @Override
	public void onProviderEnabled(String provider) {
    	log("\nProvider enabled:" + provider);
	}
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        log("\nProvider status changed:" + provider + ", status=" + S[status] + ", extras=" + extras);
    }

    private void log(String string) {
        output.append(string + "\n");
    }
    private void dumpLocation(Location location) {
        if(location == null){
            log("\nLocation[unknown]");
        }
        else{
            log("\n" + location.toString().replace(",", ",\n\t").replace("[", "[\n\t").replace("]", "\n]"));
        }
    }
    private void dumpProviders() {
        List<String> providers = mgr.getAllProviders();
        for (String provider : providers) {
            dumpProvider(provider);
        }
    }
    private void dumpProvider(String provider) {
        LocationProvider info = mgr.getProvider(provider);
        StringBuilder builder = new StringBuilder();
        builder.append("LocationProvider[")
            .append("\n\tname=")
            .append(info.getName())
            .append(",\n\tenabled=")
            .append(mgr.isProviderEnabled(provider))
            .append(",\n\tgetAccuracy=")
            .append(A[info.getAccuracy()])
            .append(",\n\tgetPowerRequirement=")
            .append(P[info.getPowerRequirement()])
            .append(",\n\thasMonetaryCost=")
            .append(info.hasMonetaryCost())
            .append(",\n\trequiresCell=")
            .append(info.requiresCell())
            .append(",\n\trequiresNetwork=")
            .append(info.requiresNetwork())
            .append(",\n\trequiresSatellite=")
            .append(info.requiresSatellite())
            .append(",\n\tsupportsAltitude=")
            .append(info.supportsAltitude())
            .append(",\n\tsupportsBearing=")
            .append(info.supportsBearing())
            .append(",\n\tsupportsSpeed=")
            .append(info.supportsSpeed())
            .append("\n]");
        log(builder.toString());
    }
}

Javaの配列宣言がPHPやJavaScriptと異なっててどうもしっくりこないな。

■解説

@Overrideしているもので、アプリケーションの状態に合わせた挙動の定義をしてる感じですな。今回は、アプリがスタートした時の動作がほとんどなので、結果的にonCreateがメインです。+privateメソッドでクラス内で必要なメソッドを実装。

void org.example.locationtest.LocationTest.onCreate(Bundle savedInstanceState)

super.onCreate(savedInstanceState);

スーパークラスのメソッドをコール。

setContentView(R.layout.main);

androidのView Wigetを使ってActivityの画面を生成する。

mgr = (LocationManager) getSystemService(LOCATION_SERVICE);

LocationManagerオブジェクトを取得し変数に格納。

output = (TextView) findViewById(R.id.output);

Resource IDに基づいてAndroid Viewを探す。

Criteria criteria = new Criteria();

Criteriaオブジェクトの生成。location providerの選択のためにapplicationの尺度を示すらしい。

best = mgr.getBestProvider(criteria, true);

状況に応じた最良のセンサー名をbest変数に格納する。

Location location = mgr.getLastKnownLocation(best);

センサーによっては位置を取得するのに時間がかかるので最後に取得した値を利用する。

void org.example.locationtest.LocationTest.onResume()

アプリがforegroundに復活した時の挙動を定義。

super.onResume();
mgr.requestLocationUpdates(best, 15000, 1, this);

スーパークラスのメソッドをコール。位置情報の定期更新を設定する。

void org.example.locationtest.LocationTest.onPause()

アプリがbackgroundにある時の挙動を定義。

super.onPause();
mgr.removeUpdates(this);

スーパークラスのメソッドをコール。アップデートを休止する(位置情報の更新を無効にする)。

void org.example.locationtest.LocationTest.dumpProviders()

for (String provider : providers) {
    dumpProvider(provider);
}

JDK5.0からできるようになった記法らしい。コロンの右側に配列(もしくはコレクション)を配置しループをぶん回せる。ちなみにこの記法はJavaScriptでは使えない。

void org.example.locationtest.LocationTest.log(String string)

output.append(string + "\n");

引数のstringが出力に追加されるイメージですな。

■画面

こんな風に表示されます。

gpsのデータ

コメントはまだありません »

コメントはまだありません。

この投稿へのコメントの RSS フィード。 TrackBack URL

コメントする