Getting MAC address in Android 6.0 - android

I'm developing an app that gets the MAC address of the device, but since Android 6.0 my code doesn't work, giving me an incorrect value.
Here's my code...
public String ObtenMAC()
{
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
return(info.getMacAddress().toUpperCase());
}
Instead of the real MAC address, it returns an strange code: 02:00:00:00:00:00.

Please refer to Android 6.0 Changes.
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.

Use below code to get Mac address in Android 6.0
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(Integer.toHexString(b & 0xFF) + ":");
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
//handle exception
}
return "";
}

I didn't get the above answer to work, but stumbled upon another answer.
Here is a complete and simple method on getting the IPv6 address and then getting the mac address from it.
How to get Wi-Fi Mac address in Android Marshmallow
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
}
return "02:00:00:00:00:00";
}
Tested it already and it works. Many thanks to Rob Anderson!

this is the complete 2 ways code of getting it successfully on Marshmallow , just copy past this and it will work !
//Android 6.0 : Access to mac address from WifiManager forbidden
private static final String marshmallowMacAddress = "02:00:00:00:00:00";
private static final String fileAddressMac = "/sys/class/net/wlan0/address";
public static String recupAdresseMAC(WifiManager wifiMan) {
WifiInfo wifiInf = wifiMan.getConnectionInfo();
if(wifiInf.getMacAddress().equals(marshmallowMacAddress)){
String ret = null;
try {
ret= getAdressMacByInterface();
if (ret != null){
return ret;
} else {
ret = getAddressMacByFile(wifiMan);
return ret;
}
} catch (IOException e) {
Log.e("MobileAccess", "Erreur lecture propriete Adresse MAC");
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
} else{
return wifiInf.getMacAddress();
}
return marshmallowMacAddress;
}
private static String getAdressMacByInterface(){
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (nif.getName().equalsIgnoreCase("wlan0")) {
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
}
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
return null;
}
private static String getAddressMacByFile(WifiManager wifiMan) throws Exception {
String ret;
int wifiState = wifiMan.getWifiState();
wifiMan.setWifiEnabled(true);
File fl = new File(fileAddressMac);
FileInputStream fin = new FileInputStream(fl);
StringBuilder builder = new StringBuilder();
int ch;
while((ch = fin.read()) != -1){
builder.append((char)ch);
}
ret = builder.toString();
fin.close();
boolean enabled = WifiManager.WIFI_STATE_ENABLED == wifiState;
wifiMan.setWifiEnabled(enabled);
return ret;
}
manifest :
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Summary : this code will try to get the MAC address first by Interface and if its failed it get it by file system.
Note:for file System way, you need to enable WIFI to access the file.
thnx to Sam's answer here https://stackoverflow.com/a/39288868/3818437

You can get the MAC address from the IPv6 local address. E.g., the IPv6 address "fe80::1034:56ff:fe78:9abc" corresponds to the MAC address "12-34-56-78-9a-bc". See the code below. Getting the WiFi IPv6 address only requires android.permission.INTERNET.
See the Wikipedia page IPv6 address, particularly the note about "local addresses" fe80::/64 and the section about "Modified EUI-64".
/**
* Gets an EUI-48 MAC address from an IPv6 link-local address.
* E.g., the IPv6 address "fe80::1034:56ff:fe78:9abc"
* corresponds to the MAC address "12-34-56-78-9a-bc".
* <p/>
* See the note about "local addresses" fe80::/64 and the section about "Modified EUI-64" in
* the Wikipedia article "IPv6 address" at https://en.wikipedia.org/wiki/IPv6_address
*
* #param ipv6 An Inet6Address object.
* #return The EUI-48 MAC address as a byte array, null on error.
*/
private static byte[] getMacAddressFromIpv6(final Inet6Address ipv6)
{
byte[] eui48mac = null;
if (ipv6 != null) {
/*
* Make sure that this is an fe80::/64 link-local address.
*/
final byte[] ipv6Bytes = ipv6.getAddress();
if ((ipv6Bytes != null) &&
(ipv6Bytes.length == 16) &&
(ipv6Bytes[0] == (byte) 0xfe) &&
(ipv6Bytes[1] == (byte) 0x80) &&
(ipv6Bytes[11] == (byte) 0xff) &&
(ipv6Bytes[12] == (byte) 0xfe)) {
/*
* Allocate a byte array for storing the EUI-48 MAC address, then fill it
* from the appropriate bytes of the IPv6 address. Invert the 7th bit
* of the first byte and discard the "ff:fe" portion of the modified
* EUI-64 MAC address.
*/
eui48mac = new byte[6];
eui48mac[0] = (byte) (ipv6Bytes[8] ^ 0x2);
eui48mac[1] = ipv6Bytes[9];
eui48mac[2] = ipv6Bytes[10];
eui48mac[3] = ipv6Bytes[13];
eui48mac[4] = ipv6Bytes[14];
eui48mac[5] = ipv6Bytes[15];
}
}
return eui48mac;
}

I try to get mac address with 2 methods, first by Interface and if its failed, i get it by file system, but you need to enable wifi to access the file.
//Android 6.0 : Access to mac address from WifiManager forbidden
private static final String marshmallowMacAddress = "02:00:00:00:00:00";
private static final String fileAddressMac = "/sys/class/net/wlan0/address";
public static String recupAdresseMAC(WifiManager wifiMan) {
WifiInfo wifiInf = wifiMan.getConnectionInfo();
if(wifiInf.getMacAddress().equals(marshmallowMacAddress)){
String ret = null;
try {
ret= getAdressMacByInterface();
if (ret != null){
return ret;
} else {
ret = getAddressMacByFile(wifiMan);
return ret;
}
} catch (IOException e) {
Log.e("MobileAccess", "Erreur lecture propriete Adresse MAC");
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
} else{
return wifiInf.getMacAddress();
}
return marshmallowMacAddress;
}
private static String getAdressMacByInterface(){
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (nif.getName().equalsIgnoreCase("wlan0")) {
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
}
} catch (Exception e) {
Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
}
return null;
}
private static String getAddressMacByFile(WifiManager wifiMan) throws Exception {
String ret;
int wifiState = wifiMan.getWifiState();
wifiMan.setWifiEnabled(true);
File fl = new File(fileAddressMac);
FileInputStream fin = new FileInputStream(fl);
ret = convertStreamToString(fin);
fin.close();
boolean enabled = WifiManager.WIFI_STATE_ENABLED == wifiState;
wifiMan.setWifiEnabled(enabled);
return ret;
}
Add this line to your manifest.
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
I recommend you to persist your mac address in your preferences like here
mac = activity.getSharedPreferences("MAC_ADDRESS", Context.MODE_PRIVATE).getString("MAC_ADDRESS", "");
if(mac == null || mac.equals("")){
WifiManager wifiMan = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
mac = MobileAccess.recupAdresseMAC(wifiMan);
if(mac != null && !mac.equals("")){
SharedPreferences.Editor editor = activity.getSharedPreferences("MAC_ADDRESS", Context.MODE_PRIVATE).edit();
editor.putString("MAC_ADDRESS", mac).commit();
}
}

Its Perfectly Fine
package com.keshav.fetchmacaddress;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("keshav","getMacAddr -> " +getMacAddr());
}
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(Integer.toHexString(b & 0xFF) + ":");
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
//handle exception
}
return "";
}
}

