Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีหา Serial Number ของอุปกรณ์ Android

ภาพรวม

ตัวอย่างนี้สาธิตการดึงหมายเลข Serial Number ของอุปกรณ์ Android ผ่าน Build.SERIAL และ TelephonyManager พร้อมจัดการ Runtime Permission สำหรับ READ_PHONE_STATE

⚠️ ข้อจำกัดสำคัญ (Android 10+ / API 29+)

ตั้งแต่ Android 10 (API 29) เป็นต้นมา ไม่สามารถเข้าถึง Serial Number จริงได้แล้ว เพื่อเหตุผลด้านความเป็นส่วนตัว

  • Build.SERIAL จะคืนค่า "UNKNOWN" เสมอ
  • TelephonyManager.getSerial() ต้องการ Permission READ_PRIVILEGED_PHONE_STATE (System App เท่านั้น)
  • แอปทั่วไปควรใช้ Android ID (Settings.Secure.ANDROID_ID) หรือ Advertising ID แทน

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → File → New Project → Empty Activity

ขั้นตอนที่ 2: จัดรูปแบบหน้าจอ (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:onClick="showDeviceInfo"
        android:text="Get Serial Number" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16sp"
        android:textSize="16sp" />

</RelativeLayout>

ขั้นตอนที่ 3: เขียนโค้ด MainActivity.java

import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CODE_PHONE_STATE = 100;
    private TextView textView;
    private boolean permissionGranted = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = findViewById(R.id.textView);
        
        // ตรวจสอบ Permission เริ่มต้น
        checkPermission();
    }

    private void checkPermission() {
        int permissionCheck = ContextCompat.checkSelfPermission(this, 
            Manifest.permission.READ_PHONE_STATE);
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, 
                    REQUEST_CODE_PHONE_STATE);
            } else {
                permissionGranted = true;
            }
        } else {
            // Android 5.1 (API 22) และต่ำกว่า ให้ Permission อัตโนมัติตอน Install
            permissionGranted = true;
        }
    }

    public void showDeviceInfo(View v) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        StringBuilder info = new StringBuilder();

        // 1. Build.SERIAL (Android 9 และต่ำกว่า ทำงานได้, Android 10+ คืน "UNKNOWN")
        String serial = Build.SERIAL;
        info.append("Build.SERIAL: ").append(serial).append("\n\n");

        // 2. Android ID (ไม่ต้อง Permission, คงที่ต่อการติดตั้งแอป)
        String androidId = Settings.Secure.getString(getContentResolver(), 
            Settings.Secure.ANDROID_ID);
        info.append("Android ID: ").append(androidId).append("\n\n");

        // 3. TelephonyManager (ต้อง Permission READ_PHONE_STATE)
        if (permissionGranted) {
            TelephonyManager telephonyManager = (TelephonyManager) 
                getSystemService(Context.TELEPHONY_SERVICE);
            
            // IMEI (Android 8.0+ ต้อง Permission)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) 
                    == PackageManager.PERMISSION_GRANTED) {
                    info.append("IMEI: ").append(telephonyManager.getImei()).append("\n");
                }
            } else {
                info.append("IMEI: ").append(telephonyManager.getDeviceId()).append("\n");
            }
        } else {
            info.append("IMEI: Permission denied\n");
        }

        builder.setTitle("Device Information")
               .setMessage(info.toString())
               .setPositiveButton("OK", null)
               .show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_PHONE_STATE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                permissionGranted = true;
                Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

ขั้นตอนที่ 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                
                
            </intent-filter>
        </activity>

    </application>
</manifest>

การทดสอบ

รันแอป → กดปุ่ม "Get Serial Number" → จะแสดง Dialog ข้อมูลอุปกรณ์

วิธีหา Serial Number ของอุปกรณ์ Android

สรุป Identifier ต่างๆ ใน Android

IdentifierAPIPermissionความคงที่หมายเหตุ
Serial NumberBuild.SERIAL-HardwareAndroid 10+ คืน UNKNOWN
Android IDSettings.Secure.ANDROID_ID-Per InstallReset เมื่อ Factory Reset
IMEI/MEIDTelephonyManagerREAD_PHONE_STATEHardwareเฉพาะอุปกรณ์ที่มี SIM
Advertising IDAdvertisingIdClient-Per Userผู้ใช้ Reset ได้, สำหรับ Ads
Instance IDFirebaseInstanceId-Per App Installสำหรับ Push Notification

แนวทางปฏิบัติที่ดีที่สุด (Best Practice)

  1. ใช้ Android ID สำหรับระบุตัวตนอุปกรณ์ทั่วไป
  2. ใช้ Advertising ID สำหรับการตลาด/Analytics
  3. ใช้ Firebase Installation ID สำหรับ Push Notification
  4. หลีกเลี่ยงการใช้ Hardware ID (IMEI, Serial) เพราะจำกัดมากใน Android ใหม่
  5. สร้าง UUID เองเก็บใน SharedPreferences หากต้องการ ID ที่ควบคุมได้เต็มที่