MAC Address เป็นตัวเลขเฉพาะที่จะถูกระบุอยู่บนอุปกรณ์ใดๆ ซึ่งบนแอนดรอยด์นั้นก็จะมีอุปกรณ์อยู่ 2 อย่างที่มี MAC Address กำกับอยู่ด้วย นั่นก็คือ WiFi และ Bluetooth ที่อยู่ภายในเครื่องนั่นเอง

จึงทำให้บ่อยครั้งที่นักพัฒนาแอปพยายามจะใช้ MAC Address จากอุปกรณ์เหล่านี้ (โดยเฉพาะ WiFi) เพื่อใช้ในการระบุตัวเครื่อง

แต่ทว่า...

สิ่งที่ควรรู้สำหรับ MAC Address บนแอนดรอยด์

ไม่ว่าจะเป็น MAC Address จาก WiFi หรือ Bluetooth บนอุปกรณ์แอนดรอยด์จะถูกเรียกว่า Device's Non-resettable Identifiers ซึ่งก็คือค่าที่ติดอยู่กับตัวเครื่องอย่างถาวร ต่อให้ผู้ใช้ Factory Reset เครื่องก็ตาม ค่าที่อ่านได้ก็จะยังเป็นค่าเดิมเสมอ ด้วยเหตุนี้จึงทำให้ MAC Address สำหรับอุปกรณ์แอนดรอยด์ถือว่าเป็นหนึ่งในข้อมูลสำคัญสำหรับผู้ใช้

และแน่นอนว่าทีมแอนดรอยด์ค่อนข้างให้ความสำคัญมากสำหรับ User Privacy จึงทำให้ตั้งแต่ Android 10 (API 29) เป็นต้นไป นักพัฒนาแอปทั่วๆไปจะไม่สามารถเขียนคำสั่งเพื่อดึงค่า MAC Address ไปใช้งานได้อีกต่อไปแล้ว

ดังนั้นไม่ควรใช้ MAC Address ในการระบุตัวเครื่องของผู้ใช้แอปเด็ดขาด ถ้าไม่อยากมีปัญหาในภายหลัง

ถ้าจะเป็นต้องใช้ค่า MAC Address จริงๆ

สำหรับแอปที่ต้องการใช้ค่า MAC Access จากอุปกรณ์แอนดรอยด์จะต้องเข้าเงื่อนไขข้อใดข้อหนึ่งจาก 3 ข้อนี้เท่านั้น

  • ใช้กับอุปกรณ์แอนดรอยด์ที่เวอร์ชันต่ำกว่า Android 10 (API 29) ลงไป (สำหรับ WiFi) และใช้กับอุปกรณ์แอนดรอยด์ที่เวอร์ชันต่ำกว่า Android 8.0 Oreo (API 26) ลงไป (สำหรับ Bluetooth)
  • เป็น Systems App ที่ติดตั้งอยู่ในเครื่องตั้งแต่แรก (บ้างก็เรียกว่า Privileged App หรือ Pre-installed App)
  • เป็นแอปที่เปิดใช้งาน Android Enterprise

ถ้าแอปของนักพัฒนาไม่ได้อยู่ในเงื่อนไขทั้ง 3 ข้อนี้ ก็แนะนำให้เปลี่ยนไปใช้ Solution อื่นๆที่ให้ผลลัพธ์ที่ใกล้เคียงแทนดีกว่า

Solution อื่นๆ?

จาก Requirement ของนักพัฒนาส่วนใหญ่จะพบว่าไม่จำเป็นต้องใช้ MAC Address ก็ได้ และยังมี Solution อื่นๆอีกมากมายที่สามารถใช้ทดแทนได้ เช่น

ต้องการจำกัดจำนวนเครื่องที่ผู้ใช้ล็อกอินใช้งานแอปได้

เมื่อเข้าใช้งานครั้งแรกก็ให้แอปสร้าง Random Unique ID ขึ้นมาซักชุดนึงเพื่อเก็บไว้ทั้งฝั่งแอปและฝั่ง Server แทนก็ได้

ต้องการให้ Bluetooth Device สามารถจำได้ว่าเชื่อมต่อกับอุปกรณ์แอนดรอยด์เครื่องไหน

เมื่อเชื่อมต่อในครั้งแรกก็ให้แอปสร้าง Random Unique ID แล้วเก็บไว้ทั้งฝั่งแอปและ Bluetooth Device แทนก็ได้

ต้องการให้ผู้ใช้ซื้อแอปไปติดตั้งได้แค่เครื่องเดียวเท่านั้น

วิธีแบบนี้ไม่ควรทำตั้งแต่แรก เพราะผู้ใช้มีสิทธิ์ที่จะย้ายไปใช้งานแอปบนเครื่องอื่นๆได้ ตราบใดที่ยังใช้ Google Account เดิมอยู่ อย่างมากก็ควรจำกัดจำนวนเครื่องที่สามารถเข้าใช้งานแอปได้พร้อมๆกันแทน

การอ่านค่า MAC Address ของ WiFi

ในการอ่านค่า MAC Address จาก WiFi บนอุปกรณ์แอนดรอยด์จะต้องขอ Permission ที่ชื่อว่า INTERNET ด้วย

<uses-permission android:name="android.permission.INTERNET" />

สำหรับคำสั่งที่ใช้จะเป็นการอ่านค่า MAC Address จาก NetworkInterface

private fun getWifiMacAddress(): String? {
    return try {
        NetworkInterface.getNetworkInterfaces()
            .toList()
            .find { networkInterface -> networkInterface.name.equals("wlan0", ignoreCase = true) }
            ?.hardwareAddress
            ?.joinToString(separator = ":") { byte -> "%02X".format(byte) }
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

จะเห็นว่า NetworkInterface จะมีคำสั่ง getNetworkInterfaces() เพื่อดึงข้อมูลทั้งหมดที่ในเครื่องนั้นมี แต่เนื่องจากต้องการดึงข้อมูลของ WiFi เท่านั้น จึงค้นหาเฉพาะ NetworkInterface ที่มีชื่อว่า wlan0 เพียงอย่างเดียว

นั่นหมายความว่าถ้าอุปกรณ์แอนดรอยด์รองรับการเชื่อมต่อผ่าน Network ด้วยวิธีแบบอื่นนอกเหนือจาก WiFi ก็สามารถดึง MAC Address ด้วยวิธีนี้ได้เช่นกัน

การอ่านค่า MAC Address ของ Bluetooth

ในการอ่านค่า MAC ADdress จาก Bluetooth จะใช้วิธีทางอ้อมอย่าง Reflection แทน ไม่จำเป็นต้องเรียกใช้งาน BluetoothManager โดยตรง

private fun getBluetoothMacAddress(context: Context): String? {
    return Settings.Secure.getString(context.contentResolver,
            "bluetooth_address")
}