First you need to add Internet user permission.
<uses-permission android:name="android.permission.INTERNET" />
Then you can find the mac over the NetworkInterfaces API.
public static String getMacAddr() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
}
return "02:00:00:00:00:00";
}

The answers are mostly correct, but keep care, that there is a change in android 7. You will need to use the
DevicePolicyManager and the Method getWifiMacAddress. The official docs has a typo, which means that you shouldnt copy/paste it from there.
DevicePolicyManager.getWifiMacAddress()
Refs:
https://developer.android.com/about/versions/nougat/android-7.0-changes.html
Get Device mac adress in Android Nougat and O programmatically

Use wifiInfo.getBSSID() to get Mac Address of AccessPoint instead of getMacAddress method.

This is a more kotlin way to get Mac Address
fun getMacAddress(): String =
NetworkInterface.getNetworkInterfaces().toList()
.firstOrNull { it.name.equals("wlan0", ignoreCase = true) }?.let {
it.hardwareAddress?.let { macBytes ->
StringBuilder().apply {
for (b in macBytes) {
append(String.format("%02X:", b))
}
if (isNotEmpty()) {
deleteCharAt(lastIndex)
}
}
}.toString()
} ?: "02:00:00:00:00:00"

Related

Wifi Direct - This device address not work on android 10

