Ticker

6/recent/ticker-posts

Implement simple Android Chat Application, server side.

It's a simple example of Chat app running on Android devices, both server and clients. One device run AndroidChatServer to wait connection from clients, other devices run AndroidChatClient to connect to the server. Any AndroidChatClient can send message to server, then server broadcast to all clients.


Here is the code in Server side, Client side can be found in next post, "Simple Android Chat Application, client side"
.
MainActivity.java
package com.example.androidchatserver;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Bundle;

public class MainActivity extends ActionBarActivity {

static final int SocketServerPORT = 8080;

TextView infoIp, infoPort, chatMsg;

String msgLog = "";

List userList;

ServerSocket serverSocket;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoIp = (TextView) findViewById(R.id.infoip);
infoPort = (TextView) findViewById(R.id.infoport);
chatMsg = (TextView) findViewById(R.id.chatmsg);

infoIp.setText(getIpAddress());

userList = new ArrayList();

ChatServerThread chatServerThread = new ChatServerThread();
chatServerThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();

if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

private class ChatServerThread extends Thread {

@Override
public void run() {
Socket socket = null;

try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
infoPort.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}
});

while (true) {
socket = serverSocket.accept();
ChatClient client = new ChatClient();
userList.add(client);
ConnectThread connectThread = new ConnectThread(client, socket);
connectThread.start();
}

} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}

}

private class ConnectThread extends Thread {

Socket socket;
ChatClient connectClient;
String msgToSend = "";

ConnectThread(ChatClient client, Socket socket){
connectClient = client;
this.socket= socket;
client.socket = socket;
client.chatThread = this;
}

@Override
public void run() {
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;

try {
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());

String n = dataInputStream.readUTF();

connectClient.name = n;

msgLog += connectClient.name + " connected@" +
connectClient.socket.getInetAddress() +
":" + connectClient.socket.getPort() + "\n";
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
chatMsg.setText(msgLog);
}
});

dataOutputStream.writeUTF("Welcome " + n + "\n");
dataOutputStream.flush();

broadcastMsg(n + " join our chat.\n");

while (true) {
if (dataInputStream.available() > 0) {
String newMsg = dataInputStream.readUTF();


msgLog += n + ": " + newMsg;
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
chatMsg.setText(msgLog);
}
});

broadcastMsg(n + ": " + newMsg);
}

if(!msgToSend.equals("")){
dataOutputStream.writeUTF(msgToSend);
dataOutputStream.flush();
msgToSend = "";
}

}

} catch (IOException e) {
e.printStackTrace();
} finally {
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

userList.remove(connectClient);
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this,
connectClient.name + " removed.", Toast.LENGTH_LONG).show();

msgLog += "-- " + connectClient.name + " leaved\n";
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
chatMsg.setText(msgLog);
}
});

broadcastMsg("-- " + connectClient.name + " leaved\n");
}
});
}

}

private void sendMsg(String msg){
msgToSend = msg;
}

}

private void broadcastMsg(String msg){
for(int i=0; i userList.get(i).chatThread.sendMsg(msg);
msgLog += "- send to " + userList.get(i).name + "\n";
}

MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
chatMsg.setText(msgLog);
}
});
}

private String getIpAddress() {
String ip = "";
try {
Enumeration enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}

class ChatClient {
String name;
Socket socket;
ConnectThread chatThread;

}

}

/res/layout/activity_main.xml
    xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
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" >

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://picturedmagazine.blogspot.com/"
android:textStyle="bold" />

android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Char Server"
android:textStyle="bold" />

android:id="@+id/infoport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

android:id="@+id/infoip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

android:layout_width="match_parent"
android:layout_height="match_parent" >

android:id="@+id/chatmsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />




make sure Add uses-permission of "android.permission.INTERNET" to AndroidManifest.xml.

download filesDownload the files.

Related:
- Command line version Chat Server.

Next:
Android Chat example, with server sending individual message to specify client.


Added@2014-12-06

If you found "Something Wrong! java.net.SocketException" displayed.

Make sure add permission of "android.permission.INTERNET" in AndroidManifest.xml. It's a common error of missing "android.permission.INTERNET" to cause SocketException.


إرسال تعليق

0 تعليقات