59

下の画像に示されている値にプログラムでアクセスするにはどうすればよいですか?

ここに画像の説明を入力

4

5 に答える 5

107

これはハードウェアのシリアル番号です。アクセスするには

  • Android Q (>= SDK 29) android.Manifest.permission.READ_PRIVILEGED_PHONE_STATEが必要です。このアクセス許可を要求できるのは、システム アプリのみです。呼び出し元のパッケージがデバイスまたはプロファイルの所有者である場合は、READ_PHONE_STATEアクセス許可で十分です。

  • android.os.Build.getSerial()危険なパーミッションREAD_PHONE_STATEを必要とするAndroid 8 以降(>= SDK 26) の使用。使用するとandroid.os.Build.UNKNOWNandroid.os.Build.SERIALが返されます。

  • Android 7.1 以前(<= SDK 25) 以前android.os.Build.SERIALは、有効なシリアルを返します。

どのデバイスにも固有です。一意のデバイス ID を取得/使用する方法をお探しの場合は、こちらをお読みください

許可を必要としないリフレクションを含むソリューションについては、この回答を参照してください。

于 2012-06-14T08:30:57.163 に答える
63

Android 7.1 (SDK 25) まで

Android 7.1 までは、次の方法で取得できます。

Build.SERIAL

Android 8 (SDK 26) 以降

Android 8 (SDK 26) 以降では、このフィールドが返さUNKNOWNれ、次の方法でアクセスする必要があります。

Build.getSerial()

危険な許可 が必要android.permission.READ_PHONE_STATEです。

Android Q (SDK 29) から

Android Q の使用Build.getSerial()は、以下を要求することで少し複雑になります。

android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE(これはシステム アプリによってのみ取得できます)、または呼び出し元のパッケージがデバイスまたはプロファイルの所有者READ_PHONE_STATEであり、アクセス許可を持っている必要があります。これは、ほとんどのアプリがこの機能を使用できないことを意味します。Google からのAndroid Q の発表をご覧ください。

Android SDK リファレンスを参照してください


Unique Device Identifier のベスト プラクティス

一意の識別子だけが必要な場合は、ハードウェア識別子を使用しないことをお勧めします。これは、Google がプライバシー上の理由からハードウェア識別子へのアクセスを困難にしようと継続的に試みているためです。UUID.randomUUID().toString();共有設定などで初めてアクセスする必要があるときに、生成して保存することができます。ANDROID_IDまたは、デバイス、ユーザー、および (Android 8+ のみ) アプリのインストールに固有の 8 バイト長の 16 進文字列である which を使用することもできます。このトピックの詳細については、一意の識別子のベスト プラクティスを参照してください。

于 2017-10-30T18:47:15.200 に答える
1

私は私のソリューションが好きです:

/**
 * Checks some permission
 *
 * @return true - If have any of the permissions sent by parameter
 * @return true - If you do not have any of the permissions sent by parameter
 */
fun Context.hasPermissionSome(vararg permissions: String): Boolean {
    permissions.forEach { permission ->
        if (hasPermission(permission)) {
            return true
        }
    }
    return false
}

@CheckResult
fun validateValue(value: String?, valueToCompare: String? = null): Boolean {
    if (!value.isNullOrEmpty() && value != Build.UNKNOWN && value != valueToCompare)
        return true

    return false
}

/**
 * @see: https://developer.android.com/about/versions/10/privacy/changes#data-ids
 *
 * Retrieve SerialNumber with system commands:
 *   adb shell getprop ro.serialno
 *   adb shell getprop ro.boot.serialno
 *   adb shell getprop ril.serialnumber
 * @return device Serial Number obtained with SystemProperties
 */
@SuppressLint("PrivateApi")
private fun serialNumberBySysProp(): String? {
    var sn: String? = null

    val readPhonePermissions = arrayOf(
        Manifest.permission.READ_PHONE_STATE,
        "android.permission.READ_PRIVILEGED_PHONE_STATE"
    )

    if (!this.context.hasPermissionSome(*readPhonePermissions))
        return sn

    try {
        val systemProps = Class.forName("android.os.SystemProperties")
        val getProp = systemProps.getMethod("get", String::class.java)
        
        // 1ª tentativa
        sn = getProp("ril.serialnumber") as String?
        if (validateValue(sn)) {
            return sn
        }

        // 2ª tentativa
        sn = getProp("ro.serialno") as String?
        if (validateValue(sn)) {
            return sn
        }

        // 3ª tentativa
        sn = getProp("ro.boot.serialno") as String?
        if (validateValue(sn)) {
            return sn
        }

        // 4ª tentativa
        sn = getProp("sys.serialnumber") as String?
        if (validateValue(sn)) {
            return sn
        }

    } catch (e: Exception) { }

    return if (validateValue(sn))
        sn
    else
        null
}

/**
 * @return device Serial Number obtained with Build Class
 */
@SuppressLint("HardwareIds")
private fun serialNumberByBuild(): String? {
    var sn: String? = null
    MediaDrm.PROPERTY_DEVICE_UNIQUE_ID
    if (!this.context.hasPermissionSome(
            Manifest.permission.READ_PHONE_STATE,
            "android.permission.READ_PRIVILEGED_PHONE_STATE"
        ))
        return sn

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        sn = Build.getSerial()
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        sn = Build.getSerial()
    } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) {
        sn = Build.getSerial()

        if (!validateValue(sn))
            sn = Build.SERIAL
    }

    return if (validateValue(sn))
        sn
    else
        null
}

val serialNumber: String
    @SuppressLint("HardwareIds", "PrivateApi", "MissingPermission", "StaticFieldLeak")
    get() {
        var serial: String = serialNumberByBuild() ?: ""

        if (!validateValue(serial)) {
            serial = serialNumberBySysProp() ?: ""
        }

        return serial
    }

この権限を AndroidManifest.xml に追加します

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
于 2021-03-30T02:06:57.220 に答える