I use this method to get the MAC address of my device. This works well in Android 9 and below. But in Android 10, the MAC address is not given correctly and it gives this value every time: 02: 00: 00: 00: 00: 00
public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:
WifiP2pDevice device = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
Log.i("My device wifi direct Mac address", device.deviceAddress);
break;
}
}
}
public String getWFDMacAddress() {
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface ntwInterface : interfaces) {
if (ntwInterface.getName().equalsIgnoreCase("p2p0")) {
byte[] byteMac = ntwInterface.getHardwareAddress();
if (byteMac == null) {
return null;
}
StringBuilder strBuilder = new StringBuilder();
for (byte b : byteMac) {
strBuilder.append(String.format("%02X:", b));
}
if (strBuilder.length() > 0) {
strBuilder.deleteCharAt(strBuilder.length() - 1);
}
return strBuilder.toString();
}
}
} catch (Exception ignored) {
}
return null;
}

Is the procedure correct to write Characteristic in Bluetooth Low Energy?

I have a button in MainActivity which is used to write a byte[] to BLE device:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Write Char"
android:id="#+id/button2"
android:onClick="onClickWrite" />
And the function onClickWrite is
public void onClickWrite(View v){
if(mBluetoothLeService != null) {
byte [] data= new byte[3];
data[0] = (byte)(0 & 0xFF);
data[1] = (byte)(255 & 0xFF);
data[2] = (byte)(0 & 0xFF);
mBluetoothLeService.sendData(data);
}
}
where sendData is a modified function in class [BluetoothLeService][1]. It worked well when I press the button. However, Let is careful to look at the sendData function. It searches service and Characteristic again when I press the button. Is it correct procedure for write a Characteristic in BLE?
public void sendData(byte[] data){
String lService = "00001c00-d102-11e1-9b23-00025b00a5A5";
String lCharacteristic = "00001c03-d102-11e1-9b23-00025b00a5a5";
BluetoothGattService mBluetoothLeService = null;
BluetoothGattCharacteristic mBluetoothGattCharacteristic = null;
for (BluetoothGattService service : mBluetoothGatt.getServices()) {
if ((service == null) || (service.getUuid() == null)) {
Log.d("TAG","Something is null");
continue;
}
if (lService.equalsIgnoreCase(service.getUuid().toString())) {
Log.d("TAG","service.getUuid().toString()="+service.getUuid().toString());
mBluetoothLeService = service;
}
}
if(mBluetoothLeService!=null) {
mBluetoothGattCharacteristic =
mBluetoothLeService.getCharacteristic(UUID.fromString(lRgbCharacteristic));
}
else{
Log.d("TAG","mBluetoothLeService is null");
}
if(mBluetoothGattCharacteristic!=null) {
mBluetoothGattCharacteristic.setValue(data);
boolean write = mBluetoothGatt.writeCharacteristic(mBluetoothGattCharacteristic);
Log.d("TAG","writeCharacteristic:"+write);
}
else{
Log.d("TAG", "mBluetoothGattCharacteristic is null");
}
}
Yes.
(filling unnecessarily required length)

Android: Change gateway address of hot-spot

