第5回・
第7回は、
今回使用したソースコードについては、
チャットルーム作成機能の実装
実装に入る前に、

- チャットルーム作成・
開始者の入室:チャットを開始する人は、 まずグループを作成し、 チャットに招待したい人をグループのメンバーとして追加する。その後、 チャットメッセージを保存するためのバケットを購読し、 他のユーザーからメッセージが送信された場合にプッシュ通知を受信できるようにする。 - チャット招待通知の送信:チャットを開始する人は、
invite_ notifyトピックを通じてチャットに招待したい人へプッシュ通知を送信する。この通知には作成されたグループの情報を付加し、 どのチャットに招待されたか判別できるようにする。 - 招待者の入室:チャットに招待された人は、
招待通知メッセージに含まれているグループ情報からチャットを行うバケットを特定し入室と購読を行う。これによって他のユーザーからメッセージが送信された場合にプッシュ通知を受信できるようにする。
この3つのフローについて、
チャットルームの作成・開始者の入室
まずはチャットを開始するために、
チャットのメッセージを保存するために、
チャットルーム作成までのフローは
// チャットに参加するユーザー名からチャットルームの名前を生成する
String chatRoomName = ChatRoom.getChatRoomName(KiiUser.getCurrentUser(), this.chatFriend);
// チャットに参加するユーザーのIDからユニークなキーを生成する
String uniqueKey = ChatRoom.getUniqueKey(KiiUser.getCurrentUser(), this.chatFriend);
// 現在メンバーとして参加しているグループを取得する
List<KiiGroup> existingGroup = KiiUser.getCurrentUser().memberOfGroups();
// 既に同じメンバーのグループが存在するかユーザーIDを用いてチェックする
for (KiiGroup kiiGroup : existingGroup) {
if (TextUtils.equals(uniqueKey, ChatRoom.getUniqueKey(kiiGroup))) {
return kiiGroup;
}
}
// チャット用のグループをユーザー名を用いて作成
KiiGroup kiiGroup = Kii.group(chatRoomName);
KiiUser target = KiiUser.createByUri(Uri.parse(this.chatFriend.getUri()));
target.refresh();
kiiGroup.addUser(target);
kiiGroup.save();
// Chat用バケツを購読してメッセージをプッシュ通知してもらう状態にする
KiiBucket chatBucket = ChatRoom.getBucket(kiiGroup);
KiiUser.getCurrentUser().pushSubscription().subscribeBucket(chatBucket);
まずは、
上記のチェックを経てグループが存在しない場合は、
最後に KiiGroup#save() を利用しKiiCloud上へ保存を行います。
これでチャット開始者とチャット招待者を含んだグループの作成が完了しました。
次にチャットメッセージを保存するバケットを購読し、
これでチャットを行うためのグループとバケットの作成が完了しました。
チャットに参加していない人
チャット招待通知の送信
次にチャットに招待された人へ招待通知を送信しましょう。招待通知の送信にはトピックを利用し、
プッシュ通知を利用するためには、
さて、
// 招待ユーザーのURIからKiiUserのインスタンスを作成
KiiUser target = KiiUser.createByUri(Uri.parse(this.chatFriend.getUri()));
// 招待ユーザー上で作成済みのinvite_notifyトピックを指定
KiiTopic topic = target.topicOfThisUser(ApplicationConst.TOPIC_INVITE_NOTIFICATION);
// プッシュ通知で送信するデータにグループのURIを付加
Data data = new Data();
data.put(ChatRoom.CAHT_GROUP_URI, kiiGroup.toUri().toString());
// プッシュ通知を送信
KiiPushMessage message = KiiPushMessage.buildWith(data).build();
topic.sendMessage(message);
チャットに招待する友人のURIを取得し、
これでチャットしたい相手に招待を送信することができました。プッシュ通知を利用するためリアルタイムで通知することができます。
招待者の入室(プッシュ通知契機)
チャットに招待されたユーザー上の端末では、
そのためチャットルームへ入室し、
上記のフローはプッシュ通知を契機とするため、
public void onReceive(final Context context, Intent intent) {
// GCM経由で送信されたメッセージかどうかを判断
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
final Bundle extras = intent.getExtras();
// MessageTypeを判断
ReceivedMessage message = PushMessageBundleHelper.parse(extras);
MessageType type = message.pushMessageType();
switch (type) {
// トピックを利用したプッシュ通知である場合
case PUSH_TO_USER:
new Thread(new Runnable() {
@Override
public void run() {
try {
// 受信したメッセージからグループのURIを取得
String groupUri = extras.getString(ChatRoom.CAHT_GROUP_URI);
// 取得したURIを元にグループのインスタンスを作成
KiiGroup kiiGroup = KiiGroup.createByUri(Uri.parse(groupUri));
// 自分がメンバーでないChatRoomは無視する
if (isMember(kiiGroup)) {
// チャットルームのバケットを取得
KiiBucket chatBucket = ChatRoom.getBucket(kiiGroup);
// チャットルームのバケットを購読
KiiUser.getCurrentUser().pushSubscription().subscribeBucket(chatBucket);
sendBroadcast(context, ApplicationConst.ACTION_CHAT_STARTED, groupUri);
}
} catch (Exception e) {
Logger.e("Unable to subscribe group bucket", e);
}
}
}).start();
break;
}
}
}
private boolean isMember(KiiGroup kiiGroup) throws GroupOperationException {
if (KiiUser.getCurrentUser() != null) {
kiiGroup.refresh();
List<KiiUser> members = kiiGroup.listMembers();
for (KiiUser member : members) {
if (KiiUser.getCurrentUser().toUri().equals(member.toUri())) {
return true;
}
}
}
return false;
}
private void sendBroadcast(Context context, String action, String message) {
Intent intent = new Intent(action);
intent.putExtra(ApplicationConst.EXTRA_MESSAGE, message);
context.sendBroadcast(intent);
}
まずは受信したメッセージについてGCM経由で送信されたメッセージかどうかを判断し、
そして、
しかしながら、
次にチャットルームのバケットを取得し、
最後に、
招待者の入室(ユーザーサインイン契機)
前項ではプッシュ通知を契機とした入室処理を行いましたが、
たとえば
そのためユーザーサインインを契機として招待者がチャットルームに入室できるよう、
public static void ensureSubscribedBucket(final KiiUser kiiUser) {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
try {
// ユーザが所属しているグループの一覧を取得
List<KiiGroup> groups = kiiUser.memberOfGroups();
for (KiiGroup group : groups) {
// 全てのグループでchat_roomバケツを購読済みであることを確認
KiiBucket chatBucket = ChatRoom.getBucket(group);
boolean isSubscribed = kiiUser.pushSubscription().isSubscribed(chatBucket);
if (!isSubscribed) {
// 購読されていない場合は、購読する
Logger.i("---------------- 取りこぼし対応 ----------------");
kiiUser.pushSubscription().subscribeBucket(chatBucket);
}
}
return true;
} catch (Exception e) {
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) {
Logger.e("Unable to subscribe group bucket");
}
}
}.execute();
}
まずは、
これによって、
まとめ
チャットルームの実装を終えて、
今回はバケット・
次回は主要機能の最後となる