質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.94%

Android チャットクライアント

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,200

score 27

Android Studioを使用してチャットクライアントを作成しています.
public void handleButtonConnectAction(View view)はソケットを接続してバックラウンドでチャットを受信待ち状態にするメソッドです
しかしこれを実行すると常にチャットを受信待ちにしなければならないはずが受信待ちのバックラウンド処理がすぐに終了してしまう問題が発生してしまいます.どうすればよいのでしょうか

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

public class MainActivity extends AppCompatActivity
        implements ChatConnectTask.ChatConnectTaskCallback{

    private ChatConnectTask connectTask;
    private EditText inputIP;
    private EditText inputPort;
    private EditText inputMessage;
    private TextView viewChat;
    private Button buttonConnect;
    private Button buttonSend;
    private Socket socket;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        inputIP = (EditText)findViewById(R.id.inputIP);
        inputPort = (EditText)findViewById(R.id.inputPort);
        inputMessage = (EditText)findViewById(R.id.inputMessage);
        buttonConnect = (Button)findViewById(R.id.buttonConnect);
        buttonSend = (Button)findViewById(R.id.buttonSend);
        viewChat = (TextView)findViewById(R.id.viewChat);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    //connectボタンでソケット接続&メッセージ受信
    public void handleButtonConnectAction(View view){
        Toast.makeText(this, "kaisi", Toast.LENGTH_SHORT).show();
        //IPアドレスを取得
        String IP = inputIP.getText().toString();
        //ポート番号を取得
        int port = Integer.parseInt(inputPort.getText().toString());
        this.socket = connect(IP,port);
        Param param = new Param(socket);
        connectTask = new ChatConnectTask(this);
        connectTask.execute(param);
    }
    //サーバと接続するメソッド
    protected Socket connect(final String IP, final int port){
        new Thread(new Runnable(){
            @Override
        public void run(){
                Socket socket = new Socket();
                try {
                    socket.connect(new InetSocketAddress(IP,port));
                } catch (IOException e) {

                }
            }
        }).start();

        return socket;
    }


    //送信ボタンでメッセージを送信
    public void handleButtonSendAction(View view){
        String message = inputMessage.getText().toString();
        Param param = new Param(socket,message);
        ChatSendTask sendTask = new ChatSendTask(param);
        sendTask.start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onPreExecute() {

    }

    @Override
    public void onProgressUpdate(String... message) {
        viewChat.setText(message[0].toString());
    }

    @Override
    public void onPostExecute(String result) {
        Toast.makeText(this,result,Toast.LENGTH_LONG).show();
        inputMessage.setText("");
    }



}

ChatConnectTask.java
import android.os.AsyncTask;

import java.io.DataInputStream;

import java.io.IOException;
import java.io.InputStream;

import java.net.Socket;

public class ChatConnectTask extends AsyncTask<Param,String,String > {
    private ChatConnectTaskCallback mCallback;

    private String showMessage = " ";//nullConnectと表示させないための処置

    public ChatConnectTask(ChatConnectTaskCallback callback){

        this.mCallback = callback;
    }

    @Override
    protected void onPreExecute(){
        if(mCallback != null)
            mCallback.onPreExecute();
    }

    protected String doInBackground(Param... param){

        Socket socket = param[0].param1;

        try {

            while(socket != null) {
                // 接続されたソケットの入力ストリームを取得し,データ入力ストリームを連結
                InputStream is = socket.getInputStream();
                DataInputStream dis = new DataInputStream(is);

                // データの受信
                String receiveMessage = dis.readUTF();
                //受信したデータに改行をつけてメッセージを追加していく
                showMessage += receiveMessage + "\r\n";
                // 受信したデータを表示

                publishProgress(showMessage);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // ソケットをクローズする
            if (socket != null ) {
                try {
                    socket.close();
                } catch (IOException e) {}
            }
        }

        return "チャットを終了します";
    }

    @Override
    protected void onProgressUpdate(String... message){
        if(mCallback != null)
            mCallback.onProgressUpdate(message);
    }

    @Override
    protected void onPostExecute(String result ){
        if(mCallback != null) {
            mCallback.onPostExecute(result);
        }
    }

    public interface ChatConnectTaskCallback{
        void onPreExecute();
        void onProgressUpdate(String... message);
        void onPostExecute(String result);
    }
}

ChatSendTask.java
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

public class ChatSendTask extends Thread {
    private Param param = new Param();

    public ChatSendTask(Param... params){
        this.param.param1 = params[0].param1;
        this.param.param2 = params[0].param2;
    }

    public void run(){

        try {

// 接続されたソケットの出力力ストリームを取得し,データ出力ストリームを連結
            OutputStream os = param.param1.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
// テキストフィールドの文字を取得
            String sendMessage = param.param2;
            //データの送信
            dos.writeUTF(sendMessage);
            dos.flush();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // ソケットをクローズする
            if (param.param1 != null) {
                try {
                    param.param1.close();
                } catch (IOException e) {}
            }
        }
    }

}

import java.net.Socket;


public class Param {
    Socket param1;
    String param2;


    Param(Socket param1,String param2){
        this.param1 = param1;
        this.param2 = param2;
    }
    Param(Socket param1){
        this(param1,null);
    }
    Param(){
        this(null,null);
    }

}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • 退会済みユーザー

    2016/03/20 21:48

    こちらの質問が他のユーザから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.94%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る