0

i tried to covert the wifimanager and wifiinfo (android) and i don't understand why i had segmentation fault, i saw that wifimanager worked well, but when i try to call some methods of wifiinfo i get "segmentation fault". my code:

http://developer.android.com/reference/android/net/wifi/WifiInfo.html http://developer.android.com/reference/android/net/wifi/WifiManager.html

unit wifi1;

interface

uses
System.SysUtils,
Androidapi.JNIBridge,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.JavaTypes,
FMX.Helpers.Android;

//-------------------------------- wifi manager ---------------------------------------//
type
JWifiManager = interface;
JWifiInfo = interface;

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.WifiManager')]
JWifiManager = interface(JObject)
['{DA7107B9-1FAD-4A9E-AA09-8D5B84614E60}']
function isWifiEnabled:Boolean;cdecl;
function setWifiEnabled(enabled:Boolean):Boolean; cdecl;
//function getConfiguredNetworks : JList;cdecl;
function getConnectionInfo :JWifiInfo; cdecl;
end;
TJWifiManager = class(TJavaGenericImport<JWifiManagerClass, JWifiManager>) end;
//-------------------------------- wifi info ---------------------------------------//
JWifiInfoClass = interface(JObjectClass)
['{2B1CE79F-DE4A-40D9-BB2E-7F9F118D8C08}']
function _GetLINK_SPEED_UNITS:JString;
property LINK_SPEED_UNITS: JString read _GetLINK_SPEED_UNITS;
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;
TJWifiInfo= class(TJavaGenericImport<JWifiInfoClass, JWifiInfo>)
end;
implementation
end.
//-----------------------------------------------------------------------

and my test is :

var obj:jobject;
wm:jwifimanager;
Winfo:jwifiinfo;
ip:integer;
mac:string;
jmac:JString;
begin
obj:=SharedActivity.getSystemService(TJActivity.JavaClass.WIFI_SERVICE);
wm:= Tjwifimanager.Wrap((obj as ILocalObject).GetObjectID);

Winfo:=TJWifiInfo.Create;
winfo:=wm.getconnectioninfo; <- segmentation fault
ip:=winfo.getIpAddress;
jmac:=winfo.getMacAddress;
mac:=JStringToString(jmac);
end;

what can be wrong with this? (the methods of wifimanager works but not getconnectioninfo )

ORIGINAL JAVA POST: Detect wifi IP address on Android?

LOGCAT when i call this function: logcat

and this is the project in delphi: PROJECT DELPHI

Community
  • 1
  • 1
user1931849
  • 169
  • 4
  • 19
  • How come your `JWifiManager` only has three methods? The real class have over 20. Are you allowed only to declare the ones that you need? Seems unlikely to me. – David Heffernan Nov 05 '13 at 16:41
  • No, the interface needs to be complete so the offets are correct. Add the missing methods. Also, get rid of the `Winfo:=TJWifiInfo.Create;` line, it is useless in this context. – Remy Lebeau Nov 05 '13 at 16:47
  • 1
    Yes, David, you are. You only need to declare the ones you want to import. – blong Nov 05 '13 at 16:48
  • No Remy, it does not now. The missing methods need not be added. The Java Bridge does not require them. – blong Nov 05 '13 at 16:49
  • @blong: I am not familiar with the inner workings of the JNI bridge. Does Delphi do a dynamic runtime lookup using reflection/RTTI? Otherwise, how can it work if you don't declare everything? – Remy Lebeau Nov 05 '13 at 16:51
  • @RemyLebeau without Winfo:=TJWifiInfo.Create; nothing changed. The 4 methods on wifimanager worked well on other test that i made. Any idea? – user1931849 Nov 05 '13 at 16:52
  • Remy, the interface is just a convenient harness for declaring all the methods you wish to access. Offsets are irrelevant as they map to Java instance or class methods, depending which interface you declare them in. Delphi runs managed code, Java is byte code on the other side of the JNI interface. The interfaces are just a means to an end. There's a CodeRage 8 talk on the matter if interested in getting familiar with the subject so you can answer knowledgeably. – blong Nov 05 '13 at 16:56
  • @blong the video of coderage need to be uploaded from embarcadero. Any idea to solve this issue? – user1931849 Nov 05 '13 at 16:58
  • I added (edited) a couple of extra pointers into my answer below, which may help in the mean time – blong Nov 05 '13 at 17:48
  • The logcat screenshot seems to include no indication of a segmentation fault. I'm not sure it's a logcat of when that code is called, unless there is some disaprity with the reported problem and the actual facts of the matter. Please clarify what's going on here. – blong Nov 06 '13 at 09:23

2 Answers2

2

What is primarily wrong with it is that lack of checking for nil values, which consequently leads to your segmentation fault (at least I'm expecting this to be the case - wm being nil, for example).

You can try referring to the code snippet in this SO answer as a general guide to working with the Android network classes. That should help for now, in lieu of a direct pointer to the error in your code. Try that code out and ensure you understand how it operates. It should then help you identify what is errant in your snippet.

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.

Judicious use of logcat (say from within the monitor app) would help identify if this was the case by seeing what the OS throws out as log messages for the period this app executes.

Oh, and one thing that should have been checked first - have you added the Access wifi state permission to your app? That will cause issues with, erm, accessing wifi state information, natch.

Community
  • 1
  • 1
blong
  • 2,145
  • 13
  • 23
  • i already saw this answer, yes i have all permission, now i have updated my question with the link of the original java code that i wanted to convert. Now i'm investigating to find the error. (http://stackoverflow.com/questions/7975473/detect-wifi-ip-address-on-android) – user1931849 Nov 06 '13 at 08:14
  • i added also logcat, but i didn't see nothing strange – user1931849 Nov 06 '13 at 09:02
  • I tried the code last night, with the required permission - I got my phone's MAC address and displayed it in a dialog. I assumed the permission was the last problem, given my unmitigated success with your code. – blong Nov 06 '13 at 09:20
  • i uploaded my test project, i already checked the permission but continue the same error with access violation. – user1931849 Nov 06 '13 at 10:01
  • Did you fix the . to / issue? I did in mine. Perhaps you can replace your logcat screenshot with one that shows the failure point as opposed to whatever is currently shown. Did you add in any nil checking? I've made a number of suggestions but you've only thus far suggested that you've checked the permissions. – blong Nov 06 '13 at 10:12
  • no, what i have to fix on the .to/ issue? the screenshot show the lines that appear when i click on the button that call that function – user1931849 Nov 06 '13 at 10:15
  • wifimanager is never nil after the wrap, istead the jwifiInfo is nil and when i call winfo:=wm.getconnectioninfo; i had access violation – user1931849 Nov 06 '13 at 10:17
  • 1
    Re separators, could you let me know what is unclear about "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." and I'll see if I can explain clearer. – blong Nov 06 '13 at 10:28
  • So your segmentation fault manifests as a message box - a handled exception? Rather than a full on crash & burn? It strikes me that if `winfo:=wm.getconnectioninfo` crashes, then the issue is with the WifiManager, not with WifiInfo. – blong Nov 06 '13 at 10:30
  • sorry! now i fixed all! I did not understand what you mean with "separator". (was the java signature)! now all works perfectly! thanks very much! – user1931849 Nov 06 '13 at 10:38
0

why did you use "Winfo:=TJWifiInfo.Create;"?!...you do not need to create it, it is the getconnectioninfo function that returns a jwifiinfo instance. Why not simply using "Winfo:=wm.getconnectioninfo;"

Bahaa
  • 123
  • 2
  • 9