Androidでソケット通信

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Androidでソケット通信

#1

投稿記事 by shiro4ao » 11年前

Androidでソケット通信をしてみようと思ったのですが
コードを書いて

コード:

//MainActivity.java
package com.example.socksample01;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	private TextView textView;
	private AlertDialog dialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

        Button btn = (Button)findViewById(R.id.sampleButton);
        btn.setOnClickListener((OnClickListener) this);
        
        textView = (TextView)findViewById(R.id.textView1);
        
	}

    public void onClick(View v) {
        // Toast.makeText(this, "ボタンが押されました", Toast.LENGTH_LONG).show();
      	EditText edit = (EditText)findViewById(R.id.edittext);
          String text = edit.getText().toString();
          Toast.makeText(this,text, Toast.LENGTH_LONG).show();
   //       dialog.show();            // ダイアログを表示    
          sockconnect();
      }
  	
    //ソケットで接続する
    private void sockconnect() {
        Socket connection = null;
        BufferedReader reader = null;
        try {
            // サーバーへ接続
            connection = new Socket("192.168.0.5", 80);	//LAN内のApacheへ接続
 
            // メッセージ取得オブジェクトのインスタンス化
            reader = new BufferedReader(new InputStreamReader(connection
                    .getInputStream()));
 
            // サーバーからのメッセージを受信
            String message = reader.readLine();
 
 
        } catch (UnknownHostException e) {
            e.printStackTrace();
            textView.setText("エラー内容:" + e.toString());
            Toast.makeText(this, "サーバーとの接続に失敗しました。",
                        Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            textView.setText("エラー内容:" + e.toString());
            Toast.makeText(this, "サーバーとの接続に失敗しました。",
                        Toast.LENGTH_SHORT).show();
        } finally {
            try {
                // 接続終了処理
                reader.close();
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
                textView.setText("エラー内容:" + e.toString());
                Toast.makeText(this, "サーバーとの接続に失敗しました。",
                                Toast.LENGTH_SHORT).show();
            }
        }
    }
    
    
    
    
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        textView.setText( "X:" + e.getX() + "\nY:" + e.getY() );
        switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.d("Sample", "ACTION_DOWN");
            break;
        case MotionEvent.ACTION_UP:
            Log.d("Sample", "ACTION_UP");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.d("Sample", "ACTION_MOVE");
            break;
        }
        return true;
    }
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}

通信をするのでインターネットアクセスを許可するようにAndroidManifest.xmlに追加したのですが

コード:

//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.socksample01"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.socksample01.MainActivity"
            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>
以下のようなエラーが出てきます

[2013-02-16 16:14:16 - SockSample01] Failed to install SockSample01.apk on device 'emulator-5554!
[2013-02-16 16:14:16 - SockSample01] (null)
[2013-02-16 16:14:16 - SockSample01] Launch canceled!

インストールに失敗しているようなので、マニフェストファイルの書き方が間違っているのでしょうか?
強引にアプリを起動すると起動はできるのですが、ボタンをクリックした時にアプリが強制終了させられてしまいました

LAN内のApacheはブラウザでアクセスできるので問題ないと思います
ファイアウォールもエミュレータ上のブラウザが通信ができるので問題ないとおもいます

何がおかしいのでしょうか・・・・?

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Androidでソケット通信

#2

投稿記事 by ISLe » 11年前

パーミッションの閉じタグ(/>)の前に空白がないからでしょうか。

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: Androidでソケット通信

#3

投稿記事 by shiro4ao » 11年前

ご返信ありがとうございます
閉じタグの前にスペースを入れてみたのですがやはりおなじエラーメッセージがでてきて
起動しようとしても強制終了してしまいます

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Androidでソケット通信

#4

投稿記事 by ISLe » 11年前

問題のapkファイルを見せてもらうことはできますか?
とりあえずapkファイルだけ添付していただければ。

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: Androidでソケット通信

#5

投稿記事 by shiro4ao » 11年前

apkファイルとプロジェクトのフォルダを圧縮したzipを添付いたします
前回から接続先を変えたり、接続処理の間にメッセージボックスをだしてみたのですが、
起こっている現象は同じようで、インストールの失敗と強制終了が起こりました・・・・。
添付ファイル
SockSample01.zip
プロジェクトのzipです
(176.72 KiB) ダウンロード数: 135 回
SockSample01.zip
zipではありません。中身はapkそのままなので拡張子をapkに戻してください。
(986.02 KiB) ダウンロード数: 108 回

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: Androidでソケット通信

#6

投稿記事 by みけCAT » 11年前

何もリクエストを送らずに、いきなり受信しようとしていいのですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Androidでソケット通信

#7

投稿記事 by ISLe » 11年前

こちらでプロジェクトをデバッグすると違う症状ですね。
AVD Managerが様変わりしてたのでAVDを新たに作りました。

apkのインストールは問題なく進み、onCreateメソッドで例外が出て落ちました。
ボタンのリスナーに、OnClickListenerをimplementsしていないActivityを無理矢理キャストして登録しているためですね。

修正して再びデバッグ、表示されたボタンを押すとsockconnectメソッドで例外が出ましたが、こちらには接続先がないですしそこは仕方ないですね。

というわけで特に問題はありませんでした。

環境に依存する問題でしょうか。
強引に起動できるというのがよく分からないですが。
単純にAVDのストレージに空きがないとか。

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: Androidでソケット通信

#8

投稿記事 by shiro4ao » 11年前

