読者です 読者をやめる 読者になる 読者になる

sos の 作業メモ

プログラミングや英会話学習、マイルや旅行、日常生活など。最近はWebFormなASP.NETのお守りがお仕事です。

日々の生活にhappyをプラスする|ハピタス Gポイント

Google Play servicesの新機能 - LocationRequest(fused provider) と Geofence

2013/07/08 追記

クラスの実装例の記事を書きました



Google Play servicesにもいろいろと機能が追加されていますが、 まずはLocationパッケージを調査。 こっち系で飯を喰ってる人間としては、とても気になる機能です。

まずは3つの目玉のうちの Fused Location Providerを使ったLocationRequest と Geofencing 。

LocationRequest

これまで位置情報の取得と言えば、LocationManagerで、GPS かWiFiかを指定して取得するのが普通でしたが、LocationRequestならPriorityに応じて相応しいproviderを使った計測をしてくれます。(provider名はfusedに固定されているようです)

以前ならGPSがとれなくなったらWiFiに切り替えて…といった処理を自前で実装する必要がありましたが、これからはそんな苦労は不要というわけですね。

LocationManagerの方でもそうでしたが、Intervalや最小移動距離、測位を行う期間や終了時刻などの細かい設定もできる優れものです。

Geofence

そしてもうひとつがGeofence。簡単に言えば、任意の場所に任意の大きさの円を書いて、その円の中に入ったときや出たときにIntentを発行できるというもの。PendingIntentでのIntent発行なので、ブラウザやTwitter、メール等を呼び出したりといろいろなことに使えます。

サンプル

最短500ミリ秒間隔で測位。 京都の某所から半径100mの円に入ったり出たときに、このブログを表示するPendingIntentを登録する

public class MainActivity extends Activity
    implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener
    , LocationClient.OnAddGeofencesResultListener 

private LocationClient mLocClient = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setupLoc();
}

@Override
protected void onResume() {
    super.onResume();
    setupLoc();
}

private void setupLoc() {
    if (mLocClient == null) {
        mLocClient = new LocationClient(this, this, this);
        mLocClient.connect();
    }
}

private void requestUpdate() {
    ArrayList<Geofence> fenceList = new ArrayList<Geofence>();
    Geofence geofence = new Geofence.Builder()
            .setRequestId("Fence-1")
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
            .setCircularRegion(34.994913, 135.738927, 100)
            .setExpirationDuration(Geofence.NEVER_EXPIRE)
            .build();
    fenceList.add(geofence);

    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://sos.hatenablog.jp/"));
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    mLocClient.addGeofences(fenceList, pendingIntent, this);

    LocationRequest req = LocationRequest.create();
    req.setFastestInterval(500);
    req.setInterval(500);
    req.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    mLocClient.requestLocationUpdates(req, new LocationListener() {
        @Override
        public void onLocationChanged(Location loc) {
            // 更新された位置情報を使う処理
        }
    });
}

@Override
public void onConnected(Bundle connectionHint) {
    requestUpdate();
}

@Override
public void onDisconnected() {
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}

@Override
public void onAddGeofencesResult(int i, String[] strings) {
    // addGeofencesの結果がやってくる
}

Google Play servicesの利用可否と、接続可否のチェックが少々面倒なのを除けば、そんなに難しい処理ではなさそうですね。