GoogleTalkのやりとりをするAndroidアプリを試作

どもー(´ω`)らーぬんです
現実逃避しまくりですがネタ投稿してきますorz

とある某ナニゲなプロジェクト向けにひとつ、リアルタイムなテキストメッセージング処理が必要になりまして。そのプロジェクトではAndroid端末使ってどうこうという考えだったので、GoogleTalkがイケそうだと思ったワケです。
Webをあさっていたところ、adamrockerさんのthrow Lifeブログ内にて「イマドキのAndroidアプリケーション開発方法」「Android用Google Talkクライアントをm5-rc14に移植」という記事がヒット。見ると、Smackなるライブラリを使って簡単にGoogleTalkな通信ができるとのこと。しかもありがたいことにAndroid向けにチューニングしたバージョン(こちらのページ下に行って「Download Source And APK From Here – XMPPClient.Zip」から)もあるとのこと。

早速試してみました。とりあえずメインGmail垢とサブGmail垢とで通信相手固定で、というヤッツケでヤッてみました。


TestGTalkClient / TestGTalkClientActivity.java

package jp.ramensroom.testgtalkclient;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class TestGTalkClientActivity extends Activity {

private static final String GTALK_HOST = "talk.google.com";
private static final int GTALK_PORT = 5222;

private static final String SERVICE = "gmail.com";
private static final String RECIPIENT = "example01@gmail.com"; //受信者のgmailアドレス
private static final String USERNAME = "example02"; //送信者のgmailアドレス(ドメイン抜き)
private static final String PASSWORD = "hogehoge"; //送信者のgmailログインパス

//GUI部品
EditText editText;
Button button;

ListView listview;
ArrayAdapter array;

//通信周り
ConnectionConfiguration connConfig;
XMPPConnection connection;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//通信ログ用ListView
listview = (ListView) findViewById(R.id.listView1);
array = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
listview.setAdapter(array);

connConfig = new ConnectionConfiguration(GTALK_HOST, GTALK_PORT, SERVICE);

PacketFilter filter = new MessageTypeFilter(Message.Type.chat);

connection = new XMPPConnection(connConfig);
try {
connection.connect();
connection.login(USERNAME, PASSWORD); //接続、ログイン
} catch (XMPPException e) {
e.printStackTrace();
}
connection.addPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) {
Message message = (Message) packet;

//本文がnullでないとき
if (message.getBody() != null) {
//送信元を見やすい形に変形(生データ→gmailアドレス)
String msgFrom = StringUtils.parseBareAddress(message.getFrom());
String msgBody = message.getBody();

Log.i("TestGTalkClientActivity", msgFrom + " : " + msgBody);

//リストビューに追加
array.insert(msgFrom + ": " + msgBody, 0);
array.notifyDataSetChanged();
}
}
}, filter);

editText = (EditText) findViewById(R.id.editText1);

button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//EditTextから送信用文字列抜き出し
String post = editText.getText().toString();

//ListViewにも追加
array.insert("me: " + post, 0);
array.notifyDataSetChanged();

//送信用メッセージ生成
Message msg = new Message(RECIPIENT, Message.Type.chat);
msg.setBody(post);
connection.sendPacket(msg);

//EditTextのクリア
editText.setText("");
}
});
}
}

TestGTalkClient / main.xml

AndroidManifest.xmlのUserPermissionにandroid.permission.INTERNETを追加するのと、Referenced Librariesとしてsmack.jarをビルドパスに追加することをお忘れなく。

手持ちのIS06(SIRIUSα)とS31HW(E-Mobile PocketWiFi S)とで試してみたところ、こんな感じにうまくいきましたヾ(´ω`)ノシ
まずIS06からS31HWへ「やぁ(´ω`)ノ」と送り、次にS31HWからIS06へ「やぁ」と返したシーンです。

IS06での画面

S31HWでの画面

ひとまずできました。ただ、相手から受信したタイミングですぐにListViewが更新されないのがなんかヘンな挙動なくらいです。Log.i見るかぎり受信イベントはリアルタイムで起きてる+データも受信されてるのでUIスレッドの取り扱いの問題(Handlerとかで更新かけるようにすべきとか)と思います。とりあえず送受信できるかの確認だけしたかったんで今回は放置(^q^)

てな感じでまた次回ーヾ(´ω`)ノシ


2012.02.07追記:
チャットデモでIS06とS31HWの通信順が逆ですたorz 本文で修正済みです