Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách lấy số serial SIM mặc định trên Android

Giới thiệu

Bài viết này minh họa cách lấy số serial của thẻ SIM (ICCID) trên Android bằng TelephonyManager.getSimSerialNumber(). Tương tự như Device ID, từ Android 10 (API 29) quyền truy cập thông tin SIM bị hạn chế nghiêm ngặt.

Các bước thực hiện

Bước 1: Tạo project mới

Android Studio → File → New Project → Empty Activity → Điền thông tin → Finish.

Bước 2: Giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/tvSimSerial"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SIM Serial Number"
        android:textSize="18sp" />

</LinearLayout>

Bước 3: Khai báo quyền (AndroidManifest.xml)

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Android 11+ cần quyền READ_PRIVILEGED_PHONE_STATE (chỉ system app) -->

Bước 4: Code xử lý (MainActivity.kt)

package com.example.simserial

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.telephony.TelephonyManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private val REQUEST_CODE = 101
    private lateinit var telephonyManager: TelephonyManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        checkPermission()
    }

    private fun checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this,
                    arrayOf(Manifest.permission.READ_PHONE_STATE), REQUEST_CODE)
            } else {
                showSimSerial()
            }
        } else {
            showSimSerial()
        }
    }

    private fun showSimSerial() {
        var simSerial = ""
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Android 10+: getSimSerialNumber() trả về null cho app thông thường
            simSerial = "Android 10+: Cần quyền READ_PRIVILEGED_PHONE_STATE (chỉ system app)"
        } else {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
                == PackageManager.PERMISSION_GRANTED) {
                simSerial = telephonyManager.simSerialNumber ?: "Không có SIM hoặc không đọc được"
            } else {
                simSerial = "Chưa cấp quyền"
            }
        }
        tvSimSerial.text = "SIM Serial: $simSerial"
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                showSimSerial()
            } else {
                Toast.makeText(this, "Cần quyền READ_PHONE_STATE", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

Lưu ý quan trọng

  • Android 10 (API 29): getSimSerialNumber() trả về null cho ứng dụng thông thường.
  • Android 11 (API 30): Cần quyền READ_PRIVILEGED_PHONE_STATE - chỉ ứng dụng hệ thống (system app) mới được cấp.
  • Thiết bị đa SIM: Dùng TelephonyManager.createForSubscriptionId(subId) để lấy thông tin từng SIM slot.
  • Emulator: Thường không có SIM serial thật, cần test trên thiết bị thật.

Giải pháp thay thế

Nếu ứng dụng cần định danh người dùng/thiết bị, hãy xem xét:

  • Firebase Installation ID (Instance ID)
  • Advertising ID (Google Play Services)
  • ANDROID_ID (Settings.Secure.ANDROID_ID)
  • Tự sinh UUID và lưu trong SharedPreferences