Search code examples
androiddelphiindydelphi-xe5

Delphi XE5 TIdUDPServer does not receive anything on Android


I have a TIdUDPServer on a form setup with a default port and broadcast mode enabled and cannot get it to receive anything under Android.

The same code is working fine under iOS but if I retarget Android I do not receive anything.

Is there a trick I am missing. I have checked the "User Permissions" and turn on everything I think might influence this but have had no luck with getting it working.

Thanks in advance, Martin


Solution

  • Thank you Remy for putting me on the right track. Here is the complete code to receive broadcast UDP packets...

    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;
    

    And then to acquire the necessary lock...

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

    Finally dont forget the permissions mentioned in Remy's post.