Is there a way to change the gateway address of the AP hot-spot feature of Android from 192.168.43.1 to something else such as 192.168.43.3 without recompiling anything? I have a rooted Android device.
You are trying to change the settings that have been hardcoded for android hotspot
This is from http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/net/wifi/WifiStateMachine.java
private boolean startTethering(ArrayList<String> available) {
boolean wifiAvailable = false;
checkAndSetConnectivityInstance();
String[] wifiRegexs = mCm.getTetherableWifiRegexs();
for (String intf : available) {
for (String regex : wifiRegexs) {
if (intf.matches(regex)) {
InterfaceConfiguration ifcg = null;
try {
ifcg = mNwService.getInterfaceConfig(intf);
if (ifcg != null) {
/* IP/netmask: 192.168.43.1/255.255.255.0 */
ifcg.setLinkAddress(new LinkAddress(
NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
ifcg.setInterfaceUp();
mNwService.setInterfaceConfig(intf, ifcg);
}
} catch (Exception e) {
loge("Error configuring interface " + intf + ", :" + e);
return false;
}
if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
loge("Error tethering on " + intf);
return false;
}
mTetherInterfaceName = intf;
return true;
}
}
}
// We found no interfaces to tether
return false;
}
Try check out this answer
https://android.stackexchange.com/questions/46499/how-configure-the-dhcp-settings-of-wifi-tetheringhotspot-in-android

How to get MAC Address of device using Wifi in Android

I want to access MAC Address of phone using Wifi. but somehow I could not get it right.
I have written following code.
context=this;
setContentView(R.layout.activity_main);
try{
WifiManager wifi=(WifiManager)this.context.getSystemService(context.WIFI_SERVICE);
wifi.setWifiEnabled(true);
WifiInfo info=wifi.getConnectionInfo();
String address=info.getMacAddress();
if(address==null){
Toast.makeText(context, "Null", Toast.LENGTH_LONG).show();
}
else{
new AsyncClass(MainActivity.this,address).execute();
}
}catch(Exception e){
Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
}
When I run this on my phone, it give me error that "Unfortunately Application Stopped"
When I run this program on Imulator, it always gives address is Null.
Please help me to get rid of it.
Thanks in advance.
My Manifest file is as below:
<uses-permission
android:required="true"
android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.INTERNET"/>
Please add a permission at manifest as follows
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
write a functin/method retrieveMacAddress as follows
public String retrieveMacAddress(Context context) {
WifiManager wimanager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String macAddress = wimanager.getConnectionInfo().getMacAddress();
if (macAddress == null) {
macAddress = "Device don't have mac address or wi-fi is disabled";
}
return macAddress;
}
Your code is working properly,just remove asyncTask Line and put Toast message. Then your code will run on device.its working properly. I have checked your code.i think you have to get error in async task.
try {
WifiManager wifi = (WifiManager) this
.getSystemService(this.WIFI_SERVICE);
wifi.setWifiEnabled(true);
WifiInfo info = wifi.getConnectionInfo();
String address = info.getMacAddress();
if (address == null) {
Toast.makeText(this, "Null", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, address, Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
}
public void uploadMacAddressTOserver(String address) {
new Thread(new Runnable() {
#Override
public void run() {
try {
CallWebserviceToUploadMacAddress(address);
} catch (IOException e) {
}
}
}).start();
}
You can use thread and upload your data to server. May be in AsyncTask some you have to pass some wrong parameter so it gives error.
This is my code and works well in android 5 +.
public static String getMacAddress() {
try {
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
// res1.append(Integer.toHexString(b & 0xFF) + ":");
res1.append(String.format("%02X:",b));
}
if (res1.length() > 0) {
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception ex) {
//handle exception
}
return "";
}

android turning on wifi programmatically

I am trying to turn add a wifi network programmatically and to connect to that network.
My code works fine if the wi-fi is already turned on.
If wi-fi is off, what i see wifimanager.addtonetwork() fails and when i see the wifi settings for the phone, i can see the status as scanning
If i try to connect again it works fine.
Please see code below.
Please help
private int changeNetwork(NetworkSetting setting) {
// If the SSID is empty, throw an error and return
if (setting.getSsid() == null || setting.getSsid().length() == 0) {
return doError(R.string.wifi_ssid_missing);
}
// If the network type is invalid
if (setting.getNetworkType() == NetworkType.NETWORK_INVALID) {
return doError(R.string.wifi_type_incorrect);
}
// If the password is empty, this is an unencrypted network
if (setting.getPassword() == null
|| setting.getPassword().length() == 0
|| setting.getNetworkType() == null
|| setting.getNetworkType() == NetworkType.NETWORK_NOPASS) {
return changeNetworkUnEncrypted(setting);
}
if (setting.getNetworkType() == NetworkType.NETWORK_WPA) {
return changeNetworkWPA(setting);
} else {
return changeNetworkWEP(setting);
}
}
private int doError(int resource_string) {
statusView.setText(resource_string);
// Give up on the connection
wifiManager.disconnect();
if (networkId > 0) {
wifiManager.removeNetwork(networkId);
networkId = -1;
}
if (receiverRegistered) {
unregisterReceiver(wifiReceiver);
receiverRegistered = false;
}
return -1;
}
private WifiConfiguration changeNetworkCommon(NetworkSetting input) {
statusView.setText(R.string.wifi_creating_network);
Log.d(TAG, "Adding new configuration: \nSSID: " + input.getSsid()
+ "\nType: " + input.getNetworkType());
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
// Android API insists that an ascii SSID must be quoted to be correctly
// handled.
config.SSID = NetworkUtil.convertToQuotedString(input.getSsid());
config.hiddenSSID = true;
return config;
}
private int requestNetworkChange(WifiConfiguration config) {
statusView.setText(R.string.wifi_changing_network);
return updateNetwork(config, false);
}
// Adding a WEP network
private int changeNetworkWEP(NetworkSetting input) {
WifiConfiguration config = changeNetworkCommon(input);
String pass = input.getPassword();
if (NetworkUtil.isHexWepKey(pass)) {
config.wepKeys[0] = pass;
} else {
config.wepKeys[0] = NetworkUtil.convertToQuotedString(pass);
}
config.allowedAuthAlgorithms
.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
return requestNetworkChange(config);
}
// Adding a WPA or WPA2 network
private int changeNetworkWPA(NetworkSetting input) {
WifiConfiguration config = changeNetworkCommon(input);
String pass = input.getPassword();
// Hex passwords that are 64 bits long are not to be quoted.
if (HEX_DIGITS_64.matcher(pass).matches()) {
Log.d(TAG, "A 64 bit hex password entered.");
config.preSharedKey = pass;
} else {
Log.d(TAG, "A normal password entered: I am quoting it.");
config.preSharedKey = NetworkUtil.convertToQuotedString(pass);
}
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
// For WPA
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
// For WPA2
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
return requestNetworkChange(config);
}
// Adding an open, unsecured network
private int changeNetworkUnEncrypted(NetworkSetting input) {
Log.d(TAG, "Empty password prompting a simple account setting");
WifiConfiguration config = changeNetworkCommon(input);
config.wepKeys[0] = "";
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.wepTxKeyIndex = 0;
return requestNetworkChange(config);
}
/**
* If the given ssid name exists in the settings, then change its password
* to the one given here, and save
*
* #param ssid
*/
private WifiConfiguration findNetworkInExistingConfig(String ssid) {
List<WifiConfiguration> existingConfigs = wifiManager
.getConfiguredNetworks();
Log.i("Start comparing","Size "+existingConfigs.size() );
for (WifiConfiguration existingConfig : existingConfigs) {
Log.i("Compare with SSID", ssid + existingConfig.SSID);
if (existingConfig.SSID.equals(ssid)) {
Log.i("Compare success with SSID", ssid + existingConfig.SSID);
return existingConfig;
}
}
return null;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
/* if (intent == null
|| !intent.getAction().equals(Intents.WifiConnect.ACTION)) {
finish();
return;
} */
String ssid = intent.getStringExtra("ssid");
String password = intent.getStringExtra("password");
String networkType = intent.getStringExtra("type");
setContentView(R.layout.network);
statusView = (TextView) findViewById(R.id.networkStatus);
NetworkType networkT;
if ("WPA".equals(networkType)) {
networkT = NetworkType.NETWORK_WPA;
} else if ("WEP".equals(networkType)) {
networkT = NetworkType.NETWORK_WEP;
} else if ("nopass".equals(networkType)) {
networkT = NetworkType.NETWORK_NOPASS;
} else {
networkT = NetworkType.NETWORK_INVALID;
}
// This is not available before onCreate
wifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE);
// Start WiFi, otherwise nothing will work
wifiManager.setWifiEnabled(true);
// So we know when the network changes
wifiReceiver = new WifiReceiver(wifiManager, this, statusView, ssid);
// The order matters!
mWifiStateFilter = new IntentFilter(
WifiManager.WIFI_STATE_CHANGED_ACTION);
mWifiStateFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mWifiStateFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
registerReceiver(wifiReceiver, mWifiStateFilter);
receiverRegistered = true;
if (password == null) {
password = "";
}
Log.d(TAG, "Adding new configuration: \nSSID: " + ssid + "Type: "
+ networkT);
NetworkSetting setting = new NetworkSetting(ssid, password, networkT);
changeNetwork(setting);
}
#Override
public void onPause() {
super.onPause();
if (receiverRegistered) {
unregisterReceiver(wifiReceiver);
receiverRegistered = false;
}
}
#Override
public void onResume() {
super.onResume();
if (wifiReceiver != null && mWifiStateFilter != null
&& !receiverRegistered) {
registerReceiver(wifiReceiver, mWifiStateFilter);
receiverRegistered = true;
}
}
#Override
protected void onDestroy() {
if (wifiReceiver != null) {
if (receiverRegistered) {
unregisterReceiver(wifiReceiver);
receiverRegistered = false;
}
wifiReceiver = null;
}
super.onDestroy();
}
/**
* Update the network: either create a new network or modify an existing
* network
*
* #param config
* the new network configuration
* #param disableOthers
* true if other networks must be disabled
* #return network ID of the connected network.
*/
private int updateNetwork(WifiConfiguration config, boolean disableOthers) {
WifiConfiguration found = findNetworkInExistingConfig(config.SSID);
wifiManager.disconnect();
if (found == null) {
Log.i("WIFI","SSID NOT FOUND");
statusView.setText(R.string.wifi_creating_network);
} else {
statusView.setText(R.string.wifi_modifying_network);
Log.d(TAG, "Removing network " + found.networkId);
wifiManager.removeNetwork(found.networkId);
wifiManager.saveConfiguration();
}
networkId = wifiManager.addNetwork(config);
Log.d(TAG, "Inserted/Modified network " + networkId);
if (networkId < 0) {
wifiManager.setWifiEnabled(true);
networkId = wifiManager.addNetwork(config);
Log.d(TAG, "Again Inserted/Modified network " + networkId);
return FAILURE_NO_NETWORK_ID;
}
// Try to disable the current network and start a new one.
if (!wifiManager.enableNetwork(networkId, disableOthers)) {
networkId = FAILURE_NO_NETWORK_ID;
return FAILURE_NO_NETWORK_ID;
}
errorCount = 0;
wifiManager.reassociate();
return networkId;
}
Here is my working code : ( its different from my previous code )
package com.idg.project.utils;
import java.util.List;
import java.util.regex.Pattern;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.util.Log;
/**
* #author Vikram Aggarwal
* #author Sean Owen
*/
public final class WifiConfigManager {
private static final String TAG = WifiConfigManager.class.getSimpleName();
private static final Pattern HEX_DIGITS = Pattern.compile("[0-9A-Fa-f]+");
private WifiConfigManager() {
}
public static void configure(final WifiManager wifiManager,
final String ssid,
final String password,
final String networkTypeString) {
Runnable configureRunnable = new Runnable() {
public void run() {
// Start WiFi, otherwise nothing will work
if (!wifiManager.isWifiEnabled()) {
Log.i(TAG, "Enabling wi-fi...");
if (wifiManager.setWifiEnabled(true)) {
Log.i(TAG, "Wi-fi enabled");
} else {
Log.w(TAG, "Wi-fi could not be enabled!");
return;
}
// This happens very quickly, but need to wait for it to enable. A little busy wait?
int count = 0;
while (!wifiManager.isWifiEnabled()) {
if (count >= 10) {
Log.i(TAG, "Took too long to enable wi-fi, quitting");
return;
}
Log.i(TAG, "Still waiting for wi-fi to enable...");
try {
Thread.sleep(1000L);
} catch (InterruptedException ie) {
// continue
}
count++;
}
}
NetworkType networkType = NetworkType.forIntentValue(networkTypeString);
if (networkType == NetworkType.NO_PASSWORD) {
changeNetworkUnEncrypted(wifiManager, ssid);
} else {
if (password == null || password.length() == 0) {
throw new IllegalArgumentException();
}
if (networkType == NetworkType.WEP) {
changeNetworkWEP(wifiManager, ssid, password);
} else if (networkType == NetworkType.WPA) {
changeNetworkWPA(wifiManager, ssid, password);
} }
}
};
new Thread(configureRunnable).start();
}
/**
* Update the network: either create a new network or modify an existing network
* #param config the new network configuration
* #return network ID of the connected network.
*/
private static void updateNetwork(WifiManager wifiManager, WifiConfiguration config) {
Integer foundNetworkID = findNetworkInExistingConfig(wifiManager, config.SSID);
if (foundNetworkID != null) {
Log.i(TAG, "Removing old configuration for network " + config.SSID);
wifiManager.removeNetwork(foundNetworkID);
wifiManager.saveConfiguration();
}
int networkId = wifiManager.addNetwork(config);
if (networkId >= 0) {
// Try to disable the current network and start a new one.
if (wifiManager.enableNetwork(networkId, true)) {
Log.i(TAG, "Associating to network " + config.SSID);
wifiManager.saveConfiguration();
} else {
Log.w(TAG, "Failed to enable network " + config.SSID);
}
} else {
Log.w(TAG, "Unable to add network " + config.SSID);
}
}
private static WifiConfiguration changeNetworkCommon(String ssid) {
WifiConfiguration config = new WifiConfiguration();
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
// Android API insists that an ascii SSID must be quoted to be correctly handled.
config.SSID = quoteNonHex(ssid);
return config;
}
// Adding a WEP network
private static void changeNetworkWEP(WifiManager wifiManager, String ssid, String password) {
WifiConfiguration config = changeNetworkCommon(ssid);
config.wepKeys[0] = quoteNonHex(password, 10, 26, 58);
config.wepTxKeyIndex = 0;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
updateNetwork(wifiManager, config);
}
// Adding a WPA or WPA2 network
private static void changeNetworkWPA(WifiManager wifiManager, String ssid, String password) {
WifiConfiguration config = changeNetworkCommon(ssid);
// Hex passwords that are 64 bits long are not to be quoted.
config.preSharedKey = quoteNonHex(password, 64);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
updateNetwork(wifiManager, config);
}
// Adding an open, unsecured network
private static void changeNetworkUnEncrypted(WifiManager wifiManager, String ssid) {
WifiConfiguration config = changeNetworkCommon(ssid);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
updateNetwork(wifiManager, config);
}
private static Integer findNetworkInExistingConfig(WifiManager wifiManager, String ssid) {
List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
for (WifiConfiguration existingConfig : existingConfigs) {
if (existingConfig.SSID.equals(ssid)) {
return existingConfig.networkId;
}
}
return null;
}
private static String quoteNonHex(String value, int... allowedLengths) {
return isHexOfLength(value, allowedLengths) ? value : convertToQuotedString(value);
}
/**
* Encloses the incoming string inside double quotes, if it isn't already quoted.
* #param string the input string
* #return a quoted string, of the form "input". If the input string is null, it returns null
* as well.
*/
private static String convertToQuotedString(String string) {
if (string == null || string.length() == 0) {
return null;
}
// If already quoted, return as-is
if (string.charAt(0) == '"' && string.charAt(string.length() - 1) == '"') {
return string;
}
return '\"' + string + '\"';
}
/**
* #param value input to check
* #param allowedLengths allowed lengths, if any
* #return true if value is a non-null, non-empty string of hex digits, and if allowed lengths are given, has
* an allowed length
*/
private static boolean isHexOfLength(CharSequence value, int... allowedLengths) {
if (value == null || !HEX_DIGITS.matcher(value).matches()) {
return false;
}
if (allowedLengths.length == 0) {
return true;
}
for (int length : allowedLengths) {
if (value.length() == length) {
return true;
}
}
return false;
}
}
package com.idg.project.utils;
enum NetworkType {
WEP,
WPA,
NO_PASSWORD;
static NetworkType forIntentValue(String networkTypeString) {
if (networkTypeString == null) {
return NO_PASSWORD;
}
if ("WPA".equals(networkTypeString)) {
return WPA;
}
if ("WEP".equals(networkTypeString)) {
return WEP;
}
if ("nopass".equals(networkTypeString)) {
return NO_PASSWORD;
}
throw new IllegalArgumentException(networkTypeString);
}
}
You can turn on/off wifi using following instructions :
WifiManager wManager = (WifiManager)this.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wManager.setWifiEnabled(booleanValue); //true or false
Set following permissions to your manifest:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE">
This code is deprecated in API 29 or over
public boolean setWifiEnabled (boolean enabled)
**This method was deprecated in API level 29**.
Starting with Build.VERSION_CODES#Q, applications are not allowed to
enable/disable Wi-Fi. Compatibility Note: For applications targeting
Build.VERSION_CODES.Q or above, this API will always return false and
will have no effect. If apps are targeting an older SDK (
Build.VERSION_CODES.P or below), they can continue to use this API.
Source : Link
You need to create wifiLock with WIFI_MODE_FULL_HIGH_PERF mode, based on the docs it will only work with the following constraints:
The lock is only active when the device is connected to an access point.
The lock is only active when the screen is on.
The lock is only active when the acquiring app is running in the foreground.

Categories

Resources