Introduction
Starting from android 11. Non-privileged apps cannot access the device's mac address.
Only Network interfaces with an IP address are visible.
This affects the original methods such as getifaddrs()
and NetworkInterface.getHardwareAddress().
Traditional methods to obtain the device mac address will become obsoleted.
For Amino apollo devices, it is suggested to get the WLAN Mac Address through IDeviceRemoteService .
Prerequisite
Please visit Enable Enterprise customer development page to obtain the Apollo SDK file. With the SDK file, you can import the included AAR and AIDL library files to build your own APP
Assuming that the latest AIDL library was imported to your android project. You are suggested to create a DeviceClient Class to communicate with the corresponding service.
Below is an example:
DeviceClient.java
package tv.amino.testplay;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
import com.aminocom.device.IDeviceRemoteService;
public class DeviceClient {
private static final String TAG = DeviceClient.class.getSimpleName();
private static final String DEVICE_REMOTE_SERVICE_PACKAGE = "com.aminocom.device";
private static final String DEVICE_REMOTE_SERVICE_CLASS = DEVICE_REMOTE_SERVICE_PACKAGE + ".DeviceRemoteService";
private static IDeviceRemoteService mService;
private static DeviceRemoteServiceConnection mConnection;
private Context mContext;
public DeviceClient(Context context, DeviceRemoteServiceConnection connection) {
mContext = context;
mConnection = connection;
}
// ----------------------------------------------------------------------
// Code showing how to deal with remote service.
// ----------------------------------------------------------------------
public static class DeviceRemoteServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
Log.d(TAG, "onServiceConnected(): className=" + className);
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mService = IDeviceRemoteService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, "onServiceDisconnected(): className=" + className);
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
}
}
public static IDeviceRemoteService getService() {
return mService;
}
public static int getVersion() {
return IDeviceRemoteService.VERSION;
}
public void connect() throws Exception {
// Bind remote service on setUp()
Intent intent = new Intent();
intent.setComponent(new ComponentName(DEVICE_REMOTE_SERVICE_PACKAGE, DEVICE_REMOTE_SERVICE_CLASS));
mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
public void disconnect() throws Exception {
// Unbind remote service on tearDown()
mContext.unbindService(mConnection);
}
public String getDeviceParameter(final String key, final String def) throws Exception {
return mService.getDeviceParameter(key, def);
}
public String getApplicationParameter(final String key, final String def) throws Exception {
return mService.getApplicationParameter(key, def);
}
public boolean setApplicationParameter(final String key, final String value) throws Exception {
return mService.setApplicationParameter(key, value);
}
public byte[] getEthernetMacAddress() throws Exception {
return mService.getEthernetMacAddress();
}
public String getDeviceSerialNumber() throws Exception {
return mService.getDeviceSerialNumber();
}
public String getDeviceHardwareModel() throws Exception {
return mService.getDeviceHardwareModel();
}
public byte[] getWlanMacAddress() {
if (mService != null) {
try {
return mService.getWlanMacAddress();
} catch (Exception e) { e.printStackTrace();}
}
return null;
}
}
Below is an example showing how to obtain the WLAN MacAddress of the apollo device.
AndroidManifest.xml
Your Manifest file needs to allow special user permission. To do this please add the following:
<uses-permission android:name="com.aminocom.device.permission.MANAGE_DEVICE" />
<uses-permission android:name="com.aminocom.device.permission.READ_DEVICE_CONFIG" />
MainActivity.java
In your MainActivity, we suggest you define the client and connection class and then make a service connection call under oncreate() as shown below:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//Definition for Device Client connection
private DeviceClient mClient;
private DeviceClient.DeviceRemoteServiceConnection mConnection = new DeviceClient.DeviceRemoteServiceConnection();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Create Device Client Connection
mClient = new DeviceClient(getApplicationContext(), mConnection);
try {
mClient.connect();
Log.e("start_deviceClient ","starting");
} catch (Exception e) {
e.printStackTrace();
}
}
}
You may need to convert the WLAN Mac address from byte array to string.
This conversion is shown below:
private static String convertMacAddress(byte[] mac) {
if (mac == null || mac.length == 0) {
return "";
}
StringBuilder buf = new StringBuilder();
for (int idx = 0; idx < mac.length; idx++) {
if (buf.length() > 0) {
buf.append(":");
}
buf.append(String.format("%02x", mac[idx]));
}
return buf.toString();
}
After the client connect is called (you may need a callback to notify your application), obtain the MacAddress with the following call:
Log.e("checkwlanMac", "W_Mac : "+ convertMacAddress(mClient.getWlanMacAddress()));
Expected output :
2022-10-27 15:41:30.762 11863-11863/tv.amino.testplay E/checkwlanMac: W_Mac : 00:03:e6:d7:dc:85