在 Pixel 2 和 Pixel 2 XL 接收 UDP 广播数据包

Posted

技术标签:

【中文标题】在 Pixel 2 和 Pixel 2 XL 接收 UDP 广播数据包【英文标题】:Receiving UDP broadcast packet at Pixel 2 and Pixel 2 XL 【发布时间】:2018-08-12 15:39:57 【问题描述】:

我正在开发一个从 Wi-Fi 摄像头接收 UPD 广播数据包的应用。 在我发现在 Google Pixel 2 / Pixel 2 XL 接收 UPD 广播数据包有问题之前,它曾经很好。

为了找出原因,我做了2个测试应用:一个是UPD广播发送器(@9​​87654321@),另一个是UDP广播接收器(https://senatech.box.com/s/abamuor47nlafocs035nfuj90d0uvx0m)。

我在一些安卓设备上测试过,发现 Google Pixel 2 / Pixel 2 XL 无法接收 UDP 广播数据包。 Pixel 2 / Pixel 2 XL 以外的 android 设备运行良好。 Android 8.1 上的 Nexus 也运行良好。

我已经尝试搜索类似的问题,我发现了一些例如 在 Android 8.0 (https://bugreports.qt.io/browse/QTBUG-64233) 上未收到 UDP 广播数据包。 我认为这可能是由同样的问题导致的,尽管它是用 QT 编写的。

这里是 UDP 广播发送者的简要代码

public void sendUPDBroadcast() 
   Thread thread = new Thread() 
      @Override
      public void run() 
         DatagramSocket ds = null;
         int port = 0;
         String udpData = "";
         try          
            port = Integer.parseInt(etPort.getText().toString());
            udpData = etUDPData.getText().toString();
            InetAddress ia = InetAddress.getByName("192.168.255.255");
            ds = new DatagramSocket(port);
            DatagramPacket data = new DatagramPacket(udpData.getBytes(), udpData.getBytes().length, ia, port);
            ds.send(data);
          catch(Exception e) 
          finally 
            if (ds != null) 
               ds.close();
               ds = null;
            
         
      
   ;
   thread.start();

这里是 UDP 广播发送者的简要代码

   packet = new DatagramPacket(buffer, buffer.length);
   socket = new DatagramSocket(port);
   socket.setBroadcast(true);

   @Override
   public void run() 
      try 
         while (alive) 
            try 
               packet.setLength(buffer.length);
               socket.receive(packet);
               String s = stringFromPacket(packet);
             catch (java.io.InterruptedIOException e) 
             catch (java.io.IOException ex) 
             catch (Exception allException) 
             finally 
               if (socket != null)
                  socket.close();
                  socket = null;
               
            
         
      
   

有人遇到过这个问题并解决了吗? 提前谢谢你。

【问题讨论】:

我也看到了,没找到解决办法 【参考方案1】:

我在使用 Pixel 2 XL 时遇到了同样的问题。 我添加了获取 Wifi 组播锁,以便能够收听 UDP 广播消息。

WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wm.createMulticastLock("mydebuginfo");
multicastLock.acquire();

并在 Android Manifest 中添加了此权限:

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

但 Pixel 2 (XL) 上的 UDP 广播接收似乎只是偶尔工作。我还没有找到一个模式,它似乎是随机的。我知道 UDP 并不意味着可靠,但是同一 Wifi LAN 上的所有其他设备都可以完美地接收 UDP 广播数据包,而不会丢失。

【讨论】:

【参考方案2】:

尝试 [Ruud van Reenen] 的解决方案,我得到了喜忧参半的结果。但是,在添加了一些额外的权限并启用了引用计数之后,它对我来说工作得更加可靠。这是我的代码:

WifiManager wm = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wm.createMulticastLock("RavnApplication");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();

...

// don't forget to release when you're done...
if (multicastLock != null) 
    multicastLock.release();
    multicastLock = null;

还有额外的清单权限。

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

【讨论】:

以上是关于在 Pixel 2 和 Pixel 2 XL 接收 UDP 广播数据包的主要内容,如果未能解决你的问题,请参考以下文章

Android:Camera2 API 仅在 Google Pixel 2 和 2 XL 设备上崩溃

pixel4国内怎么更新

Pixel XL 刷机及Root过程

如何在 Pixel XL 的 OnActivityResult 中获取图像位图?

Android应用程序崩溃在Android 8.0(谷歌Pixel XL)

Error while waiting for device: The emulator process for AVD Pixel_2_XL_API_28 was killed.