自分がどこにいるのかを知らせたい

最近のスマートフォンには洩れなくGPS受信機が付いていて、
今自分がどこにいるのか、そのあたりに何があるのかが大体分かり、
初めての地でもうろうろすることなく目的地まで案内してくれたりします。
大変便利な反面、常に監視されているようで気持ち悪くもあります。

自分で自分の位置を知るのは普通にできますが、
他人に自分の位置を知らせたいような場面も結構あり、
しかも特定の人にだけに知らせたい時にだけ知らせられるのなら安心感があります。
ということで、持ち歩いているAndroidスマートフォンと
インターネット上に公開しているウェブサーバ(Linux+Apache+PHP)で、
個人的に位置通知システムを試しに作ってみることにしました。

まずはウェブサーバ側の準備です。
以下のような内容の”setlocation.php”スクリプトファイルを
ウェブブラウザからアクセスできるように配置
(ここでは”http://www.test.com/setlocation.php”と仮定)します。

<?
$x=$_GET["x"];
$y=$_GET["y"];
header("HTTP/1.1 200 OK");
$fp=fopen("/tmp/location","w");
fprintf($fp,"%f,%f",$y,$x);
fclose($fp);
?>
<html>
<head>
<title>getlocation</title>
</head>
<body>
getlocation
</body>
</html>

さらに以下のような内容の”map.php”スクリプトファイルを
ウェブブラウザからアクセスできるように配置
(ここでは”http://www.test.com/map.php”と仮定)します。

<?
$fp=fopen("/tmp/location","r");
$pl=fgets($fp);
fclose($fp);
$url="https://www.google.co.jp/maps?q=".$pl."(here)&z=18&hl=ja";
?>
<html>
<head>
<title>link</title>
<?
printf('<meta http-equiv="refresh" content="0;URL='.$url.'">');
?>
</head>
<body>
<h1>link</h1>
<?
printf('<a href="'.$url.'">go</a>');
?>
</body>
</html>

持ち歩いているスマートフォンから定期的に
緯度経度情報を付加して”http://www.test.com/setlocation.php”にアクセスすることで
サーバに位置情報を蓄え、
他人が”http://www.test.com/map.php”(Google Mapsへのリダイレクト)を開くと、
その位置の地図が表示されるということになります。
ただし、地図が表示されるページでリロードしても最新の位置に更新されません。
更新したければ”http://www.test.com/map.php”を新たに開く必要があります。

さて、Androidスマートフォンから位置情報を送るのは
そういうアプリケーションを作って立ち上げておくのが楽です。
ということでEclipse+ADTでアプリケーションを作成します。
通常通りにウィザードでスケルトンを作り、以下のようにファイルの変更等を行い、作成します。
“AndroidManifest.xml”ファイルには””の行の直後に以下の行を追加します。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

“MainActivity.java”ファイルは以下のような感じにします。

package <このアプリケーションのパッケージ名>;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
public class MainActivity extends Activity implements LocationListener{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
	    LocationManager lm =
                    (LocationManager)getSystemService(Context.LOCATION_SERVICE);
	    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, this);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    public void onLocationChanged(Location l) {
        new sendinglocation(this).execute(l);
    }
    @Override
    public void onProviderDisabled(String provider) {
    }
    @Override
    public void onProviderEnabled(String provider) {
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
}

新しいクラスを追加してファイル名を”sendlocation.java”とし、内容は以下のような感じにします。

package <このアプリケーションのパッケージ名>;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.content.Context;
public class sendlocation extends AsyncTask {
    private Activity act;
    public sendinglocation(Activity a) {
        act = a;
    }
    @Override
    protected Object doInBackground(Object... arg0) {
        Location l=(Location)arg0[0];
        String url=
            "http://www.test.com/setlocation.php?x="
            +l.getLongitude()+"&y="+l.getLatitude();
        DefaultHttpClient cl = new DefaultHttpClient();
        HttpGet req = new HttpGet(url);
        HttpResponse res = null;
        try {
            res = cl.execute(req);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            cl.getConnectionManager().shutdown();
        }
        return null;
    }
}

とりあえず動くことを優先して作っているので、
実運用するにはまだまだ足りない部分(余計な部分)はありますが、
応用して面白くすればいいでしょう。
ただし、第3者に位置がばれないように気をつけてください。