Good afternoon. For a very long time I have been trying to get a list of wi-fi networks using WifiManager. When I try to get through a virtual device, I get only one fictional network with an SSID: Android Wifi. However, I do not receive networks from my real environment. When using a real device, it is not possible to get any network.
What is the mistake?
Rights in AndroidManifest:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
The code I use to work with Wifi:
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiManager.startScan();
List<ScanResult> availNetworks = wifiManager.getScanResults();
Log.d("STRING",Integer.toString(availNetworks.size()));
if (availNetworks.size() > 0) {
for (int i=0; i< availNetworks.size();i++) {
String buf = availNetworks.get(i).toString();
String[] buflist = buf.split(",");
Log.d("STRING","In");
String elementWssid = buflist[0];
String elementWsec = buflist[2];
String elementWlevel = buflist[3];
String SSID = elementWssid.split(": ")[1];
String Sec = elementWsec.split(": ")[1];
String level = elementWlevel.split(": ")[1];
Log.d("STRING",SSID);
Log.d("STRING",Sec);
Log.d("STRING",level);
}
}
Permits have already been issued.
Solved a problem. In the application settings there is such a section as "other permissions". It contains permissions to work with wi-fi, which by default are in the "ask" status, after changing the status to "allow" the problem was solved. For some reason, android doesn't feel the need to ask for permissions like location.
P.s.
Xiaomi has a separate slider to access the location of ALL apps, it needs to be turned on to give permissions.
AndroidWifi on a virtual device is a test network for checking the performance of applications, since it does not know how to work with real networks.
Related
With the release of API level 26, my app's core functionality broke, this being, changing the users' hotspot setting within the application.
To get and set this configuration I am using the following functions from the WifiManager hidden api: getWifiApConfiguration and setWifiApConfiguration.
Method getWifiApConfiguration = wifiManager.getClass().getMethod("getWifiApConfiguration");
getWifiApConfiguration.invoke(wifiManager);
This is working with devices prior to Android O, but in this version I get the following error:
App not allowed to read or update stored WiFi Ap config (uid = 10168)
The permissions I have declared in the manifest are:
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.NETWORK_STACK"/>
<uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
How can I do this with the latest APIs?
As of Android Oreo (26), a new permission check was added to the service implementation of the getWifiApConfiguration() method:
Snippet from WifiServiceImpl.java
/**
* see {#link WifiManager#getWifiApConfiguration()}
* #return soft access point configuration
* #throws SecurityException if the caller does not have permission to retrieve the softap
* config
*/
#Override
public WifiConfiguration getWifiApConfiguration() {
enforceAccessPermission();
int uid = Binder.getCallingUid();
// only allow Settings UI to get the saved SoftApConfig
if (!mWifiPermissionsUtil.checkConfigOverridePermission(uid)) {
// random apps should not be allowed to read the user specified config
throw new SecurityException("App not allowed to read or update stored WiFi Ap config "
+ "(uid = " + uid + ")");
}
mLog.trace("getWifiApConfiguration uid=%").c(uid).flush();
return mWifiStateMachine.syncGetWifiApConfiguration();
}
Digging into the code you will quickly find out that to successfully invoke this method your application must hold the android.permission.OVERRIDE_WIFI_CONFIG permission that is a system level protected permission:
Snippet from framework AndroidManifest.xml
<!-- #SystemApi #hide Allows an application to modify any wifi configuration, even if created
by another application. Once reconfigured the original creator cannot make any further
modifications.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
android:protectionLevel="signature|privileged" />
This means that your application needs to be signed by the platform key or be privileged to use this API.
I am using this code to get MAC ADDRESS and display it in my app. The code works fine for all devices except most latest devices and ANDROID BOX.
it shows null for ANDROID BOX and other latest device.
Here is code:
public static String getWifiMacAddress() {
try {
String interfaceName = "wlan0";
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
if (!intf.getName().equalsIgnoreCase(interfaceName)){
continue;
}
byte[] mac = intf.getHardwareAddress();
if (mac==null){
return "";
}
StringBuilder buf = new StringBuilder();
for (byte aMac : mac) {
buf.append(String.format("%02X:", aMac));
}
if (buf.length()>0) {
buf.deleteCharAt(buf.length() - 1);
}
return buf.toString();
}
} catch (Exception ex) { } // for now eat exceptions
return "";
}
I have written these permissions in manifest file
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Firstly u will check the permission is granted or not?
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String macAddress = wInfo.getMacAddress();
Also, add below permission in your manifest file
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
Please refer this link for 6.0 marshmalow
First you will need to add Internet user permission in AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET" />
and then Refer this to get mac address: http://robinhenniges.com/en/android6-get-mac-address-programmatically
And if it doesn't works then refer this Android 6.0 changes
from this i have concluded that,
To provide users with greater data protection, starting in this
release, Android removes programmatic access to the device’s local
hardware identifier for apps using the Wi-Fi and Bluetooth APIs. The
WifiInfo.getMacAddress() and the BluetoothAdapter.getAddress() methods
now return a constant value of 02:00:00:00:00:00.
To access the hardware identifiers of nearby external devices via
Bluetooth and Wi-Fi scans, your app must now have the
ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions.
Note That : you can't get your own MACs even having those permissions. Read carefully, It is said that you can get other devices MACs having those permissions, but not your own.
As in 6.0 and above adding permission in Manifest alone wont work. You should have runtime permission and grant it if not granted.
Check this link:
https://stackoverflow.com/a/30549756/3910281
A fundamental question I have been concerned about is whether or not it would be possible to connect to a WiFi network within the Android code, considering the conventional way Google Glass connects to a network with QR codes. If it is possible, my saving grace would be a snippet of code that would allow me to connect to a specified network with SSID and a key. That way I can communicate and send data through sockets or some other method.
For testing purposes I have tried connecting to my laptop's WiFi hotspot before trying to connect to the Arduino, but to no avail. Here is the code in the ConnectActivity.java file so far:
package josuablom.gimbalcontrol;
+import...
public class ConnectActivity extends Activity
{
private CardScrollView mCardScroller;
private List<Card> mCards;
private GestureDetector mGestureDetector;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect);
}
public ConnectActivity()
{
//Code to connect to wifi
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
// setup a wifi configuration
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"JosuaLaptop\"";
wc.preSharedKey = "\"123456789\"";
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
// connect to and enable the connection
int netId = wifiManager.addNetwork(wc);
wifiManager.enableNetwork(netId, true);
wifiManager.setWifiEnabled(true);
}
}
Please bare in mind that I did not write the code in the ConnectActivity() method, but I got it from another thread on stackoverflow, so I do not have a fundamental understanding of how it works, although I can follow the logic.
The permissions in my manifest looks like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="josuablom.gimbalcontrol" >
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
...
Please excuse my ignorance, this is part of a undergraduate thesis project, and the focus of my project is the design of a system, not to become a Android expert. I have wasted far too much time trying to figure out how to solve this problem.
My target is to get all neighboring cell towers information like cell id, cell lac and RSS values, I used the class telephonyManager.getNeighboringCellInfo() to get required information but it return null every time.
But, I succeeded to get the nearest single cell tower information which connected to mobile (i.e serving cell) using telephonyManager.getCellLocation().
I tried to fix this problem and searched on every thing related it, then we found that all samsung devices can not support telephonyManager.getNeighboringCellInfo() class and it does not apply on Samsung but its working on HTC and LG devices.
See this:
https://code.google.com/p/android/issues/detail?id=24136
I need to apply it on Samsung Android devices and getting neighboring cells information. Can anyone tell me how I can do that?
Single cell code:
if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
cellLocation = (GsmCellLocation)telephonyManager.getCellLocation();
if(cellLocation!=null){
int cell_ID = cellLocation.getCid();
int cell_psc= cellLocation.getPsc();
int cell_lac =cellLocation.getLac();
cell_info.setText("Cell_ID: "+ String.valueOf(cell_ID) +"\n"+"Cell_psc: "+ String.valueOf(cell_psc)+"\n"+
"Cell_lac: " +String.valueOf(cell_lac)+"\n"+cellLocation.toString());
}
}
neighboring cell code:
List<NeighboringCellInfo> neighboringCellInfos = telephonyManager.getNeighboringCellInfo();
for(NeighboringCellInfo neighboringCellInfo : neighboringCellInfos)
{
neighboringCellInfo.getCid();
neighboringCellInfo.getLac();
neighboringCellInfo.getPsc();
neighboringCellInfo.getNetworkType();
neighboringCellInfo.getRssi();
neibouring_cell_information.add(neighboringCellInfo.getCid()+"\n"+ neighboringCellInfo.getRssi());
}
Toast.makeText(getApplicationContext(),neibouring_cell_information +"ok" , Toast.LENGTH_LONG).show();
all added permissions:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
It seems Samsung phones not supporting neighbor display. Please check this forum:
http://www.finetopix.com/showthread.php?30787-G-NetTrack-Android-OS-Netmonitor/page2
The developer of this app said that samsung chips not supporting commands for display neighbors.
As #Ayman said most of samsung phones and also some other phones not support getNeigbouringCells()
The cellid implementation varies from mobile device to mobile device since these features are considered to be optional. for example:
Samsung (all devices): getNeigbouringCells () is not supported at all and always returns an empty list.
according to this: http://wiki.opencellid.org/wiki/Android_library
and this:
https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=24306
I'm reading existing Wi Fi configuration.
Code is pretty decent
WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configurations= null;
if (wifiMgr != null)
{
configurations = wifiMgr.getConfiguredNetworks();
}
I have necessary permissions:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
The problem is- all (at least in my case) BSSIDs in the WifiConfiguration is NULL, despite the fact that BSSID (MAC) can be seen in the Settings.
What could be the problem and how to fix it?
Alternative question- where to get code for Setting's Wifi Settings (Gingerbread), as it does show BSSIDs