Hello,
I am using Delphi 10.3.3, Indy 10.6.2.5366 (stock Indy version)
I am trying to listen broadcast UDP messages on Android (exact version I am testing is 4.4.2, I need to support latest versions, too) connected to a local WiFi. Broadcast messages will be sent in same network.
I have found this page https://stackoverflow.com/questions/19040674/delphi-xe5-tidudpserver-does-not-receive-anything-on-android and tried to do it as to my understanding.
Project has CHANGE_WIFI_MULTICAST_STATE permission set.
UDP server parameters are as following at design time and everything else is left as default:
TIdUDPServer.Active = False
TIdUDPServer.BroadcastEnable = True
TIdUDPServer.DefaultPort = 8080
I have following code where timer is activated as last line in OnFormCreate() event and has 0.5 seconds delay:
procedure TForm3.tmrCheckPhoneServiceTimer(Sender: TObject);
var
WifiManagerObj: JObject;
begin
// Run just once
tmrCheckPhoneService.Enabled := False;
// Get necessary OS settings to receive broadcast messages
Log('Getting multicast lock...');
WifiManagerObj := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.WIFI_SERVICE);
FWifiManager := TJWifiManager.Wrap((WifiManagerObj as ILocalObject).GetObjectID);
FMulticastLock := FWifiManager.createMulticastLock(StringToJString('LightFactory Remote'));
FMulticastLock.setReferenceCounted(True);
FMulticastLock.acquire();
// Try to open a port on Android by sending a broadcast message
Log('Sending a broadcast message...');
IdUDPServer1.Broadcast('test', IdUDPServer1.DefaultPort);
// Now we can start to listen
Log('Activating UDP listener...');
IdUDPServer1.Active := True;
if FPhoneDialerService = nil then
begin
TDialogService.ShowMessage('PhoneDialer service not supported');
Exit();
end;
PermissionsService.RequestPermissions([FCallPhonePermission], MakePhoneCallPermissionRequestResult, DisplayRationale);
end;
I have following code in my OnDestroy() event:
procedure TForm3.FormDestroy(Sender: TObject);
begin
// Stop listenning.
IdUDPServer1.Active := False;
// Release multicast lock
FMulticastLock.release();
end;
My broadcast listening code is as following:
procedure TForm3.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
Data: string;
begin
Data := TEncoding.Default.GetString(AData);
TThread.Queue(nil, procedure begin Log('Incoming broadcast message from: ' + ABinding.PeerIP) end);
if SameText(Data, 'mytriggerphrase') then
begin
TThread.Queue(nil, procedure begin TestConnection(ABinding.PeerIP) end);
end;
end;
After I run the app, I have following in my log:
2020-01-14 00:59:33.697 Getting multicast lock...
2020-01-14 00:59:33.736 Sending a broadcast message...
2020-01-14 00:59:33.740 Activating UDP listener...
2020-01-14 00:59:33.804 Incoming broadcast message from: 192.168.1.186
That IP number in above log belongs to Android device itself.
I have following problems that I could not figure a solution:
1- I do not get any other broadcast message from my PC application which is sending one broadcast message each second. Is there anything I am doing wrong for that to happen?
2- I get segmentation fault (11) when closing my app. Detailed call stack and exact line is in attached picture. This happens each and every close. I did not understand why.
Lastly, I am not sure if my code is doing it correct to keep multicast lock thru all run-time. I read a suggestion to release a multicast lock once finished with it in order to save battery life. So, I wonder if I can release multicast lock right after enabling my TIdUDPServer?
Any help is appreciated.
Thanks & regards,
Ertan