Delphi XE5 TIdUDPServer在Android上没有收到任何内容

时间:2013-09-27 00:04:00

标签: android delphi indy delphi-xe5

我在表单设置上有一个TIdUDPServer,默认端口和广播模式已启用,无法让它在Android下接收任何内容。

相同的代码在iOS下工作正常,但如果我重新定位Android,我就不会收到任何内容。

我缺少一个技巧吗?我已经检查了“用户权限”并打开了我认为可能会对此产生影响的所有内容,但却没有让它运转起来。

先谢谢,马丁

2 个答案:

答案 0 :(得分:5)

您的设备是否已连接到WiFi或移动网络?除非您首先启动传出UDP连接以打开移动运营商的防火墙,否则UDP无法在移动设备上运行。

UDP数据包是直接发送到设备的IP还是广播IP?默认情况下,Android会丢弃未直接寻址到设备IP的UDP数据包。对于多播数据包,必须事先调用WifiManager.createMulticastLock()以允许此类数据包,并且您需要在应用程序的清单中包含CHANGE_WIFI_MULTICAST_STATE权限。这也可能适用于UDP广播,我不确定。

答案 1 :(得分:2)

谢谢雷米让我走上正轨。 以下是接收广播UDP数据包的完整代码......

unit Androidapi.JNI.WiFiManager;

interface

uses
  Androidapi.JNIBridge, Androidapi.Jni,  androidapi.JNI.JavaTypes, androidapi.JNI.Net,
  androidapi.JNI.Os, FMX.Helpers.Android, Androidapi.JNI.GraphicsContentViewText, SysUtils;

Type
  JWiFiManager = interface;   // android/net/wifi/WifiManager
  JMulticastLock = interface; // android/net/wifi/WifiManager$MulticastLock

  JWiFiManagerClass = interface(JObjectClass)
   ['{F69F53AE-BC63-436A-8F69-57389B30CAA8}']
    function getSystemService(Contex: JString): JWiFiManager; cdecl;
  end;

  [JavaSignature('android/net/wifi/WifiManager')]
  JWiFiManager = interface(JObject)
  ['{382E85F2-6BF8-4255-BA3C-03C696AA6450}']
    function createMulticastLock(tag: JString): JMulticastLock;
  end;

  TJWiFiManager = class(TJavaGenericImport<JWiFiManagerClass, JWiFiManager>) end;

  JMulticastLockClass = interface(JObjectClass)
  ['{C0546633-3DF2-46B0-8E2C-C14411674A6F}']
  end;

  [JavaSignature('android/net/wifi/WifiManager$MulticastLock')]
  JMulticastLock = interface(JObject)
  ['{CFA00D0C-097C-45E3-8B33-0E5A6C9FB9F1}']
    procedure acquire();
    function isHeld(): Boolean;
    procedure release();
    procedure setReferenceCounted(refCounted: boolean);
  end;

  TJMulticastLock = class(TJavaGenericImport<JMulticastLockClass, JMulticastLock>) end;

  function GetWiFiManager: JWiFiManager;

implementation

function GetWiFiManager: JWiFiManager;
var
  Obj: JObject;
begin
  Obj := SharedActivityContext.getSystemService(TJContext.JavaClass.WIFI_SERVICE);
  if not Assigned(Obj) then
    raise Exception.Create('Could not locate Wifi Service');
  Result := TJWiFiManager.Wrap((Obj as ILocalObject).GetObjectID);
  if not Assigned(Result) then
    raise Exception.Create('Could not access Wifi Manager');
end;

然后获得必要的锁定......

wifi_manager := GetWiFiManager;
multiCastLock := wifi_manager.createMulticastLock(StringToJString('LightFactory Remote'));
multiCastLock.setReferenceCounted(true);
multiCastLock.acquire;

最后不要忘记Remy的帖子中提到的权限。