前回は、
第6回となる今回は、
なお前回と同様、
友達追加機能の実装
実装に入る前に、
友達追加機能は、

友達候補の取得
サインアップの際、
友達リストへの追加
1で取得した友達候補から、
この2つのフローの実装について、
①友達候補の取得
友達候補の取得処理をもう少し小さい処理に分割すると、
- ユーザの入力から検索キーワードを取得する
- ユーザネームもしくはEmailが検索キーワードから始まるユーザを、
‘chat_ users’ バケットから取得する - 取得したユーザのリストを表示する
この中で、
なお、
まず、
このクラスではActivity側で入手したユーザ入力を検索キーワードとして、
public class UserListLoader extends AbstractAsyncTaskLoader<List<ChatUser>> {
private String keyword;
public UserListLoader(Context context, String keyword) {
super(context);
// Activity側で取得した検索キーワードをセットする
this.keyword = keyword;
}
@Override
public List<ChatUser> loadInBackground() {
List<ChatUser> users = new ArrayList<ChatUser>();
try {
// 友達候補(キーワードにマッチするユーザ)を取得する
List<ChatUser> results = ChatUser.searchByKeyword(keyword);
for (ChatUser user : results) {
// サインイン中のユーザ(=検索実行中のユーザ自身)は検索結果から除外する
if (!TextUtils.equals(user.getUri(), KiiUser.getCurrentUser().toUri().toString())) {
users.add(user);
}
}
} catch (Exception e) {
Logger.e("Unable to list users", e);
}
return users;
}
}
UserListLoaderクラス内で、
クエリ実行時の条件は、
KiiQueryクラスの生成時に与えるKiiClauseクラスのインスタンスにより、
以下の例では、
public class ChatUser extends KiiObjectWrapper implements IUser {
// “chat_users”バケット: アプリケーションの全ユーザの情報が登録されている
private static final String BUCKET_NAME = "chat_users";
private static final String FIELD_USERNAME = "username";
private static final String FIELD_EMAIL = "email";
public ChatUser(KiiObject user) {
super(user);
}
public static KiiBucket getBucket() {
return Kii.bucket(BUCKET_NAME);
}
public static List<ChatUser> searchByKeyword(String keyword) throws Exception {
KiiQuery query = null;
// *(アスタリスク)を指定した場合、全ユーザを取得する
if (TextUtils.equals("*", keyword)) {
query = new KiiQuery();
} else {
query = new KiiQuery(
// 取得した検索キーワードから始まる”username”/”email”フィールドの値を検索する
KiiClause.or(
KiiClause.startsWith(FIELD_USERNAME, keyword),
KiiClause.startsWith(FIELD_EMAIL, keyword)
)
);
}
List<ChatUser> users = new ArrayList<ChatUser>();
List<KiiObject> objects = getBucket().query(query).getResult();
// ChatUserはKiiObject(オブジェクトを表すAndroid Cloud SDKのクラス)から作成する
for (KiiObject object : objects) {
users.add(new ChatUser(object));
}
return users;
}
…
}
②友達リストへの追加
友達リストへの追加をもう少し小さい処理に分割すると、
- 「①友達候補の取得」
で取得した友達候補から、 友達リストに追加したいユーザを選択する - ユーザの意思を確認するダイアログを表示する
- 上記ダイアログで追加に同意するボタンをクリックした場合、
友達リストにユーザを追加/表示する
この中で、
AddFriendActivityクラス内で定義するAsyncTask(AddingFriendTaskクラス)により,友達リストへの追加処理がバックグラウンドで実行されます。追加するユーザのインスタンス(ChatUserのインスタンス)は、
public class AddFriendActivity extends ActionBarActivity implements
LoaderCallbacks<List<ChatUser>>,
OnItemClickListener,
OnAddFriendListener {
…
private class AddingFriendTask extends AsyncTask<Void, Void, Boolean> {
private final ChatUser chatUser;
private AddingFriendTask(ChatUser chatUser) {
this.chatUser = chatUser;
}
@Override
protected void onPreExecute() {
ProgressDialogFragment.show(getSupportFragmentManager(),
"Adding Friend", "Processing...");
}
@Override
protected Boolean doInBackground(Void... params) {
try {
// 選択したユーザを友達リストに追加する
ChatFriend friend = new ChatFriend(this.chatUser);
friend.getKiiObject().save();
return true;
} catch (Exception e) {
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
ProgressDialogFragment.hide(getSupportFragmentManager());
if (result) {
setResult(RESULT_OK);
} else {
ToastUtils.showShort(AddFriendActivity.this, "Unable to add friend");
setResult(RESULT_CANCELED);
}
finish();
}
}
}
AddingFriendTaskクラス内で、
public class ChatFriend extends KiiObjectWrapper implements IUser {
// “chat_friends”バケット: 友達リスト内のユーザの情報が登録されている
private static final String BUCKET_NAME = "chat_friends";
…
// ログインユーザ(友達を追加する側)のユーザスコープ下の’chat_friends’バケットを返す
public static KiiBucket getBucket() {
return KiiUser.getCurrentUser().bucket(BUCKET_NAME);
}
...
public ChatFriend(ChatUser user) {
// ‘chat_friends’バケット下にユーザを表すオブジェクトを作成する
super(getBucket().object());
setUsername(user.getUsername());
setEmail(user.getEmail());
setUri(user.getUri());
}
…
}
上記までに友達リストに登録されたユーザを一覧する処理は、
public class FriendListLoader extends AbstractAsyncTaskLoader<List<ChatFriend>> {
public FriendListLoader(Context context) {
super(context);
}
@Override
public List<ChatFriend> loadInBackground() {
List<ChatFriend> friends = new ArrayList<ChatFriend>();
try {
// ログインユーザのユーザスコープ下にある“chat_friends”バケットを返す
KiiBucket friendsBucket = ChatFriend.getBucket();
// new KiiQuery()はバケット下の全てのオブジェクトを返す
List<KiiObject> results = friendsBucket.query(new KiiQuery()).getResult();
for (KiiObject friend : results) {
friends.add(new ChatFriend(friend));
}
return friends;
} catch (Exception e) {
Logger.e("Unable to list users", e);
return friends;
}
}
}
以上で、
次回の第7回は、