以前にJavaSEでSocket通信のプログラムを書いた。今度は、AndroidでSocket通信をしてみる。
と言っても、コーディングはJavaSEとまったく同じやり方で出来るのだが、Androidの場合はSocket通信をするためにパーミッションを設定しておく必要がある。
まずは、AndroidManifest.xmlに以下のパーミッションを追記する。
<uses-permission android:name=”android.permission.INTERNET” />
次に、以下のような画面を作ってみた。

Sendボタンを押したときにサーバーと正しく接続できれば、テキストボックスに入力した値をサーバーへ送信するようになっている。
このレイアウトxmlのソースは以下のようになる。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="120dp"
android:layout_height="fill_parent"
android:text="IP Address"
/>
<EditText
android:id="@+id/txtIPAdress"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text=""
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="120dp"
android:layout_height="fill_parent"
android:text="Port"
/>
<EditText
android:id="@+id/txtPort"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="10000"
/>
</LinearLayout>
<EditText
android:id="@+id/txtSend"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<Button
android:id="@+id/button1"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Send" />
</LinearLayout>
Activity側のソースは以下のようになる。
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String address =
((EditText)findViewById(R.id.txtIPAdress)).getText().toString();
String strPort =
((EditText)findViewById(R.id.txtPort)).getText().toString();
int port = Integer.parseInt(strPort);
Socket socket = null;
try {
socket = new Socket(address,port);
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
String sendTxt =
((EditText)findViewById(R.id.txtSend)).getText().toString();
pw.println(sendTxt);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if( socket != null){
try {
socket.close();
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
}
ボタンが押されたときにSocket通信の処理を書いているが、この部分は以前に作ったクライアントプログラムと全く変わっていない。
プログラムがビルドできたら、サーバーを立ち上げておこう。ここで使うサーバープログラムも、以前に作ったコンソールベースのものである。
サーバーが立ち上がったら、そのマシンのローカルIPアドレスを確認して、Android側のアドレス入力欄に入力する。
ローカルIPアドレスは、Windowsならばipconfigコマンドで確認できるだろう。
ポートの値はクライアントとサーバーで合っていれば良いが、ここでは例ということで「10000」固定にしておいた。
ipconfigで確認したIPアドレスを・・・

アプリのアドレス欄へ入力する

そうしたら、何か適当な文字を入力してSendボタンを押す。

正しく接続できたならば、サーバー側に受信した文字列が表示されるだろう。

実は、このAndroidプログラムはサーバーとの接続に失敗したり、接続に時間がかかったときに短時間画面をブロックしてしまい、使い勝手があまりよくない。
本来ならば、接続部分は別スレッドを起こすなりした方が良いだろう。
サンプルコードをコピーして試してみても、アプリが落ちます。
以前のjava同士のやつは出来てるんですけど。。。
非常にシンプルで分かりやすいサンプルがあって助かります!
現在のandroidの仕様では送信部分は別のスレッドで行う必要があります.
私もandroidでのTCP/IP通信の勉強を始めたばかりですが,修正して動作が確認できたソースを載せておきたいと思います.※ findViewById…の中身
@Override
public void onClick(View v) {
Runnable sender = new Runnable() {
@Override
public void run() {
String address =
((EditText) findViewById(R.id.txtIPAdress)).getText().toString();
String strPort =
((EditText) findViewById(R.id.txtPort)).getText().toString();
int port = Integer.parseInt(strPort);
Socket socket = null;
try {
socket = new Socket(address, port);
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
String sendTxt =
((EditText) findViewById(R.id.txtSend)).getText().toString();
pw.println(sendTxt);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (socket != null) {
try {
socket.close();
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
Thread th = new Thread(sender);
th.start();
}