techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

Google Nearby Messages APIを使ってみる〜実際使ってみた編〜

前回の記事でNearby Messages APIのセットアップまでを紹介した。
blog.techium.jp

今回は実際にAndroid端末でメッセージの送受信を確認する。

動作確認に使用した端末はNexus 5 、Nexus 5x、全てのコードはActivityに実装した。

ユーザーの同意を得る

Nearby Messages APIはBluetoothや他のデバイスを使用し、近くのデバイスと通信するため電池を大量に消費する可能性がある。
このため、ユーザーがNearby Messages APIを使用するとき確認ダイアログを表示する。
ユーザーが同意して、初めてNearby Messages APIが使用可能となる。
enableAutoManage)を使用することで、簡単に確認ダイアログを表示することができる。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Nearby.MESSAGES_API)
                .addConnectionCallbacks(connectionCallbacks)
                .enableAutoManage(this, mConnectionFailedListener)
                .build();
    }

f:id:forestsoftjpdev:20160621004414p:plain:w300

エラーハンドリング

Nearby Messages APIへの接続に失敗した場合、onConnectionFailedがコールされる。
解決可能なエラーの場合は、startResolutionForResultを呼び出し、結果をonActivityResultで受け、再度接続を試みる。

  private GoogleApiClient.OnConnectionFailedListener mConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() {
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
            if (connectionResult.hasResolution()) {
                try {
                    connectionResult.startResolutionForResult(MainActivity.this, REQUEST_RESOLVE_ERROR);
                } catch (IntentSender.SendIntentException e) {
                    e.printStackTrace();
                }
            } else {
                Log.e(TAG, "GoogleApiClient connection failed");
            }
        }
    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == REQUEST_RESOLVE_ERROR) {
            if (resultCode == RESULT_OK) {
                mGoogleApiClient.connect();
            } else {
                Log.e(TAG, "GoogleApiClient connection failed. Unable to resolve.");
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

PublishとSubscribe

Nearby Messages APIはサイズの小さいメッセージをやり取りできるPublish-SubscribeAPIである。
Publishされたメッセージは近くにいるどの端末でも受診することが可能である。

端末がPublish、Subscribe中はNearby Messages APIを使用中であることをNotificationを使用してユーザーに知らせる。
Notificationから、Nearbyの停止や設定画面への遷移、Nearbyの無効化が可能である。

f:id:forestsoftjpdev:20160621021532p:plain:w300

メッセージの送受信

Nearby Messages APIは、バッテリーへの影響を考慮し、アプリケーションがフォアグラウンド状態の時のみ使用するべきである。

メッセージの送信にはNearby.Messages.publish()メソッドを、受信にはNearby.Messages.subscribe()メソッドを使用する。
受信したメッセージはMessageListenerインターフェースを通じてハンドリングする。

publish、subscribeはGoogleApiClientに接続後のみ行える。
接続完了のonConnectedがコールされたタイミングで開始するのがベストなタイミングだ。
また、onStop時にunSubscribeまたは、unPublishをコールしなければならない。

メッセージのPublish

  • メッセージはbyte配列の形で送信する
  • 必要があれば、100KBまでのデータ送受信が可能であるが、速度重視でサイズは3KB以下にするべきである
  • Nearby Messages APIはビデオや写真などを送信する用に作られてはいない

メッセージのSubscribe

  • サブスクライブはアクティブなインターネット接続が存在しないと失敗する
    @Override
    public void onConnected(Bundle connectionHint) {
        // メッセージの受信登録開始
        subscribe();
    }

    @Override
    public void onStop() {
        unPublish();
        unSubscribe();

        super.onStop();
    }

    private void publish(String message) {
        Log.i(TAG, "Publishing message: " + message);
        unPublish();
        mActiveMessage = new Message(message.getBytes());
        Nearby.Messages.publish(mGoogleApiClient, mActiveMessage);
        mArrayAdapter.add(message);
    }

    private void unPublish() {
        Log.i(TAG, "Unpublishing.");
        if (mActiveMessage != null) {
            Nearby.Messages.unpublish(mGoogleApiClient, mActiveMessage);
            mActiveMessage = null;
        }
    }

    private MessageListener mMessageListener = new MessageListener() {
        @Override
        public void onFound(Message message) {
            // Publishされたメッセージを発見
            String messageAsString = new String(message.getContent());
            Log.d(TAG, "Found message: " + messageAsString);
            mArrayAdapter.add(messageAsString);
        }

        @Override
        public void onLost(Message message) {
            // メッセージをロスト
            String messageAsString = new String(message.getContent());
            Log.d(TAG, "Lost sight of message: " + messageAsString);

        }
    };

    private void subscribe() {
        // メッセージの受信登録
        Nearby.Messages.subscribe(mGoogleApiClient, mMessageListener);
    }


    private void unSubscribe() {
        Log.i(TAG, "Unsubscribing.");
        if (mGoogleApiClient.isConnected()) {
            Nearby.Messages.unsubscribe(mGoogleApiClient, mMessageListener);
        }
    }

サンプルでは受信したメッセージをListViewに表示するように実装している。
f:id:forestsoftjpdev:20160621021528p:plain:w300

これで、Nearby Messages APIを使用し端末間でのメッセージのやり取りが可能となる。