【问题标题】:Delphi XE7 Android How to get current ipaddress, submask and gateway?Delphi XE7 Android 如何获取当前IP地址、子网掩码和网关?
【发布时间】:2015-06-28 15:14:07
【问题描述】:

我用Delphi XE7为Androiod设备开发的项目需要标题中声明的函数。

我找到了一段代码,它可以在 Windows 和 IOS 平台上运行并得到正确的结果。但在 Android 设备上,结果始终是:IP 地址 = 127.0.0.1,子网掩码为空。

procedure TForm1.RefreshList;
var
  LList: TIdStackLocalAddressList;
  I: Integer;
  AAddresses: TStrings;
begin
  AAddresses := TStringList.Create;
  try
    TIdStack.IncUsage;
    try
      LList := TIdStackLocalAddressList.Create;
      try
        // for backwards compatibility, return only IPv4 addresses
        GStack.GetLocalAddressList(LList);
        if LList.Count > 0 then begin
          AAddresses.BeginUpdate;
          try
            for I := 0 to LList.Count-1 do begin
              if LList[I].IPVersion = Id_IPv4 then begin
                AAddresses.Add(
                  LList[I].IPAddress+':'+
                  TIdStackLocalAddressIPv4(LList[I]).SubNetMask);
              end;
            end;
          finally
            AAddresses.EndUpdate;
          end;
        end;
      finally
        LList.Free;
      end;
    finally
      TIdStack.DecUsage;
    end;
    if AAddresses.Count > 0 then
      Text1.Text:= AAddresses.Text;
  finally
    AAddresses.Free;
  end;
end;

我发现byandroid.net.wifi.WifiManager.getDhcpInfo大概可以得到信息,但是我不知道怎么在Delphi中使用这个界面还是这样对吗?

【问题讨论】:

  • SubNetMask 属性尚未在 Android 上实现。 IPAddress127.0.0.1 因为 Indy 在 Android 上使用 getaddrinfo(),将本地主机名指定为要解析的主机,显然 Android 将其解析为环回 IP。在 OSX/iOS 上,Indy 使用 POSIX getifaddrs() 函数,而在 Windows 上,它使用 Win32 GetAdaptersInfo()/GetAdaptersAddresses() 函数。这些 API 报告实际 IP 和子网掩码...
  • ... Indy 有一个 TODO 项,用于支持 Android 上的getifaddrs()(Android 本身不支持,但有一个第三方实现浮动)或通过 Delphi 的 JNI 提供的原生 Android API桥接框架(但这并不能解决 FreePascal 的问题,因此需要 getifaddrs())。
  • @Remy 我仍然有这个问题,在 Delphi 10 Seattle。无论我尝试什么,TIdStackTIdTCPClient.Socket.BoundIPJNI。无论我尝试什么,我总是得到127.0.0.1。非常令人沮丧,我仍然没有找到解决方案:-/
  • @JerryDodge Indy 尚未更新以解决 Android 上的此问题。请注意,BoundIP 是仅输入属性,而不是输出属性。如果要绑定IP,连接后使用TIdTCPClient.Socket.Binding.IP。否则,使用 JNI 桥接器访问 Java API 应该能够获得正确的 IP,前提是您一开始就正确使用了 API。随意发布一个新的问题。

标签: android delphi indy


【解决方案1】:
type

  JWifiManager = interface;
  JDhcpInfo = interface;

  JWifiManagerClass = interface( JObjectClass )
    ['{0238345B-CF08-4139-B943-64900FC845F5}']
    function _GetACTION_PICK_WIFI_NETWORK : JString;
    function _GetEXTRA_WIFI_INFO : JString;
    function _GetWIFI_STATE_CHANGED_ACTION : JString;

    property ACTION_PICK_WIFI_NETWORK : JString read _GetACTION_PICK_WIFI_NETWORK;
    property EXTRA_WIFI_INFO : JString read _GetEXTRA_WIFI_INFO;
    property WIFI_STATE_CHANGED_ACTION : JString read _GetWIFI_STATE_CHANGED_ACTION;
  end;

  [ JavaSignature( 'android/net/wifi/WifiManager' ) ]
  JWifiManager = interface( JObject )
    ['{28DF429C-6E3E-4AFE-8372-18D8E81734E4}']
    function isWifiEnabled : Boolean; cdecl;
    function setWifiEnabled( enabled : Boolean ) : Boolean; cdecl;
    function getDhcpInfo : JDHCPInfo; cdecl;
    function getWifiState : Integer; cdecl;
    function getConnectionInfo : JWifiInfo; cdecl;
  end;

  TJWifiManager = class( TJavaGenericImport< JWifiManagerClass, JWifiManager > )
  end;


  JDHCPInfoClass = interface( JObjectClass )
    [ '{65204FA7-CD50-4EA9-85D6-0A9296A01C40}' ]
  end;

  [ JavaSignature( 'android/net/DhcpInfo' ) ]
  JDHCPInfo = interface( JObject )
    [ '{BBA64EF4-C771-4ECE-BD98-D6A706A5137F}' ]
  end;

  TJDHCPInfo = class( TJavaGenericImport< JDHCPInfoClass, JDHCPInfo > )
  end;


procedure TForm1.Button1Click(Sender: TObject);
var
  WifiManagerObj: JObject;
  WifiManager: JWifiManager;
  DhcpInfo: JDHCPInfo;
begin
  WifiManagerObj := SharedActivityContext.getSystemService(TJContext.JavaClass.WIFI_SERVICE);
  WifiManager := TJWifiManager.Wrap((WifiManagerObj as ILocalObject).GetObjectID);
  try
    DhcpInfo:= WifiManager.getDhcpInfo;
    text1.Text:= Text1.Text + #13#13 + JStringToString(DhcpInfo.toString);
  except on E:System.SysUtils.Exception do
    begin
      text1.Text:= e.ToString;
    end;
  end;
end;

上面的代码可以打印出字符串格式的正确信息。 关于定义 JDHCPInfoClass 和 JDHCPInfo 接口以直接读取字段值的任何建议?如:DhcpInfo.netmask、DhcpInfo.gateway?

【讨论】:

  • 请注意,此方法仅在连接到 WiFi 网络时有效,而在连接到蜂窝网络时无效。为此,您必须枚举 Android 的 NetworkInterface 类的 getNetworkInterfaces()getInetAddresses() 方法返回的列表
猜你喜欢
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
  • 2015-07-02
  • 2014-12-31
  • 2017-02-13
  • 2015-10-18
  • 1970-01-01
  • 2015-05-16
相关资源
最近更新 更多