最近的工作将用到UDP通信,为此,自己写了个通过UDP协议发送和接收数据的小小的在线聊天软件。贴上主要代码:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
/**
* @author Eric Liu
* Date 2012-3-5
* Describe Main Activity of the chatten application.-
* Copyright Kingsun 2011-2012
*/
public class ChattenActivity extends Activity {
private static String IP="192.168.1.117"; //IP address
private static int PORT=3456; //port number
private TextView tv_showMessage; //show messages
private EditText et_message; //for input message
private Button bt_send; //send button
private final static int ITEM0=0; //menu 0
private ReceiveMessage receive; //the receiver thread
private boolean receivable=false; //wether the receiver can receive data
private ScrollView sv_list; //ScrollView
private String localip=""; //the local ip address
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
String message=msg.getData().getString("message");
String messages=tv_showMessage.getText().toString();
tv_showMessage.setText(messages+"\n"+message);
//sv_list.fullScroll(View.FOCUS_DOWN);
sv_list.post(new Runnable() {
public void run() {
sv_list.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
intViews();
localip=getLocalIpAddress();
receivable=true;
receive=new ReceiveMessage();
receive.inti();
receive.start();
}
private void intViews()
{
tv_showMessage=(TextView) this.findViewById(R.id.tv_messages);
et_message=(EditText) this.findViewById(R.id.et_message);
bt_send=(Button) this.findViewById(R.id.bt_send);
bt_send.setOnClickListener(new SendClick());
sv_list=(ScrollView) this.findViewById(R.id.sv_list);
}
//get the local ip address
public String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (SocketException ex) {
}
return null;
}
//send message button click listener
class SendClick implements OnClickListener
{
public void onClick(View v) {
// TODO Auto-generated method stub
String oldMessages="";
String inputMessage="";
oldMessages=tv_showMessage.getText().toString();
inputMessage=et_message.getText().toString().trim();
oldMessages=oldMessages+"\n"+"我:"+"\n"+inputMessage+"\n\n";
//if user do not input empty message
if(inputMessage!=null && !inputMessage.equals(""))
{
sendMessage(IP,PORT,inputMessage);
et_message.setText("");
tv_showMessage.setText(oldMessages);
sv_list.post(new Runnable() {
public void run() {
sv_list.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
}
}
//send message via UDP
private void sendMessage(String ipaddr,int port,String message)
{
DatagramSocket socket=null;
InetAddress addr=null;
String sendContent=localip+":\n"+message+"\n\n";
try {
addr=InetAddress.getByName(ipaddr);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(addr==null) return;
try {
socket=new DatagramSocket();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(socket==null) return;
//int lenth=sendContent.length();
System.out.println("send message:"+sendContent);
byte[] messBytes=null;
try {
messBytes = sendContent.getBytes("gb2312");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(messBytes==null) return;
DatagramPacket packet=new DatagramPacket(messBytes, messBytes.length, addr, port);
try {
socket.send(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
menu.add(0, ITEM0, 1, ChattenActivity.this.getResources().getString(R.string.menu_setting));
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId())
{
case ITEM0:
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.alert_dialog_text_entry, null);
final EditText et_ip=(EditText) textEntryView.findViewById(R.id.et_address);
new AlertDialog.Builder(ChattenActivity.this)
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(R.string.setting_title)
.setView(textEntryView)
.setPositiveButton(R.string.bt_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
IP=et_ip.getText().toString().trim();
receive.inti();
/* User clicked OK so do some stuff */
}
})
.setNegativeButton(R.string.bt_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
/* User clicked cancel so do some stuff */
}
})
.create().show();
break;
}
return super.onOptionsItemSelected(item);
}
//receive message thread
class ReceiveMessage extends Thread
{
byte[] messageBytes=new byte[1024];
DatagramSocket datagramSocket=null;
DatagramPacket datagramPacket=null;
public void inti()
{
try {
datagramSocket=new DatagramSocket(PORT);
datagramSocket.setReuseAddress(true);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
datagramPacket = new DatagramPacket(messageBytes,messageBytes.length);
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("running");
while(receivable)
{
try {
datagramSocket.receive(datagramPacket);
String message=new String(datagramPacket.getData(),0,datagramPacket.getLength(),"gb2312");
Message msg=new Message();
Bundle data=new Bundle();
System.out.println(message);
data.putCharSequence("message", message);
msg.setData(data);
handler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
datagramSocket.close();
datagramSocket.disconnect();
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
receivable=false;
receive=null;
System.exit(0);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
receivable=false;
finish();
System.exit(0);
}
return super.onKeyDown(keyCode, event);
}
}