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
Related
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.
I have been trying to use an react native ble librairie (react-native-ble-manager). In order to use this the user have to allow location permission (as explain in the documentation android.permission.ACCESS_COARSE_LOCATION and android.permission.ACCESS_FINE_LOCATION if android API >= 29.
I request the autorisation as their example with:
(PermissionsAndroid is from the react-native librairie) :
if (Platform.OS === 'android' && Platform.Version >= 23) {
PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("Permission is OK");
} else {
PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("User accept");
} else {
console.log("User refuse");
}
});
}
});
}
On my device the pop-up ask me for the autorisation with only two choices :
Only when the application is running
Refuse
But with their example I have 3 choices the two others and "always authorise"
And for some reason I'm not able to scan peripheral if I don't always approve (I have been able to change to always for my application by going in the settings of it).
Part of my android manifest (android/app/src/main) (as you can see I have background_location)
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
I'm sure I'm missing an obvious thing but I can't see what..
In advance thank you :)
For those having the same issue : my phone has android 11 so it can't be directly requested in the pop-up.
You have to indicate to your user how to change the permission
Source : https://developer.android.com/training/location/permissions
I just cannot get Android to scan for Bluetooth devices. I've tried several different approaches, but none of them work. Here is my latest code.
// Create a BroadcastReceiver for ACTION_FOUND.
devicesFoundReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
devicesListArray.add(deviceName + "\n" + deviceHardwareAddress);
arrayAdapter.notifyDataSetChanged();
}
}
};
I register the receiver like this:
_thisContext.registerReceiver(devicesFoundReceiver, filter);
My manifest has these permissions:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
I call
bluetoothAdapter.startDiscovery();
OnReceive on the broadcastreceiver NEVER fires.
I'm tired of looking at bajillion different websites, some with the same approach, other's don't. But NONE of them work. What am I doing wrong?
Here is the SDK version for reference:
minSdkVersion 26
targetSdkVersion 30
The Bluetooth related actions of mobile phones have nothing to do with net. Your problems are generally caused by the lack of authorized location permissions. When targetsdkversion 23 or above, you need to dynamically request mobile location permission“ android.permission.ACCESS_ FINE_ Location "can search for Bluetooth devices nearby. Of course, you can reduce the targetsdkversion version of the project to below 23. In this way, you do not need to apply for permission dynamically.
Here are some good dynamic permission application open source library, I hope to help you:
https://github.com/googlesamples/easypermissions
https://github.com/permissions-dispatcher/PermissionsDispatcher
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'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