4

これまでのところ、1つのAndroidデバイス(wifiテザリング/ホットスポット)でサーバーを起動し、クライアント(別のAndroid)をサーバーに接続してメッセージを送信できました。その後、サーバーはそれに応答しました。チャット アプリが実行されていない場合でも、サーバーがクライアントをリッスンし続ける方法が必要であることに気付きました。クライアントはメッセージを送信できる必要があり、サーバーはこれを受信する必要があります。これをアーカイブするには Service または IntentService を使用する必要がありますか? AsyncTask & Service から拡張できません...これを実装するにはどうすればよいですか? いくつかのサンプルコードは素晴らしいでしょう。

これは私のサーバーがどのように見えるかです:

public class Server extends AsyncTask<Integer, Void, Socket> {

    private ServerSocket serverSocket;
    private TextView textView;
    private String incomingMsg;
    private String outgoingMsg;

    public Server(TextView textView) {
        this.textView = textView;
    }

    public void closeServer() {
        try {
            serverSocket.close();
        } catch (IOException e) {
            Log.d("Server", "Closung the server caused a problem");
            e.printStackTrace();
        }       
    }


    @Override
    protected Socket doInBackground(Integer... params) {

        try {
            serverSocket = new ServerSocket(params[0]);       

            //accept connections
            Socket socket = serverSocket.accept();

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            incomingMsg = in.readLine() + System.getProperty("line.separator");

            //send a message
            outgoingMsg = "You are connected to the Server" + System.getProperty("line.separator");
            out.write(outgoingMsg);
            out.flush();

            return socket;


        } catch (InterruptedIOException e) {
            //if timeout occurs
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();

        } 
//      finally {
//          if (serverSocket != null) {
//              try {
//                  serverSocket.close();
//              } catch (IOException e) {
//                  e.printStackTrace();
//              }
//          }
//      }

        return null;
    }


    protected void onPostExecute(Socket socket) {

        if(socket != null) {
            try {

                Log.i("Server", "Server received: " + incomingMsg);
                textView.setText("Server received: " + incomingMsg + "\n");

                textView.append("Server sent: " + outgoingMsg + "\n");
                Log.i("Server", "Server sent: " + outgoingMsg);

                socket.close();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        } else {
            Log.d("Server", "Can't communicate with the client!");
        }
    }
}

そして、これは私のクライアントです:

public class Client extends AsyncTask<Integer, Void, Socket> {

    private WifiManager wifi;
    private Context context;
    private String outMsg;
    private String inMsg;

    public Client(Context context, WifiManager wifiManager) {
        this.context = context;
        this.wifi = wifiManager;
    }

    @Override
    protected Socket doInBackground(Integer... params) {

        try {

            String gateway = intToIp(wifi.getDhcpInfo().gateway);
            Socket socket = new Socket(gateway, params[0]);

            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            String ipAdress = intToIp(wifi.getConnectionInfo().getIpAddress());

            outMsg = ", Client " + ipAdress +" is connecting!" + System.getProperty("line.separator"); 
            out.write(outMsg);
            out.flush();

            //accept server response
            inMsg = in.readLine() + System.getProperty("line.separator");

            return socket;

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null; 
    }


    public String intToIp(int addr) {
        return  ((addr & 0xFF) + "." + 
                ((addr >>>= 8) & 0xFF) + "." + 
                ((addr >>>= 8) & 0xFF) + "." + 
                ((addr >>>= 8) & 0xFF));
    }


    protected void onPostExecute(Socket socket) {

        if(socket != null) {

            Log.i("Client", "Client sent: " + outMsg);
            Toast.makeText(context, "\nClient sent: " + outMsg + "\n", Toast.LENGTH_LONG).show();

            Log.i("Client", "Client received: " + inMsg);
            Toast.makeText(context, "Client received: " + inMsg + "\n", Toast.LENGTH_LONG).show();

        } else {
            Log.d("Client", "Can't connect to server!");
            Toast.makeText(context, "Can't connect to server!", Toast.LENGTH_LONG).show();
        }           
    }
}

サーバーからサービスを作成する方法は? クライアントもサービスにする必要がありますか?

4

1 に答える 1

3

サービスを使用しますが、AsyncTask は忘れてください。サービスで汎用スレッド ( https://developer.android.com/reference/java/lang/Thread.html ) を起動し、ソケットとリスナーをセットアップします。このサービスは、メッセージの送信も処理できます (以下のリンクで説明されている多くのオプションの 1 つを使用)。

サービスの onDestroy() でスレッドを適切にクリーンアップすることを忘れないでください。

また、アプリが引き続き他のクライアントからメッセージを受信するようにする場合は、サービスが強制的にフォアグラウンドになるようにする必要があることに注意してください ( http://developer.android.com/reference/android/app/Serviceを参照)。 .html#startForeground(int , android.app.Notification). ただし、これは絶対確実ではなく、サービスが強制終了される可能性があります。

これが、個々のデバイスではなく、専用のボックスでホストされているサーバーを使用する傾向がある理由です...

于 2013-04-17T14:47:49.570 に答える