>何もリクエストを送らずに、いきなり受信しようとしていいのですか?
起動すらできないのでまずはその段階にいけるようにします

>こちらでプロジェクトをデバッグすると違う症状ですね。
仮想デバイスがおかしかったのか、再度仮想デバイスを作ったらインストールの失敗はなくなりました
しかし、今度はSocketをnewしたとたん落ちてしまいます。
接続先をLAN内のサーバ(192.168.0.5)とandroidからみえるローカルホスト(10.0.2.2)で試してみたのですが、
どちらでもSocketをnewしたタイミングで「Unfortuately SockSample01 has Stopped」のように言われて落ちてしまいます

インターネットアクセスの許可はManifestファイルに入れてあるので問題ないと思うのですが
それ以外の準備が必要なのでしょうか

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: Androidでソケット通信

#9

投稿記事 by shiro4ao » 11年前

そもそもアプリがインターネットアクセスできているのかという疑問があったので
HTTPでグーグルへアクセスするようにしてみたのですが、
例外が投げられてしまい、インターネットアクセスができていない可能性が高まりました
Manifest.xmlにはインターネットアクセスを求めるように書いたはずなのですが
他に必要な設定があるのでしょうか・・・・。

コード:

//MainActivity.java
package com.example.socksample01;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
	private TextView textView;
	private AlertDialog dialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

        Button btn = (Button)findViewById(R.id.sampleButton);
        btn.setOnClickListener((OnClickListener) this);
        
        textView = (TextView)findViewById(R.id.textView1);
        
	}

    public void onClick(View v) {
        // Toast.makeText(this, "ボタンが押されました", Toast.LENGTH_LONG).show();
      	EditText edit = (EditText)findViewById(R.id.edittext);
          String text = edit.getText().toString();
          Toast.makeText(this,text, Toast.LENGTH_LONG).show();
   //       dialog.show();            // ダイアログを表示    
        text = doGet("http://www.google.co.jp/");
        Toast.makeText(this,text, Toast.LENGTH_LONG).show();
    } 
    
    
    public String doGet( String url )
    {
        try
        {
            HttpGet method = new HttpGet( url );

            DefaultHttpClient client = new DefaultHttpClient();

            // ヘッダを設定する
            method.setHeader( "Connection", "Keep-Alive" );
            
            HttpResponse response = client.execute( method );
            int status = response.getStatusLine().getStatusCode();
            if ( status != HttpStatus.SC_OK )
                throw new Exception( "" );
            
            return EntityUtils.toString( response.getEntity(), "UTF-8" );
        }
        catch ( Exception e )
        {
        	Toast.makeText(this,"例外", Toast.LENGTH_LONG).show();
            return null;
        }
    }
    
    
    
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        textView.setText( "X:" + e.getX() + "\nY:" + e.getY() );
        switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.d("Sample", "ACTION_DOWN");
            break;
        case MotionEvent.ACTION_UP:
            Log.d("Sample", "ACTION_UP");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.d("Sample", "ACTION_MOVE");
            break;
        }
        return true;
    }
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}


追記
設定→アプリ→アプリ管理→アプリ選択でパーミッションを確認したところ
NETWORK COMMUNICATIONがあったのでインターネットアクセスの登録はできるはずなのですが・・・・

Androidエミュレータ自体はブラウザでインターネットへアクセスできるので通信できるはずですし
なぜ自作アプリがインターネットにアクセス出来ないのか、正直お手上げです。

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: Androidでソケット通信

#10

投稿記事 by shiro4ao » 11年前

例外が投げられる原因は不明なままなのですが
スレッドの中で接続処理を呼び出すとうまくいきました
いろいろとご迷惑をおかけしました
ありがとうございます

コード:



package com.example.socksample01;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button btn = (Button)findViewById(R.id.sampleButton);
        btn.setOnClickListener(this);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
	
	@Override
	public void onClick(View arg0) {
		 Log.d("socksample","ボタンが押された!");
		 Toast.makeText( this, "ボタンが押された!", Toast.LENGTH_LONG ).show();
        (new Thread(new Runnable() {
            @Override
            public void run() {
            	Log.d("socksample","コネクトがよばれた");
            	connect() ;
            }
        })).start();	
	}
	
	
    private void connect() {
        Socket connection = null;
        BufferedReader reader = null;
        try {
            connection = new Socket("74.125.235.191",80);
            reader = new BufferedReader(new InputStreamReader(connection
                    .getInputStream()));
            String message = reader.readLine();
            if (!(message.matches("^\\+OK.*$"))) {
                Log.d("socksample","失敗した");
            } else {
            	Log.d("socksample","接続した");            }
 
        } catch (UnknownHostException e) {
            e.printStackTrace();
            Log.d("socksample","未知の例外");
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("socksample","IO例外");
        } finally {
            try {
                // 接続終了処理
                reader.close();
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
           }
        }
    }
	
}





xxx
記事: 26
登録日時: 13年前

Re: Androidでソケット通信

#11

投稿記事 by xxx » 11年前

メインスレッドで通信しようとするとNetworkOnMainThreadExceptionを吐いた記憶があるので
多分これが例外の原因ではないでしょうか
http://developer.android.com/reference/ ... ption.html
onCreate()でネットワーク通信を始める前に
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
を追加するとおそらく例外を履かなくなると思います

アバター
shiro4ao
記事: 224
登録日時: 13年前
住所: 広島

Re: Androidでソケット通信

#12

投稿記事 by shiro4ao » 11年前

3以降は例外を吐くんですね、知りませんでした。
情報ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る