BUG or Normal Behavior on Android MAC-Address? - android

I am trying to get the MAC address, BSSID and LINK_speed of the Wifi. I notice that all three show up with values even when Wifi is turned off. I turn the phone off and then on again but do not turn wifi on. The app crashes on any interrogation of the three items and I cant try/catch the errors. If I turn wifi on then off I can interrogate the items and app runs fine. Its like BSSID and LINKSPEED are really 'LAST'BSSID and 'LAST'LINKSPEED. Is being blind to the MAC address after power on but not turning wifi on normal behavior? And is there a way to trap the error to keep from force close of the app?
WifiManager wifi;
wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifi.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
ipAddress = wifiInfo.getIpAddress();
//above work no matter whether wifi on or off before
String BSSID=wifiInfo.getBSSID(); //<<<<< ERRORS FORCE CLOSE IF NOT EVER CONNECTED
int WifiLinkSpeed=wifiInfo.getLinkSpeed(); printi("link speed",WifiLinkSpeed);
String MacAddress=wifiInfo.getMacAddress(); Log.e("MAC address",MacAddress);
//All three of these FORCE close if WIFI has never been turn on

Try this,
WifiManager wifiManager = (WifiManager) Settings.cntxt.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
strMacAddr = wifiInfo.getMacAddress();
if(strMacAddr==null) {
strMacAddr = "Unknown MAC";
}

Although you did say you tried try/catch... which errors/exceptions are you catching? Evidently not the right one(s).
It's been a while since I did any Android programming, but that's the crux of the matter... figuring out which exception is firing when you try those functions.
try {
// don't declare variables inside block, you'll limit scope
BSSID=wifiInfo.getBSSID(); //<<<<< ERRORS FORCE CLOSE IF NOT EVER CONNECTED
WifiLinkSpeed=wifiInfo.getLinkSpeed(); printi("link speed",WifiLinkSpeed);
MacAddress=wifiInfo.getMacAddress(); Log.e("MAC address",MacAddress);
//All three of these FORCE close if WIFI has never been turn on
}
catch { /* something bad happened, handle it */ }
// continue on since all is good in the world today...

Related

Inconsistent result of WifiInfo#getBssid() behavior

I am trying to define WiFi connection state on its changing. But I need a bit more - to get BSSID for WiFi network.
I didn't use BroadcastReceiver approach, instead I just poll WifiInfo#getBssid() every second. Most of time it works correct, but after my phone goes sleep for relatively long time (>~hour) WifiInfo#getBssid() returns null when my phon is connected to the WiFi.
public String getBssid() {
WifiManager wifiMgr = (WifiManager);
getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
String bssid = wifiInfo.getBSSID();
}
I call this function from Qt code via JNI.
The problem is not in Android but in Qt. I used QNetworkConfigurationManager as a member of my NetworkMonitor class and checked QNetworkConfigurationManager#defaultConfiguration().bearerType() == QNetworkConfiguration::BearerWLAN prior to check bssid. So, the bearerType was returning wrong value after device sleep-wakeup until I implemented recreation of QNetworkConfigurationManager instance on every wakeup.

How to save access point settings in android 7 programatically

