花了兩三個禮拜終於把Android UDP搞定!
首先,要先搞懂Thread / Handler是甚麼,不然這篇往下看沒有意義(因為會看不懂)
在MainActivity的部分,這邊負責主要的UI介面+Handler+Thread呼叫
package com.example.thread_example;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import android.annotation.SuppressLint;
import android.net.wifi.WifiInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.support.v7.app.ActionBarActivity;
import android.text.format.Time;
import android.util.Log;
import android.widget.TextView;
@SuppressLint("NewApi")
public class MainActivity extends ActionBarActivity {
 public static Handler exHandler;
 private TextView txv;
 private ChatServer chatserver;
 private ChatSender chatsender;
 public static InetAddress IP;
 public WifiInfo mwifiInfo;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  if (android.os.Build.VERSION.SDK_INT > 9) {
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
      StrictMode.setThreadPolicy(policy);
  }
  
  
  txv = (TextView) findViewById(R.id.textView);
  //利用handler來顯示接收到的文字
  exHandler=new Handler() {
         @Override
         public void handleMessage(Message msg) { 
          super.handleMessage(msg);
          String msgString = (String)msg.obj;
          Log.d("Handler","Now in Handler");
          txv.setText(null);
          txv.setText(msgString+"\n"+txv.getText().toString());
         }
     };
  
        //獲得Wifi的內部網路IP
     StringBuilder IFCONFIG=new StringBuilder();
     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() && !inetAddress.isLinkLocalAddress() && inetAddress.isSiteLocalAddress()) {
                 IFCONFIG.append(inetAddress.getHostAddress().toString()+"\n");
                
                 }
             }
         }
         txv.setText(IFCONFIG.toString());
         Log.d("LOG_Text", IFCONFIG.toString());
     } catch (SocketException ex) {
         Log.e("LOG_TAG", ex.toString());
     }
  
  
  
  try{
   chatserver = new ChatServer();
   chatserver.start();
   chatsender = new ChatSender();
   chatsender.start();
   
   Log.d("User","Thread start...");
   
  }catch(Exception e)
  {
   String str = e.toString();
   Log.e("Error by User", str);
  }
    
 }
 
 protected void onPause(){
  super.onPause();
  if(chatserver != null)
  {
   if(!chatserver.isInterrupted())
   {
    chatserver.interrupt();
   }
  }
 }
 
}
有一點長,這邊元件只有拉一個TextView而已,十分簡單。
IFCONFIG 
這邊負責顯示WIFI的IP
Thread--chatserver/chatsender
則是另外開兩個java檔(與mainActivity.java同層)分別做為接收與傳送,.start()就是讓他啟動而已。
exHandler
這邊負責顯示接收到的資訊(不能用static來傳值,因為Android不支援,至於為什麼我也不清楚),並把他印出來在textview上面。
Receiver部分(chatserver.java)
package com.example.thread_example;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
public class ChatServer extends Thread{
 
 private DatagramSocket server = null;
 private static final int PORT = 8000;
 
 public ChatServer() throws IOException {
  server = new DatagramSocket(PORT);
  Log.d("User","new server socket");
 }
 public void run(){
  byte[] byte1024 = new byte[1024];
  //Message msg = new Message();
  //Bundle data = new Bundle();
  DatagramPacket dPacket = new DatagramPacket(byte1024, 100);
  String txt;
  try{
   Log.d("User","runing run()");
   while(true){
    server.receive(dPacket);
    while(true)
    {
     //印出來到螢幕上
     txt = new String(byte1024, 0, dPacket.getLength()); 
     MainActivity.exHandler.sendMessage(MainActivity.exHandler.obtainMessage(1,txt));
     Log.d("User","Handler send Message");     
     if(true) break;
    }
    //CloseSocket(client);//關閉
   }
  }
  catch(IOException e)
  {}
 }
 
 private void CloseSocket(DatagramSocket socket) throws IOException{
  socket.close();
 }
}
 
這邊宣告一個1024的byte來接收資料(按照你的資料量大小來調整宣告大小)
一定要宣告datagramSocket,datagramPacket,一個是連線,一個是接收封包用,至於handler這邊的
sendMessage就是回傳到MainActivity來讓textview顯示接收的資訊而已。結構上有兩個while(),第
一個while會卡在receive()這邊,一直到有封包進來才會往下跑到第二個while(),第二個則是印出資
訊,沒有甚麼特別的地方(Log是debug用的)