我在表单设置上有一个 TIdUDPServer 并启用了默认端口和广播模式,并且无法让它在 Android 下接收任何内容。
相同的代码在 iOS 下运行良好,但如果我重新定位 Android,我什么也收不到。
有没有我错过的技巧。我已经检查了“用户权限”并打开了我认为可能会影响这一点的所有内容,但没有让它正常工作。
在此先感谢,马丁
我在表单设置上有一个 TIdUDPServer 并启用了默认端口和广播模式,并且无法让它在 Android 下接收任何内容。
相同的代码在 iOS 下运行良好,但如果我重新定位 Android,我什么也收不到。
有没有我错过的技巧。我已经检查了“用户权限”并打开了我认为可能会影响这一点的所有内容,但没有让它正常工作。
在此先感谢,马丁
您的设备是否连接到 WiFi 或移动网络?除非您首先启动传出 UDP 连接以打开移动运营商的防火墙,否则 UDP 无法在移动设备上运行。
UDP 数据包是直接发送到设备的 IP 还是广播 IP?默认情况下,Android 会丢弃不直接发送到设备 IP 的 UDP 数据包。对于多播数据包,WifiManager.createMulticastLock()
必须事先调用以允许此类数据包,并且您需要CHANGE_WIFI_MULTICAST_STATE
在应用程序的清单中包含该权限。这可能也适用于 UDP 广播,我不确定。
谢谢雷米让我走上正轨。这是接收广播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 帖子中提到的权限。