sos の 作業メモ

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

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

Google Play services Location APIを使ったActivityRecognitionを簡単に利用するためのクラスの実装例

I/Oの発表の後に記事を書いていますが、 こちらもちゃんとクラスに仕立てたので載っけときます。

やっていることは Location APIを使った測位クラスと似たようなものです。ちょっとややこしいのは、行動種別データのやりとりで、判定されたものを一旦 IntentServiceで受け取り、さらにBroadcastでこのクラスに投げてもらうところくらいでしょうか。

private class ActivityRecognitionReceiver extends BroadcastReceiver implements ConnectionCallbacks, OnConnectionFailedListener {
    private ActivityRecognitionClient mRecognitionClient = null;
    private boolean mReconnect = false;
    private boolean mRegistered = false;
    private PendingIntent mRecognitionCallback = null;

    ActivityRecognitionReceiver(Context context) {
        mRecognitionClient = new ActivityRecognitionClient(context, this, this);
        Intent intent = new Intent(context, MyRecognitionService.class);
        intent.setAction("jp.hoge.hoge.FROM_GPS_SERVICE");
        mRecognitionCallback = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    void start() {
        if (!mRecognitionClient.isConnected() && !mRecognitionClient.isConnecting()) {
            mReconnect = false;
            if (!mRegistered) {
                mRegistered = true;
                IntentFilter filter = new IntentFilter();
                filter.addAction("jp.hoge.hoge.FROM_MY_RECOGNITION_SERVICE");
                registerReceiver(this, filter);
            }
            mRecognitionClient.connect();
        }
    }

    void stop() {
        mReconnect = false;
        if (mRegistered) {
            unregisterReceiver(this);
            mRegistered = false;
        }
        mRecognitionClient.removeActivityUpdates(mRecognitionCallback);
        mRecognitionClient.disconnect();
    }

    @Override
    public void onConnected(Bundle bundle) {
        // ActivityRecognitionサービスとの接続が完了
        mReconnect = true; // onDisconnected時に再接続を行うようにフラグを立てる
        // 10秒間隔での更新をリクエスト
        mRecognitionClient.requestActivityUpdates(10000l, mRecognitionCallback);
    }

    @Override
    public void onDisconnected() {
        if (mReconnect) {
            start(); // 意図しない切断のため再接続を試みる
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // ActivityRecognitionサービスへの接続に失敗したため、ユーザーへアラート表示等を行う
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent != null){
            // 目的のデータ
            int type = intent.getIntExtra("KEY_DETECTED_ACTIVITY_TYPE", -1); 
        }
    }
}

これも使い方は簡単で、インスタンスを作ってstartで開始、stopで終了。

ActivityRecognitionReceiver activityReceiver = new ActivityRecognitionReceiver(this);
activityReceiver.start(); // 測位開始
activityReceiver.stop(); // 測位終了

こっちが IntentServiceのMyRecognitionService.java。受け取ったデータをそのままBroadcastしてるだけ。

public class MyRecognitionService extends IntentService {
    public MyRecognitionService() {
        super("MyRecognitionService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if ("jp.hoge.hoge.FROM_GPS_SERVICE".equals(intent.getAction()) && ActivityRecognitionResult.hasResult(intent)) {
            DetectedActivity detectedActivity = ActivityRecognitionResult.extractResult(intent).getMostProbableActivity();
            Intent i = new Intent("jp.hoge.hoge.FROM_MY_RECOGNITION_SERVICE");
            i.putExtra("KEY_DETECTED_ACTIVITY_TYPE", detectedActivity.getType());
            sendBroadcast(i);
        }
    }
}

いつのまにかすっかり夏の青空が広がる季節…溶けそうなくらい暑い…