I'm working on an app that creates a hotspot as soon as it starts up.
This has benn working fine until Android 7 Nougat came.
I'm using the WifiApManager class.
Like I said everything worked perfect but when using API 25 the hotspot is created with the correct settings (ssid, password, etc.) and my laptop recognizes it and connects .
However it has "no Internet" hence no data exchange happens. Waht I need to do is to go to the phones hotspot settings and press save. It will turn of and on again and eventually work as it should.
I don't know if this is an android bug or is it intentional but I belive there was no "save" button in previous API's!? I have been searching the web but couldn't find anything. Thanks in advance. kEbO
public static boolean setHotspotNameAndPassword(String newName,String password, Context context) {
try {
WifiManager wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
Method getConfigMethod = wifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration wifiConfig = (WifiConfiguration) getConfigMethod.invoke(wifiManager);
wifiConfig.preSharedKey=password;
wifiConfig.SSID = newName;
Method setConfigMethod = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
setConfigMethod.invoke(wifiManager, wifiConfig);
return true;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
It is work for me! Change setting.
but I can't find way to turn on/off Hotspot on Android 7.0+

failed to connect to specific WiFi in android programmatically

I'm using the following code to detect and connect to specific WiFi ssid when I press a button in android. Below is the code. Any help will be appreciated.
ssid :- "myHotspot" & password:- "12345678"
Button b1 = (Button) findViewById(R.id.button); <br>
b1.setOnClickListener(new View.OnClickListener() {
<br><br>#Override
<br>public void onClick(View v) {
wifiConfiguration.SSID = "\"myHotspot\"";
wifiConfiguration.preSharedKey ="\"12345678\"";
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
int netId = wifiManager.updateNetwork(wifiConfiguration);
if (wifiManager.isWifiEnabled()) { //---wifi is turned on---
//---disconnect it first---
wifiManager.disconnect();
} else { //---wifi is turned off---
//---turn on wifi---
wifiManager.setWifiEnabled(true);
}
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
}
});
The main problem I'm getting is that my phone gets connected to the ssid and after 2-3 seconds it loses the connection and gets connected to my home Wifi router (which has internet connectivity)
Note:- The ssid I'm trying to connect is just a local hotspot without any internet connection.
and if I try with "addNetwork(wifiConfiguration)" it creates multiple networks of the same name. so Now how do I resolve this ?!
I think the problem here is you try to enableNetwork immediately after the call to wifiManager.setWifiEnabled(true). Generally, switching on wifi will take 5-10 seconds depending on the device, until then any call to wifiManager.enableNetwork will be lost. Hence, your call to connect to the desired network is getting lost and as soon as the wifi is switched on, your device connects to the last network it remembers.
Try to create a loop where you keep checking if wifiManager.isWifiEnabled() == true and keep looping until it returns true (with Thread.sleep() obviously and doing this in an AsyncTask or separate Thread). Only after that try to call enableNetwork.

Android wifimanager.startscan() in main thread or in background?

What philosophy of startscan is better to use when i wanna get list of available wifi network?
I'm do this in main thread:
List<ScanResult> wifiList;
wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) wifiManager.setWifiEnabled(true);
wifiManager.startScan();
wifiList = wifiManager.getScanResults();
for (int i = 0; i < wifiList.size(); i++) {
String[] networkInfo = wifiList.get(i).toString().split(",");
if (networkInfo[0].trim().equals(AP_SEARCH_SSID))
petcub_networks++;
}
In all device which i'm use for test, it's work fine, except few samsung smartphone. It's happened on customer device and i can't debug it quickly.
Is some one have same problem with samsung? Or will be better scan AP in background? Can it solve my problem?
**UPD:**Essence of my problem in next: i'm wanna scan available wifi networks, then if needs network was found i'm make connect to it(to socket). This procedure used in pipeline like first step.
I'm sorry to inform you but the code snippets had lots of missing elements (in term of efficiency) and is also incorrect, Let me elaborate this in points:
startScan() only request a scan from the OS , it does not initiate a scan right away in some cases. so you need to check the return boolean from the call
Before calling startScan you should register a BroadcastReceiver for WifiManager.SCAN_RESULTS_AVAILABLE_ACTION and only in after that even you should get the results
You might not need to initiate a scan at a lot. a relatively fresh result may already be available. You can take a look on the timestamp value (API 17) of ScanResult to estimate how "fresh" the scan is
You don't check if the device has WIFI hardware at all
You only initiate a scan if the Wifi is on, Android devices (since API 16 I think) can scan for networks even if the WIFI is off
To check if you can initiate a scan use this (In a function the returns boolean):
if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
return false;
}
WifiManager mWifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
boolean ret = mWifiManager.isWifiEnabled();
ret = ret || ((android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) &&
mWifiManager.isScanAlwaysAvailable());
return ret;

Wifi getSSID() returns null

I use getSSID() to get the name of the wifi network as soon as a new connection is made.
But sometimes I get null for that value. This is my code:
Permissions in manifest are correct, because, as I said, most of the times it works.
I use this filter for the broadcast receiver:
<action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
In the broadcast I do this:
if("android.net.wifi.supplicant.CONNECTION_CHANGE".equals(intent.getAction()))
{ boolean bConected = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false);
if(bConnected == true)
{ WifiManager wifi = (WifiManager) Contexto.getSystemService(Context.WIFI_SERVICE);
String MyName = wifi.getConnectionInfo().getSSID();
Sometimes MyName is null here even if Wifi is connected correctly
}
}
Any ideas?
I use similar code regularly and I have never received null when connected.
Here is my code:
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
String myName = info.getSSID();
Therefore, I propose that you should wait 400 to 1000ms or so after receipt of the CONNECTION_CHANGE broadcast before requesting the information.
Here is one example that will implement the delay:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
String myName = info.getSSID();
}
}, 1000);
The Android Developers website states that :
The SSID may be null if there is no network currently connected.
You're listening to a CONNECTION_CHANGE event, what if the state of the connection changed from connected to disconnected ?
Wifi devices gets sometimes disconnected from an access point and they do reconnect silently without you even noticed it was disconnected.
I've found out the hard way that the supplicant subsystem is only relevant to the WPA security mechanism, and is really not a good choice to use for monitoring general wifi connection status. The verbiage in the documentation would lead you to believe that it's possible, but I had a lot of trouble when trying to use the supplicant actions, including issues similar to the one you describe.
From the SupplicantState enum documenation:
These enumeration values are used to indicate the current
wpa_supplicant state. This is more fine-grained than most users will
be interested in. In general, it is better to use NetworkInfo.State.
Using the NETWORK_STATE_CHANGED_ACTION and looking at the NetworkInfo extra I was able to get expected, stable behavior.

Categories

Resources