MainActivity.java
package com.example.androidchatclient;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
static final int SocketServerPORT = 8080;
LinearLayout loginPanel, chatPanel;
EditText editTextUserName, editTextAddress;
Button buttonConnect;
TextView chatMsg, textPort;
EditText editTextSay;
Button buttonSend;
Button buttonDisconnect;
String msgLog = "";
ChatClientThread chatClientThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginPanel = (LinearLayout)findViewById(R.id.loginpanel);
chatPanel = (LinearLayout)findViewById(R.id.chatpanel);
editTextUserName = (EditText) findViewById(R.id.username);
editTextAddress = (EditText) findViewById(R.id.address);
textPort = (TextView) findViewById(R.id.port);
textPort.setText("port: " + SocketServerPORT);
buttonConnect = (Button) findViewById(R.id.connect);
buttonDisconnect = (Button) findViewById(R.id.disconnect);
chatMsg = (TextView) findViewById(R.id.chatmsg);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonDisconnect.setOnClickListener(buttonDisconnectOnClickListener);
editTextSay = (EditText)findViewById(R.id.say);
buttonSend = (Button)findViewById(R.id.send);
buttonSend.setOnClickListener(buttonSendOnClickListener);
}
OnClickListener buttonDisconnectOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if(chatClientThread==null){
return;
}
chatClientThread.disconnect();
}
};
OnClickListener buttonSendOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (editTextSay.getText().toString().equals("")) {
return;
}
if(chatClientThread==null){
return;
}
chatClientThread.sendMsg(editTextSay.getText().toString() + "\n");
}
};
OnClickListener buttonConnectOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
String textUserName = editTextUserName.getText().toString();
if (textUserName.equals("")) {
Toast.makeText(MainActivity.this, "Enter User Name",
Toast.LENGTH_LONG).show();
return;
}
String textAddress = editTextAddress.getText().toString();
if (textAddress.equals("")) {
Toast.makeText(MainActivity.this, "Enter Addresse",
Toast.LENGTH_LONG).show();
return;
}
msgLog = "";
chatMsg.setText(msgLog);
loginPanel.setVisibility(View.GONE);
chatPanel.setVisibility(View.VISIBLE);
chatClientThread = new ChatClientThread(
textUserName, textAddress, SocketServerPORT);
chatClientThread.start();
}
};
private class ChatClientThread extends Thread {
String name;
String dstAddress;
int dstPort;
String msgToSend = "";
boolean goOut = false;
ChatClientThread(String name, String address, int port) {
this.name = name;
dstAddress = address;
dstPort = port;
}
@Override
public void run() {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(name);
dataOutputStream.flush();
while (!goOut) {
if (dataInputStream.available() > 0) {
msgLog += dataInputStream.readUTF();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
chatMsg.setText(msgLog);
}
});
}
if(!msgToSend.equals("")){
dataOutputStream.writeUTF(msgToSend);
dataOutputStream.flush();
msgToSend = "";
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
final String eString = e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, eString, Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
e.printStackTrace();
final String eString = e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, eString, Toast.LENGTH_LONG).show();
}
});
} finally {
if (socket != null) {
try {
socket.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();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
loginPanel.setVisibility(View.VISIBLE);
chatPanel.setVisibility(View.GONE);
}
});
}
}
private void sendMsg(String msg){
msgToSend = msg;
}
private void disconnect(){
goOut = true;
}
}
}
/res/layout/activity_main.xml
<LinearLayout 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: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" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Char Client"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/loginpanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="visible" >
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="User name" />
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstAddress" />
<TextView
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect..." />
</LinearLayout>
<LinearLayout
android:id="@+id/chatpanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone" >
<EditText
android:id="@+id/say"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Say something" />
<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send" />
<Button
android:id="@+id/disconnect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Disconnect" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/chatmsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
</LinearLayout>
Permission of "android.permission.INTERNET" is needed in AndroidManifest.xml.
Download the files.
So good
ReplyDeletesir i am new to to wifi api ..i could not download the files attached .so i copy pasted the code and edited the manifest file .and copied the appcompat file to the project .but it is stopping on startup saying in logcat NoClassDefFound..Please guide me
ReplyDeleteCan't connect to server from another device, am i need to port forward or something else?
ReplyDeleteI am not sure but I think when client disconnect from the application, Toast that writes "removed" does not seem immediately.It is seen after a new client connects and sends a message.How can i handle this? Thanks for the answers.
ReplyDeleteHi good sir, how come you don't get a "CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views" error?
ReplyDeleteIt seems that you are calling chatMsg.setText from within the clientChatThread, but chatMsg was made in the MainActivity thread. Intuitively I would do this as well but I've been getting this error, do you have any work-arounds to this error? Thanks1
hello Anonymous,
ReplyDeleteTo prevent "CalledFromWrongThreadException...":
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
chatMsg.setText(msgLog);
}
});
This will create a Runnable to run in ui thread.
Sir how we can chat with individual in different Router
ReplyDeletethank for this application ,but i want know if i can create other ChatRoom or GroupChat in this app
ReplyDeleteI think it is depends on you.
ReplyDeletesir
ReplyDeletewhat is the username and destAddress to connect
hello raju mahato,
ReplyDeleteusername is any name you choice.
destAddress is the IP address of the server, it will be shown in Server side app.
tks tks tks
ReplyDeleteFirstly, Thats a very nice code :)
ReplyDeleteCan you plz guide me as to also implement small files transfer in this application?? I tried going through a lot of stuff like xmpp etc but is there something more simpler?
Dear I need such type of communication as between client and server as in
ReplyDeletehttp://android-er.blogspot.com/2014/08/implement-simple-android-chat.html
presented but using 3G/4G services.
What you want to suggest me, type of hint/method to do to achieve this.
Is it Tcp application?
ReplyDeletehow to prevent java.net.socketException
ReplyDeleteawesome & loved it, tutorial is working finely
ReplyDeleteHi, this is great, but may i ask how to make the text to not repeat if i send, i mean i want to replace the current text with the new one sent from server or also client,
ReplyDeletei believe we need to change something here;
while (!goOut) {
if (dataInputStream.available() >= 0) {
msgLog += dataInputStream.readUTF();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
chatMsg.setText(msgLog);
}
});
}
}
Hello Ezra Alvaro Manuel,
ReplyDeleteIt's a old exercise, i also forgot the details.
The point is what's new or old. For human understanding, client enter text "abc" then send, then enter "cde" then send. "abc" is old, "cde" is new.
What the machine view (in my understanding), it's "a", "b", "c", "d", "e", "f". It don't know when you click the send button. And the code if(dataInputStream.available() > 0){} will not handle it. May be it will receive "a", "bcd", "ef", or "abcd", "e", "f", no guarantee.
So I will suggest to insert some signature (such as "NL"(new line), "CR"(carriage return)) in the end of the text in client side. Such that the service side can check the signature to clear msgLog.
hope can help.
HY WHERE CAN I RECEIVE THE MESSAGES LIKE SHOWN ATT THE TABLETTE
ReplyDeletehello Anonymous,
ReplyDeleteRefer "Implement simple Android Chat Application, server side (http://android-er.blogspot.com/2014/08/implement-simple-android-chat.html)"
I need permission to download the files. Can I please get dot compliance permission?
ReplyDeleteHello Isha Sinha,
ReplyDelete??? Already set public, no permission needed.
Or you try to download here (https://sites.google.com/site/androidexercise2/download/AndroidChatClient_20140818a.zip) to by-pass the adv. page.
Hello,
ReplyDeleteI can't receive data from server? I am using an another server, python server.
Can you give any clue? Thanks
awesome.. so useful. helped it alot. thank u
ReplyDeleteawesome work.will u please help me I want to send messages from the server also.is it possible???
ReplyDelete