Android Wifi获取组播

From: http://www.apkbus.com/forum.php?mod=viewthread&tid=16351


Android的Wifi,默认情况下是不接受组播的,见:http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html

默认情况下,应用是不接收组播信息的,这样要接收处理的报文太多,很快就会把电池用尽。要知道移动设备(特指电话一类的,平板要好得多)目前最重要的因素是电量。

要想打开组播功能,有以下几个步骤:

  • 在Manifest文件中加入:android.permission.CHANGE_WIFI_MULTICAST_STATE,这个权限
  • 获取到MulticastLock对象,这个对象不能直接实例化,要通过WifiManager间接得到,工厂模式
  • 调用MulticastLock对象的acquire方法,获取到组播锁
  • 相应的,用完组播,为了不浪费电力,要调用MulticastLock的release方法释放锁

下面写了个简单示例,通过组播发现服务器。

Activity写的比较简单:

  1. public class MulticastDemoActivity extends Activity { 
  2.     
  3.     MulticastLock multicastLock; 
  4.     
  5.     /** Called when the activity is first created. */ 
  6.     @Override 
  7.     public void onCreate(Bundle savedInstanceState) { 
  8.         super.onCreate(savedInstanceState); 
  9.         setContentView(R.layout.main); 
  10.         
  11.         allowMulticast(); 
  12.         
  13.         try { 
  14.             NetUtil.findServerIpAddress(); 
  15.         } catch (IOException e) { 
  16.             throw new RuntimeException(e); 
  17.         } 
  18.         
  19.         Log.d("multicast.demo", "find ip ok."); 
  20.         
  21.         multicastLock.release(); 
  22.     } 
  23.     
  24.     private void allowMulticast(){ 
  25.         WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE); 
  26.         multicastLock=wifiManager.createMulticastLock("multicast.test"); 
  27.         multicastLock.acquire(); 
  28.     } 
  29. }
复制代码
在Activity中打开和释放组播锁。使用组播发送报文和接收ip地址信息的工具类代码:
  1. public class NetUtil { 
  2.     
  3.     private static final String TAG="Net.Utils"; 
  4.     private static final int MULTICAST_PORT=5111; 
  5.     private static final String GROUP_IP="224.5.0.7"; 
  6.     private static byte[] sendData; 
  7.     
  8.     static{ 
  9.         sendData=new byte[4]; 
  10.         // 0xEE78F1FB 
  11.         sendData[3] = (byte) 0xEE; 
  12.         sendData[2] = (byte) 0×78; 
  13.         sendData[1] = (byte) 0xF1; 
  14.         sendData[0] = (byte) 0xFB; 
  15.     } 
  16.     
  17.     public static String findServerIpAddress() throws IOException{ 
  18.         String ip=null;

  19.         MulticastSocket multicastSocket=new MulticastSocket(MULTICAST_PORT); 
  20.         multicastSocket.setLoopbackMode(true); 
  21.         InetAddress group = InetAddress.getByName(GROUP_IP); 
  22.         multicastSocket.joinGroup(group); 
  23.         
  24.         DatagramPacket packet=new DatagramPacket(sendData, sendData.length,group,MULTICAST_PORT); 
  25.         
  26.         for(;;){ 
  27.             multicastSocket.send(packet); 
  28.             Log.d(TAG,">>>send packet ok"); 
  29.             
  30.             byte[] receiveData=new byte[256]; 
  31.             packet=new DatagramPacket(receiveData, receiveData.length); 
  32.             multicastSocket.receive(packet); 
  33.             
  34.             String packetIpAddress=packet.getAddress().toString(); 
  35.             packetIpAddress=packetIpAddress.substring(1, packetIpAddress.length()); 
  36.             Log.d(TAG,"packet ip address: "+packetIpAddress); 
  37.             
  38.             StringBuilder packetContent=new StringBuilder(); 
  39.             for(int i=0;i<receiveData.length;i++){ 
  40.                 if(receiveData[i]==0){ 
  41.                     break; 
  42.                 } 
  43.                 packetContent.append((char)receiveData[i]); 
  44.             } 
  45.             ip=packetContent.toString(); 
  46.             Log.d(TAG,"packet content ip is: "+ip); 
  47.             
  48.             if(ip.equals(packetIpAddress)){ 
  49.                 Log.d(TAG,"find server ip address: "+ip); 
  50.                 break; 
  51.             }else{ 
  52.                 Log.d(TAG,"not find server ip address, continue …"); 
  53.                 try { 
  54.                     Thread.sleep(1000); 
  55.                 } catch (InterruptedException e) { 
  56.                 } 
  57.             } 
  58.         } 
  59.         
  60.         return ip; 
  61.     } 
  62. }
要在 Android 上接收数据,可以使用 MulticastSocket 类。以下是一个简单的示例代码: ```java MulticastSocket socket = new MulticastSocket(12345); // 绑定到一个指定的端口 InetAddress group = InetAddress.getByName("224.0.0.1"); // 地址 socket.joinGroup(group); // 加入 byte[] buffer = new byte[1024]; while (true) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); // 接收数据 String message = new String(packet.getData(), 0, packet.getLength()); // 处理接收到的数据 } socket.leaveGroup(group); // 离开 socket.close(); // 关闭 socket ``` 在上面的代码中,我们首先创建一个 MulticastSocket 对象,并绑定到一个指定的端口。然后,我们获取地址并加入到中。接着,我们使用一个循环来接收数据,并对接收到的数据进行处理。最后,我们离开并关闭 socket。 需要注意的是,在 Android 6.0 及以上版本中,为了确保应用程序能够接收数据,需要在应用程序的清单文件中添加以下权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> ``` 同时,为了避免在主线程中进行网络操作,建议将上面的代码放在一个单独的线程中执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值