1

I am trying to get an IP address from my android device (specifically from WiFi adapter). I managed to get WiFi State (even to disconnect from current AP, not included in this example), but I didn't manage to get IP address. Application exits without exception.

Can You help me with.

I have whole project attached here.

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Helpers.Android,
  Androidapi.JNIBridge,
  Androidapi.JNI.GraphicsContentViewText,
  Androidapi.JNI.JavaTypes,
  Androidapi.JNI, FMX.Layouts, FMX.Memo;

...

implementation

type
  JWifiManagerClass = interface(JObjectClass)
  ['{69F35EA7-3EB9-48AA-B7FC-4FFD0E7D712F}']
    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.WifiInfo')]
  JWifiInfo = interface(JObject)
  ['{4F09E865-DB04-4E64-8C81-AEFB36DABC45}']
    function getBSSID:jString; cdecl;
    function getHiddenSSID:Boolean; cdecl;
    function getIpAddress:Integer; cdecl;
    function getLinkSpeed:integer; cdecl;
    function getMacAddress:JString; cdecl;
    function getNetworkId:integer; cdecl;
    function getRssi:integer; cdecl;
    function GetSSID:jString; cdecl;
  end;

  JWifiInfoClass = interface(JObjectClass)
  ['{2B1CE79F-DE4A-40D9-BB2E-7F9F118D8C08}']
    function _GetLINK_SPEED_UNITS:JString;
    property LINK_SPEED_UNITS: JString read _GetLINK_SPEED_UNITS;
  end;

  TJWifiInfo= class(TJavaGenericImport<JWifiInfoClass, JWifiInfo>) end;

  [JavaSignature('android.net.wifi.WifiManager')]
  JWifiManager = interface(JObject)
  ['{DA7107B9-1FAD-4A9E-AA09-8D5B84614E60}']
    function isWifiEnabled:Boolean;cdecl;
    function setWifiEnabled(enabled:Boolean):Boolean; cdecl;
    function getConnectionInfo :JWifiInfo; cdecl;
    function getWifiState :Integer; cdecl;
    function disconnect :Boolean; cdecl;
  end;

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


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

...

var WiFiManager: JWifiManager;
    info: JWiFiInfo;
    ip: Integer;
begin
  WifiManager := GetWiFiManager;
  info := WifiManager.getConnectionInfo;  // <- Crash without exception
  ip := info.getIpAddress;
Ljubomir Đokić
  • 426
  • 4
  • 10

1 Answers1

2

After trying a few things I found that replacing . with / in the JavaSignature attribute of the interface declarations seems to do the trick.

[JavaSignature('android/net/wifi/WifiInfo')]

[JavaSignature('android/net/wifi/WifiManager')]

Quoted from this question:

One potential problem with the code is the attributes are using dot-separators, but the RTL Android class attributes, along with the aforementioned snippet, use / as a separator.

Community
  • 1
  • 1
ThePenguin
  • 123
  • 9