Retrieving MAC Address Programmatically - Android - java

I'm having an issue with retrieving the MAC address of the device programatically, before anyone mentions anything about other posts I have read them already such as:
How to find MAC address of an Android device programmatically
however I tried using the code with my own application and tested it with a simple log.d, only to find that it is returning nothing. The message of "seeing if this works shows" but nothing else. So i am presuming the mac address is null.
Log.d("seeing if this works", macAddress2);
The code of what I have done is shown here:
//Set onclick listener for the Get Mac Address button
getMac.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String macAddress2 = wInfo.getMacAddress();
macAddress.setText(macAddress2);
}
});

Which Android version are you testing on? The latest(10/2015) Android M preview has blocked the app from getting the hardware identifiers for Wifi and Bluetooth.
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.
There is a workaround by reading the Wifi MAC from /sys/class/net/wlan0/address, which however will also be blocked in the Android N as claimed by Google.

Try this:
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) {
}
return "02:00:00:00:00:00";
}
From here:
http://robinhenniges.com/en/android6-get-mac-address-programmatically
Works for me.

Do you have this in the manifest?
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Related

trying to customize hotspot SSID but stuck at WifiConfiguration

I'm trying to make an app on android studio that can customize the user's hotspot name (SSID), but found that WifiConfiguration was deprecated. I'm not sure about the difference between "NetworkSpecifier" and "WifiNetworkSuggestion", and how to use them to fix this. I'm new to android studio and I couldn't find a similar solution. Can anyone teach me what should I do? Or is it possible to customize it?
`
public void configureHotspot(String name) {
WifiConfiguration apConfig = new WifiConfiguration();
apConfig.SSID = name;
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
try {
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
Log.d(TAG, "setWifiApConfiguration - success? " + status);
} catch (Exception e) {
Log.e(TAG, "Error in configureHotspot");
e.printStackTrace();
}
}
`
This part of the code is from this example: "https://github.com/aegis1980/WifiHotSpot", in "MyOreoWifiManager.java".
(this is the only example I found that can successfully turn on my phone's hotspot.)
I think I could keep the try-and-catch part because "WifiManager" is not deprecated, so maybe the problem is at apConfig only.

Cannot use WifiP2pManager.setDeviceName on Android 11 (Wi-Fi Direct)

My team and I are working with Wi-Fi Direct technology on Android devices. Until now, the used devices were on Android 8, 9 and 10. We were able to change the Wifi P2P device name of the devices via the WifiP2pManager.setDeviceName method.
Unfortunately, from Android 11 it is impossible to call this method without system permissions.
I came here to ask you if there is a solution to change the WifiP2p device name of non-rooted Android 11 devices programmatically.
If not, is there an alternative to Wi-Fi Direct (excepted Bluetooth) supported from Android 8 on which you can start a connection between two (or more) devices, communicate and send files programmatically without a connection to the internet?
Thank you
Maybe now it's too late but just in case :
We had to use reflection to change our device names.
We're using this implementation :
public void setDeviceName(String name) {
if(name.length() > 32) { // Name size limit is 32 chars.
name = name.substring(0, 32);
}
Class[] paramTypes = new Class[3];
paramTypes[0] = WifiP2pManager.Channel.class;
paramTypes[1] = String.class;
paramTypes[2] = WifiP2pManager.ActionListener.class;
Object[] argList = new Object[3];
argList[0] = mChannel; // Your current channel
argList[1] = name;
argList[2] = new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d(TAG, "Wifi name successfully set to " + name);
}
#Override
public void onFailure(int reason) {
Log.e(TAG, "Device name set failed: reason = " + reason);
}
};
try {
Method setDeviceNameMethod = WifiP2pManager.class.getMethod("setDeviceName", paramTypes);
setDeviceNameMethod.setAccessible(true);
setDeviceNameMethod.invoke(mWifiP2pMgr, argList);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException |
IllegalArgumentException e) {
Log.e(TAG, "Exception while trying to set device name.\n" + e.toString());
}
}

Discovering all services on the network using jmDNS on Android

I'm using the jmdns.jar from this project https://github.com/twitwi/AndroidDnssdDemo in my Android project.
I'm currently trying to find all services on my network. I can't use Android NSD, so please avoid suggesting it as a solution.
protected Object doInBackground(Object[] params) {
try {
WifiManager wifi = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);
final InetAddress deviceIpAddress = InetAddress.getByName(Formatter.formatIpAddress(wifi.getConnectionInfo().getIpAddress()));
multicastLock = wifi.createMulticastLock(getClass().getName());
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
jmDNS = JmDNS.create(deviceIpAddress, "Android Device Discovery");
jmDNS.addServiceListener("_http._tcp.local.", new ServiceListener() {//_services._dns-sd._udp _http._tcp.local. _workstation._tcp.local.
#Override
public void serviceAdded(ServiceEvent serviceEvent) {
jmDNS.requestServiceInfo("", "", 1000);
}
#Override
public void serviceRemoved(ServiceEvent serviceEvent) {
}
#Override
public void serviceResolved(ServiceEvent serviceEvent) {
System.out.println(serviceEvent.getInfo().getHostAddress());
System.out.println(serviceEvent.getInfo().getName());
}
});
}catch(IOException e) {
Log.e(TAG, e.getMessage(), e);
}
}
The above code gives me the address and name of a printer on my network. That's great. What I would like is a TYPE that will catch all the services being broadcasted on my network. Android NSD had a _services._dns-sd._udpthat could be used for the type of service and find all services on the network. This doesn't work with jmDNS. I can't find anything in the limited documentation about this.
Do I need to go through and add all the service types myself? That is not a very clean solution.
I have the proper perms in my AndroidManifest.
Try adding the dot at the end, my jmdns app crashed without it..
Also try adding the .local. by yourself with the service type.

