Androidアプリで、ボタンを押したらサーバーへ接続するアプリを作成します。
◆環境
OS |
Windows 7 Professional Service Pack 1 |
eclipse |
4.2.2 |
Android |
4.4 |
Android端末 |
Nexus7 |
@eclipseで[File]-[New]-[Project]を選択します。
ANew Projectウィンドウが開いたら[Android]-[Android Application Project]を選択し「Next」ボタンを押します。
BNew Android Applicationウィンドウが開いたら「Aplication Name」に AndroidSocketClient と入力し「Next」ボタンを押します。
CConfigure Projectウィンドウが開いたらそのまま「Next」ボタンを押します。
DConfigure the attributes of the icon setウィンドウが開いたらそのまま「Next」ボタンを押します。
ECreate Activityウィンドウが開いたらそのまま「Next」ボタンを押します。
FBlank Activityウィンドウが開いたらそのまま「Finish」ボタンを押します。
編集
ボタンを追加します。
activity_main.xml にボタンを押したときに呼ばれる関数名を追記します。
activity_main.xml
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res
/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:onClick="button1_click"
android:text="Button" />
</RelativeLayout>
|
|
MainActivity.java に Socket の接続処理を入れます。
MainActivity.java
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
|
package com.example.androidsocketclient;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void button1_click( View v )
{
Socket con = null;
try
{
Log.d( "INFO", "START Socket" );
con = new Socket( "127.0.0.1", 9876 );
Log.d( "INFO", "OK Socket" );
con.close();
}
catch ( UnknownHostException e )
{
Log.d( "ERROR", "Socket(1)" );
e.printStackTrace();
}
catch ( IOException e )
{
Log.d( "ERROR", "Socket(2)" );
e.printStackTrace();
}
}
}
|
|
実行したところエラーがでました。
java.net.SocketException: socket failed: EACCES (Permission denied)
AndroidManifest.xml に uses-permission を追加します。
AndroidManifest.xml
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
|
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/andr
oid"
package="com.example.androidsocketclient"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.androidsocketclient.MainAc
tivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN"
/>
<category android:name="android.intent.category.
LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
|
|
再度実行したところ別のエラーがでました。
java.lang.IllegalStateException: Could not execute method of the activity
アクティビティではこの関数は実行できない、といった内容でしょうか。
AsyncTask から派生した MySocket というクラスを作り、こちらで実行すうように修正します。
MySocket.java
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
|
package com.example.androidsocketclient;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.net.Uri;
import android.net.Uri.Builder;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
public class MySocket extends AsyncTask<Uri.Builder, Void, String>
{
private Activity mAct;
public MySocket( Activity act )
{
super();
mAct = act;
}
@Override
protected String doInBackground( Builder... arg0 )
{
Log.d( "INFO", "START doInBackground" );
Socket con = null;
try
{
Log.d( "INFO", "START Socket" );
con = new Socket( "127.0.0.1", 9876 );
Log.d( "INFO", "OK Socket" );
TextView txt
= ( TextView )mAct.findViewById( R.id.textView1 );
// txt.setText( "Socket OK!!" );
con.close();
}
catch ( UnknownHostException e )
{
Log.d( "ERROR", "Socket(1)" );
e.printStackTrace();
}
catch ( IOException e )
{
Log.d( "ERROR", "Socket(2)" );
e.printStackTrace();
}
Log.d( "INFO", "E N D doInBackground" );
return null;
}
}
|
|
txt.setText() を実行するとExceptionで異常終了するので、コメントアウトしています。
MainActivity は MySocket の execute を実行するように変更します。
MainActivity.java
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
|
package com.example.androidsocketclient;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void button1_click( View v )
{
Log.d( "INFO", "START button1_click" );
Uri.Builder params = new Uri.Builder();
MySocket soc = new MySocket( this );
soc.execute( params );
Log.d( "INFO", "E N D button1_click" );
}
}
|
|
実行してみます。
サーバー側は LinuxC の 通信(サーバー側) を使いました。
まずはサーバー側を実行します。
# ./LC112Server
17:42:38 SV LC112Server START
17:42:38 SV 接続を待っています
続いて Android側を実行しボタンを押してみます。
LogCatに以下のログが出ました。
11-29 17:43:39.058: D/INFO(18531): START button1_click
11-29 17:43:39.058: D/INFO(18531): E N D button1_click
11-29 17:43:39.058: D/INFO(18531): START doInBackground
11-29 17:43:39.058: D/INFO(18531): START Socket
11-29 17:43:39.078: D/INFO(18531): OK Socket
11-29 17:43:39.078: D/INFO(18531): E N D doInBackground
うまくいったようです。
サーバー側を見ると、接続を受け付けメッセージ送信処理選択の入力待ちになっていました。
17:43:15 SV accept OK
17:43:15 SV ----------------------------------
17:43:15 SV (1) send messase
17:43:15 SV (9) end
17:43:15 SV input number:
Android側(クライアント側)には受信処理を入れていないので 9でサーバーを終了させます。
17:43:15 SV input number: 9
17:45:09 SV 終了します。
17:45:09 SV LC112Server END
▲ PageTop ■ Home
Copyright (C) 2013 ymlib.com