Jump to content
Sign in to follow this  
ertank

Mac address on Android 6.0 or above

Recommended Posts

Hello,

 

As of Android 6.0 we cannot read mac address using an app as indicated in here: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id

It seems some people have success reading it on network interfaces. I have seen some java code that I cannot translate and test on an Android 7.0 device. An example with several code alternatives: https://stackoverflow.com/questions/33159224/getting-mac-address-in-android-6-0

 

1- If anybody can share some working code that would be appreciated.

2- I have no information on how reliable device unique id on Android devices. I have that Chinese made hand held barcode terminal running modified Android OS. I cannot be sure if unique device id is actually globally unique independent of modifications to Android OS. Any information on that or links to read is appreciated.

 

Thanks & regards,

Ertan

Share this post


Link to post

1. This should at least have you started:

uses
  Androidapi.JNI.Java.Net, Androidapi.JNI.JavaTypes, Androidapi.Helpers,  Androidapi.JNIBridge;

function BytesToHex(const ABytes: TBytes): string;
var
  I: Integer;
begin
  Result := '';
  for I := Low(ABytes) to High(ABytes) do
    Result := Result + IntToHex(ABytes[I], 2);
end;

procedure GetMacAddresses(const AAddresses: TStrings);
var
  LInterfaces, LAddresses: JEnumeration;
  LInterface: JNetworkInterface;
  LJavaBytes: TJavaArray<Byte>;
  LBytes: TBytes;
  LByte: Byte;
  I: Integer;
  LAddress: JInetAddress;
  LName, LHostAddress: string;
begin
  AAddresses.Clear;
  LInterfaces := TJNetworkInterface.JavaClass.getNetworkInterfaces;
  while LInterfaces.hasMoreElements do
  begin
    LInterface := TJNetworkInterface.Wrap(JObjectToID(LInterfaces.nextElement));
    LJavaBytes := LInterface.getHardwareAddress;
    if LJavaBytes <> nil then
    begin
      SetLength(LBytes, LJavaBytes.Length);
      for I := 0 to LJavaBytes.Length - 1 do
        LBytes[I] := LJavaBytes.Items[I];
      AAddresses.Add(BytesToHex(LBytes));
    end;
  end;
end;

2. Check the code (and warning) for GetUniqueDeviceID, here:

 

https://github.com/DelphiWorlds/KastriFree/blob/master/Core/DW.OSDevice.Android.pas

 

Apparently things have changed a little since Android 8:

https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID

Share this post


Link to post
23 hours ago, Dave Nottage said:

1. This should at least have you started:

Thank you. I have just slightly modified provided code to my taste and get rid of "deprecated" message for JObjectToID on Delphi 10.3.2.

Final working for me version is below.


uses
  System.SysUtils,
  Androidapi.JNI,
  Androidapi.JNI.Java.Net,
  Androidapi.JNI.JavaTypes,
  Androidapi.Helpers,
  Androidapi.JNIBridge;

 

function BytesToHex(const ABytes: TBytes): string;
var
  I: Integer;
begin
  Result := EmptyStr;
  for I := Low(ABytes) to High(ABytes) do
    Result := Result + IntToHex(ABytes[I], 2) + ':';
  SetLength(Result, Result.Length - 1);
end;


function GetMacAddress(const InterfaceName: string = 'wlan0'): string;
var
  LInterfaces: JEnumeration;
  LInterface: JNetworkInterface;
  LJavaBytes: TJavaArray<Byte>;
  LBytes: TBytes;
  I: Integer;
begin
  Result := EmptyStr;
  LInterfaces := TJNetworkInterface.JavaClass.getNetworkInterfaces;
  while LInterfaces.hasMoreElements do
  begin
    LInterface := TJNetworkInterface.Wrap(TAndroidHelper.JObjectToID(LInterfaces.nextElement));
    if JStringToString(LInterface.getName).ToLower().Equals(InterfaceName) then
    begin
      LJavaBytes := LInterface.getHardwareAddress;
      if LJavaBytes <> nil then
      begin
        SetLength(LBytes, LJavaBytes.Length);
        for I := 0 to LJavaBytes.Length - 1 do
          LBytes[I] := LJavaBytes.Items[I];
        Result := BytesToHex(LBytes);
        Exit();
      end;
    end;
  end;
end;

 

23 hours ago, Dave Nottage said:

2. Check the code (and warning) for GetUniqueDeviceID, here:

It seems Mac address is still way to go. At least for a while.

 

Edited by ertank
  • Like 1

Share this post


Link to post

Hi Alexandria

I am new in Delphi Firemonkey and I need to getting Device mac address in my project

I use your code in my project and it work properly on android emulator but when I transfer application on mobile phone (android 11) it did not work 

I put sum checkpoints in code and find that on mobile phone flowing  line return nil all times. 

what do you think about this problem?

thanks 

LJavaBytes := LInterface.getHardwareAddress

Share this post


Link to post
18 minutes ago, Fayyaz said:

application on mobile phone (android 11) it did not work

Apparently things are different on Android 11 or higher: https://developer.android.com/training/articles/user-data-ids#mac-11-plus

Going by that documentation, it appears it is not possible any more. If you're after a unique identifier for the device, see the earlier messages in this thread.

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×