How does shareit discovers nearby devices android programmatically [duplicate]

This question already has answers here:
How the "SHAREit" android application works technically?
(2 answers)
Closed 1 year ago.
I'm want to create a file sharing app like shareit but I'm really confused about how shareit discovers the nearby devices.
When you click receive button shareit creates a hotspot at the receiver side and the sender without connecting to the hotspot shows the receiver name. How is that possible?
If shareit uses Wi-Fi direct then what's the point of creating hotspot?
And to use Network Service Discovery (NSD) both server and client should be on same network so I think shareit is using something else
If anyone can explain this concept of shareit it will be very helpful.
I finally found the answer! SHAREit uses WiFi SSID to identify the nearby app users.
The SSID Consist of two partslike this. BAHD-bXViYQ WHERE 'B' Stands for ANDROID DEVICE and the AHD for the user icon. the second part is the user name encoded in Base64. In this example my name muba.
I hope this answer helps save some time.
Well I have found how to enable the hotspot from one sharing app and find the list of available wifi enabled by that sharing app into another one. just like shareIt receiver enables the wifi hotspot and sender discovers the list of available receivers.
First of all You have to scan all available wifi network using WifiManager
public void startScan(){
mWifiManager.startScan();
mScanResultList = mWifiManager.getScanResults();
mWifiConfigurations = mWifiManager.getConfiguredNetworks();
}
now pass this mScanResultList to a method which finds the network according to your requirement.
public static List<ScanResult> filterWithNoPassword(List<ScanResult> scanResultList){
if(scanResultList == null || scanResultList.size() == 0){
return scanResultList;
}
List<ScanResult> resultList = new ArrayList<>();
for(ScanResult scanResult : scanResultList){
if(scanResult.capabilities != null && scanResult.capabilities.equals(NO_PASSWORD) || scanResult.capabilities != null && scanResult.capabilities.equals(NO_PASSWORD_WPS)){
resultList.add(scanResult);
}
}
return resultList;
}
Now pass the resultList to arraylist adapter to show the network in list. Inside adapter's convertView method just pass that dataList to scanner to get ssid and mac address of the network
#Override
public View convertView(int position, View convertView) {
ScanResultHolder viewHolder = null;
if(convertView == null){
convertView = View.inflate(getContext(), R.layout.item_wifi_scan_result, null);
viewHolder = new ScanResultHolder();
viewHolder.iv_device = (ImageView) convertView.findViewById(R.id.iv_device);
viewHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
viewHolder.tv_mac = (TextView) convertView.findViewById(R.id.tv_mac);
convertView.setTag(viewHolder);
}else{
viewHolder = (ScanResultHolder) convertView.getTag();
}
ScanResult scanResult = getDataList().get(position);
if(scanResult != null){
viewHolder.tv_name.setText(scanResult.SSID);
viewHolder.tv_mac.setText(scanResult.BSSID);
}
return convertView;
}
This is the code to enable the hotspot
public static boolean configApState(Context context, String apName) {
WifiManager wifimanager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
WifiConfiguration wificonfiguration = null;
try {
wificonfiguration = new WifiConfiguration();
wificonfiguration.SSID = apName;
// if WiFi is on, turn it off
if(isApOn(context)) {
wifimanager.setWifiEnabled(false);
// if ap is on and then disable ap
disableAp(context);
}
Method method = wifimanager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method.invoke(wifimanager, wificonfiguration, !isApOn(context));
return true;
}
catch (Exception e) {
e.printStackTrace();
}
return false;
}

Add android.permission.MANAGE_USB permission to existing system application

We have an application installed on a rooted device as a system application. The latter doesn't have the android.permission.MANAGE_USB and we want to add it to a newer version so that the permission is given to the user automatically. I have followed the post:
bypass android usb host permission confirmation dialog
More specifically, the answer marked as correct from the user d_d_t.
Why doesn't it work? I mean, I have taken this newer version, directly installed it as our original system application and it works perfectly! But when I update the existing version with no usb permission with the newer version it just doesn't work. The new one is just an update. Same certificate and all.
I'm at a loss. Any thoughts?
Our code below:
AndroidManifest.xml.
<uses-permission
android:name="android.permission.MANAGE_USB"
android:protectionLevel="signature" />
Java class.
try {
PackageManager pm = getApplicationContext().getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(getApplicationContext().getPackageName(), 0);
if (ai != null) {
UsbManager manager = (UsbManager) getApplicationContext().getSystemService(Context.USB_SERVICE);
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
IUsbManager service = IUsbManager.Stub.asInterface(b);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
if (device.getVendorId() == 0x0403) {
service.grantDevicePermission(device, ai.uid);
service.setDevicePackage(device,getApplicationContext().getPackageName(), 0);
}
}
}
} catch (Exception e) {
Log.e("UsbReceiver", "exception " + e);
e.printStackTrace();
}

Categories