วิธีรับ IMEI / ESN ของอุปกรณ์โดยใช้โปรแกรมใน Android


343

ในการระบุอุปกรณ์แต่ละตัวโดยเฉพาะฉันต้องการใช้ IMEI (หรือหมายเลข ESN สำหรับอุปกรณ์ CDMA) วิธีการเข้าถึงโปรแกรมนี้โดยทาง?


ในการรับ IMEI สำหรับทั้ง SIM ในโทรศัพท์สองซิมให้ใช้การสะท้อนกลับของ Java ดูที่นี่คือตัวอย่าง
— Vaibhav Jani

5
@PiedPiper: IMEI ไม่เฉพาะกับซิม คุณกำลังคิด IMSI
— Phillip

@Phillip ขอบคุณเพื่อน ฉันได้อัปเดตคำตอบแล้ว :)
— Vaibhav Jani

1
ทุกคน .. มีการเปลี่ยนแปลงใน android 6 ไหม? เรายังสามารถเข้าถึง IMEI ได้ไหม?
— ดังนั้นผู้ประกาศที่

1
คุณต้องขออนุญาต READ_PHONE_STATE เมื่อใช้งานจริงจากนั้นคุณยังสามารถรับ IMEI ได้
— Flo เรา

คำตอบ:


387

android.telephony.TelephonyManager.getDeviceId()คุณต้องการที่จะเรียก

สิ่งนี้จะคืนค่าสตริงที่ระบุอุปกรณ์ (IMEI บน GSM, MEID สำหรับ CDMA) โดยไม่ซ้ำกัน

คุณจะต้องได้รับอนุญาตจากคุณในAndroidManifest.xml:

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

เพื่อที่จะทำสิ่งนี้

ที่ถูกกล่าวว่าระวังการทำเช่นนี้ ไม่เพียง แต่ผู้ใช้จะสงสัยว่าทำไมแอปพลิเคชันของคุณเข้าถึงสแต็กโทรศัพท์ของพวกเขามันอาจเป็นการยากที่จะโยกย้ายข้อมูลหากผู้ใช้ได้รับอุปกรณ์ใหม่

อัปเดต:ดังที่กล่าวไว้ในความคิดเห็นด้านล่างนี่ไม่ใช่วิธีที่ปลอดภัยในการตรวจสอบสิทธิ์ผู้ใช้และแจ้งข้อกังวลด้านความเป็นส่วนตัว ไม่แนะนำ ให้ดูที่API การเข้าสู่ระบบของ Google+ แทนหากคุณต้องการใช้ระบบการเข้าสู่ระบบแบบไม่ใช้แรงเสียดทาน

API การสำรองข้อมูล Androidยังมีอยู่ถ้าคุณเพียงต้องการเป็นวิธีที่มีน้ำหนักเบายังคงกำของสตริงสำหรับเมื่อผู้ใช้ตั้งค่าโทรศัพท์ของพวกเขา (หรือซื้ออุปกรณ์ใหม่)


1
อะไรจะเป็นทางออกที่ดีกว่าซึ่งจะทำให้พวกเขาสามารถโยกย้ายข้อมูลในอนาคต? ที่อยู่อีเมลของ Google? ถ้าเป็นเช่นนั้นฉันจะดึงมันออกจากระบบได้อย่างไร?
— Tom

3
วิธีที่น่าเชื่อถือที่สุดในการทำเช่นนี้คือให้พวกเขาสร้างบัญชีในครั้งแรกที่พวกเขาเปิดแอปของคุณ มีวิธีรับที่อยู่อีเมลของผู้ใช้ (ดูเอกสารใน AccountManager) แต่การตรวจสอบว่าผู้ใช้ที่ประสงค์ร้ายไม่ได้ปลอมแปลงข้อมูลนี้ต้องการความรู้เล็กน้อยเกี่ยวกับวิธีการทำงานของ Google Data API มากกว่าที่ฉันสามารถทำได้ ช่องแสดงความคิดเห็นขนาดเล็ก ;)
— Trevor Johns

1
ที่จริงแล้วสำหรับเรื่องนั้นคุณไม่มีการรับประกันใด ๆ ว่าผู้ใช้ไม่ได้ปลอมแปลง IMEI / MEID ด้วยเช่นกัน หากการรักษาความปลอดภัยเป็นเรื่องที่กังวลคุณต้องใช้ชื่อผู้ใช้ / รหัสผ่านหรือวิธี getAuthToken () ใน AccountManager (และอีกครั้งคุณต้องยืนยันโทเค็นนี้กับเซิร์ฟเวอร์ที่เปิดตัวไว้เดิม)
— เทรเวอร์ Johns

2
Adi: รหัสสำหรับรับรหัสอุปกรณ์? ไม่มีอะไรมากกว่าหนึ่งสิทธิ์ + วิธีที่ฉันกล่าวถึงข้างต้น ที่กล่าวว่าคุณควรตรวจสอบ API การเข้าสู่ระบบ Google+ ซึ่งเป็นแนวทางที่แนะนำสำหรับการตรวจสอบผู้ใช้ในปัจจุบัน: developer.android.com/google/play-services/auth.html
— Trevor Johns

2
มันใช้ Android 6 หรือไม่? และคุณกำหนดเป้าหมาย SDK 23 หรือไม่ จากนั้นคุณต้องขอ READ_PHONE_STATE ตอนรันไทม์ก่อนสอบถาม IMEI
— Flo เรา

284

นอกเหนือจากคำตอบของ Trevor Johns คุณสามารถใช้สิ่งต่อไปนี้:

TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.getDeviceId();

และคุณควรเพิ่มสิทธิ์ต่อไปนี้ในไฟล์ Manifest.xml ของคุณ:

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

ในโปรแกรมจำลองคุณอาจได้รับค่า "00000 ... " getDeviceId () ส่งคืนค่า NULL หาก ID อุปกรณ์ไม่พร้อมใช้งาน


1
มีวิธีรับตัวจำลองให้ส่งคืนหมายเลข IMEI หรือไม่
— MikeSchem

@ MikeSchem ผู้เลียนแบบไม่มีสตริง IMEI ที่มีความหมาย
— shizhen

ลองอย่าใช้: <uses-permission android: name = "android.permission.READ_PHONE_STATE" /> การอนุญาตนี้มีความสำคัญมากคุณสามารถรับแอปที่ถูกปฏิเสธจาก Google Play Team (กฎความปลอดภัยใหม่ที่เพิ่มเข้ามาในช่วงปลายปี 2561) ตามคำแนะนำให้ใช้รหัสโฆษณาดีกว่า
— Duna

@Taner มันจะทำงานกับอุปกรณ์ Dual sim หรือไม่? (จำเป็นต้องได้รับ IMEI ครั้งแรกเท่านั้น)
— Arnold Brown

มีความกังวลเรื่องความปลอดภัยในการใช้READ_PHONE_STATEสิทธิ์หรือไม่?
— viper

62

ฉันใช้รหัสต่อไปนี้เพื่อรับ IMEI หรือใช้ Secure.ANDROID_ID เป็นทางเลือกเมื่ออุปกรณ์ไม่มีคุณสมบัติโทรศัพท์:

/**
 * Returns the unique identifier for the device
 *
 * @return unique identifier for the device
 */
public String getDeviceIMEI() {
    String deviceUniqueIdentifier = null;
    TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
    if (null != tm) {
        deviceUniqueIdentifier = tm.getDeviceId();
    }
    if (null == deviceUniqueIdentifier || 0 == deviceUniqueIdentifier.length()) {
        deviceUniqueIdentifier = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
    }
    return deviceUniqueIdentifier;
}

17
TextUtils.isEmpty () -> if (identifier == null || identifier .length () == 0)
— Mikhaili

2
สวัสดี Pinhassi คุณมีกรณีใด ๆ เมื่อ ID อุปกรณ์ที่ส่งคืนโดยผู้จัดการระบบโทรศัพท์ว่างเปล่าหรือว่างเปล่า แต่ค่าที่อ่านจาก Secure.ANDROID_ID นั้นไม่ว่างเปล่า? ขอบคุณ
— Budda

4
เท่าที่ฉันจำได้มันเป็นแท็บเล็ตที่ไม่มีซิมการ์ด (แต่ฉันไม่แน่ใจ 100%)
— Asaf Pinhassi

Secure.ANDROID_ID จะเปลี่ยนหากอุปกรณ์ถูกฟอร์แมตหรือรอมถูกรีเซ็ตเป็นค่าจากโรงงาน
— shridutt kothari

Nexus7 ของฉัน (1stGen) ส่งคืนnullสำหรับอุปกรณ์โทรศัพท์แล้ว ... ใครทราบวิธีรับ IMEI จากแท็บเล็ต
— Sakiboy

38

หรือคุณสามารถใช้การตั้งค่า ANDROID_ID จาก Android.Provider.Settings.System (ตามที่อธิบายไว้ที่นี่strazerre.com )

นี่เป็นข้อดีที่ไม่จำเป็นต้องมีการอนุญาตพิเศษ แต่สามารถเปลี่ยนแปลงได้หากแอปพลิเคชันอื่นมีการเข้าถึงเพื่อเขียนและเปลี่ยนแปลง (ซึ่งเห็นได้ชัดว่าผิดปกติ แต่ไม่สามารถเป็นไปไม่ได้)

เพียงเพื่อการอ้างอิงนี่คือรหัสจากบล็อก:

import android.provider.Settings;
import android.provider.Settings.System;   

String androidID = System.getString(this.getContentResolver(),Secure.ANDROID_ID);

หมายเหตุการใช้งาน : หาก ID มีความสำคัญต่อสถาปัตยกรรมระบบคุณจำเป็นต้องทราบว่าในทางปฏิบัติแล้วพบว่าโทรศัพท์และแท็บเล็ต Android บางรุ่นที่มีระดับต่ำมาก ๆ กลับมาใช้ซ้ำ ANDROID_ID เดียวกัน (9774d56d682e549c) เป็นค่าที่ปรากฏในบันทึกของเรา)


15
ค่าคงที่นี้เลิกใช้แล้ว คุณต้องใช้ android.provider.Settings.Secure.ANDROID_ID แทน
— mcorley

@mcorley เมื่อฉันใช้ android.provider.Settings.Secure.ANDROID_ID สำหรับ Nexus 7 แท็บเล็ตและ Nexus 4 จะส่งคืนค่าเดียวกัน 'android_id'
— vuhung3990

3
@meowmeo ทำแบบเดียวกันกับฉันจนกระทั่งฉันใช้รหัสซึ่งตอนนี้เป็นส่วนหนึ่งของคำตอบ (ish) String androidID = android.provider.Settings.System.getString(this.getContentResolver(), Secure.ANDROID_ID);
— Matthias

แต่สิ่งนี้จะไม่ถูกรีเซ็ตเป็น ANDROID_ID ใหม่เมื่อรีเซ็ตเป็นค่าจากโรงงาน? จะทำอย่างไรถ้าฉันต้องการ ANDROID_ID แบบถาวรที่สามารถอยู่รอดได้รีเซ็ต
— IgorGanapolsky

35

จาก: http://mytechead.wordpress.com/2011/08/28/how-to-get-imei-number-of-android-device/ :

รหัสต่อไปนี้ช่วยในการรับอุปกรณ์ Android จำนวน IMEI:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String device_id = tm.getDeviceId();

สิทธิ์ที่จำเป็นในรายการ Android:

android.permission.READ_PHONE_STATE

หมายเหตุ: ในกรณีแท็บเล็ตหรืออุปกรณ์ที่ไม่สามารถทำหน้าที่เป็นโทรศัพท์มือถือ IMEI จะเป็นโมฆะ


1
นี่คือรหัสที่แท้จริงซึ่งฉันกำลังค้นหาเพื่อรับ IMEI
— Anand Savjani

2
น่าเสียดายที่ Marshmallow ส่งต่อคุณต้องขออนุญาตในตอนนี้ การอนุญาตนี้ไม่เหมาะเนื่องจากเป็นการรบกวนการใช้งานของผู้ใช้และอาจทำให้ผู้ใช้บางคนสงสัย
— IgorGanapolsky

ลองอย่าใช้: <uses-permission android: name = "android.permission.READ_PHONE_STATE" /> การอนุญาตนี้มีความสำคัญมากคุณสามารถรับแอปที่ถูกปฏิเสธจากทีม Google Play (กฎความปลอดภัยใหม่ที่เพิ่มในช่วงปลายปี 2018) ตามคำแนะนำให้ใช้ ID โฆษณาแทน IMEI
— Duna

ทางออกสำหรับ Android 10 คืออะไร?
— Amin Pinjari

23

รับIMEI (ตัวระบุอุปกรณ์มือถือระหว่างประเทศ)

public String getIMEI(Activity activity) {
    TelephonyManager telephonyManager = (TelephonyManager) activity
            .getSystemService(Context.TELEPHONY_SERVICE);
    return telephonyManager.getDeviceId();
}

เพื่อรับรหัสเฉพาะของอุปกรณ์

public String getDeviceUniqueID(Activity activity){
    String device_unique_id = Secure.getString(activity.getContentResolver(),
            Secure.ANDROID_ID);
    return device_unique_id;
}

2
การแสดงตัวเลือก device_unique_id มีประโยชน์จริง ๆ
— JoeGalind

20

สำหรับ Android 6.0+ เกมมีการเปลี่ยนแปลงดังนั้นฉันขอแนะนำให้คุณใช้สิ่งนี้;

วิธีที่ดีที่สุดที่จะไปคือในระหว่างรันไทม์อื่นคุณจะได้รับข้อผิดพลาดในการอนุญาต

   /**
 * A loading screen after AppIntroActivity.
 */
public class LoadingActivity extends BaseActivity {
private static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;
private TextView loading_tv2;

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

    //trigger 'loadIMEI'
    loadIMEI();
    /** Fading Transition Effect */
    overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}

/**
 * Called when the 'loadIMEI' function is triggered.
 */
public void loadIMEI() {
    // Check if the READ_PHONE_STATE permission is already available.
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
            != PackageManager.PERMISSION_GRANTED) {
        // READ_PHONE_STATE permission has not been granted.
        requestReadPhoneStatePermission();
    } else {
        // READ_PHONE_STATE permission is already been granted.
        doPermissionGrantedStuffs();
    }
}



/**
 * Requests the READ_PHONE_STATE permission.
 * If the permission has been denied previously, a dialog will prompt the user to grant the
 * permission, otherwise it is requested directly.
 */
private void requestReadPhoneStatePermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.READ_PHONE_STATE)) {
        // Provide an additional rationale to the user if the permission was not granted
        // and the user would benefit from additional context for the use of the permission.
        // For example if the user has previously denied the permission.
        new AlertDialog.Builder(LoadingActivity.this)
                .setTitle("Permission Request")
                .setMessage(getString(R.string.permission_read_phone_state_rationale))
                .setCancelable(false)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        //re-request
                        ActivityCompat.requestPermissions(LoadingActivity.this,
                                new String[]{Manifest.permission.READ_PHONE_STATE},
                                MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
                    }
                })
                .setIcon(R.drawable.onlinlinew_warning_sign)
                .show();
    } else {
        // READ_PHONE_STATE permission has not been granted yet. Request it directly.
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE},
                MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
    }
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {

    if (requestCode == MY_PERMISSIONS_REQUEST_READ_PHONE_STATE) {
        // Received permission result for READ_PHONE_STATE permission.est.");
        // Check if the only required permission has been granted
        if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // READ_PHONE_STATE permission has been granted, proceed with displaying IMEI Number
            //alertAlert(getString(R.string.permision_available_read_phone_state));
            doPermissionGrantedStuffs();
        } else {
            alertAlert(getString(R.string.permissions_not_granted_read_phone_state));
          }
    }
}

private void alertAlert(String msg) {
    new AlertDialog.Builder(LoadingActivity.this)
            .setTitle("Permission Request")
            .setMessage(msg)
            .setCancelable(false)
            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // do somthing here
                }
            })
            .setIcon(R.drawable.onlinlinew_warning_sign)
            .show();
}


public void doPermissionGrantedStuffs() {
    //Have an  object of TelephonyManager
    TelephonyManager tm =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    //Get IMEI Number of Phone  //////////////// for this example i only need the IMEI
    String IMEINumber=tm.getDeviceId();

    /************************************************
     * **********************************************
     * This is just an icing on the cake
     * the following are other children of TELEPHONY_SERVICE
     *
     //Get Subscriber ID
     String subscriberID=tm.getDeviceId();

     //Get SIM Serial Number
     String SIMSerialNumber=tm.getSimSerialNumber();

     //Get Network Country ISO Code
     String networkCountryISO=tm.getNetworkCountryIso();

     //Get SIM Country ISO Code
     String SIMCountryISO=tm.getSimCountryIso();

     //Get the device software version
     String softwareVersion=tm.getDeviceSoftwareVersion()

     //Get the Voice mail number
     String voiceMailNumber=tm.getVoiceMailNumber();


     //Get the Phone Type CDMA/GSM/NONE
     int phoneType=tm.getPhoneType();

     switch (phoneType)
     {
     case (TelephonyManager.PHONE_TYPE_CDMA):
     // your code
     break;
     case (TelephonyManager.PHONE_TYPE_GSM)
     // your code
     break;
     case (TelephonyManager.PHONE_TYPE_NONE):
     // your code
     break;
     }

     //Find whether the Phone is in Roaming, returns true if in roaming
     boolean isRoaming=tm.isNetworkRoaming();
     if(isRoaming)
     phoneDetails+="\nIs In Roaming : "+"YES";
     else
     phoneDetails+="\nIs In Roaming : "+"NO";


     //Get the SIM state
     int SIMState=tm.getSimState();
     switch(SIMState)
     {
     case TelephonyManager.SIM_STATE_ABSENT :
     // your code
     break;
     case TelephonyManager.SIM_STATE_NETWORK_LOCKED :
     // your code
     break;
     case TelephonyManager.SIM_STATE_PIN_REQUIRED :
     // your code
     break;
     case TelephonyManager.SIM_STATE_PUK_REQUIRED :
     // your code
     break;
     case TelephonyManager.SIM_STATE_READY :
     // your code
     break;
     case TelephonyManager.SIM_STATE_UNKNOWN :
     // your code
     break;

     }
     */
    // Now read the desired content to a textview.
    loading_tv2 = (TextView) findViewById(R.id.loading_tv2);
    loading_tv2.setText(IMEINumber);
}
}

หวังว่านี่จะช่วยคุณหรือใครบางคน


16

อัพเดทใหม่:

สำหรับ Android เวอร์ชัน 6 ขึ้นไปที่อยู่ WLAN MAC นั้นเลิกใช้แล้วให้ทำตามคำตอบของ Trevor Johns

ปรับปรุง:

สำหรับเอกลักษณ์ประจำตัวของอุปกรณ์ที่คุณสามารถใช้Secure.ANDROID_ID

คำตอบเก่า:

ข้อเสียของการใช้ IMEI เป็นรหัสอุปกรณ์ที่ไม่ซ้ำ:

  • IMEI ขึ้นอยู่กับช่องใส่ซิมการ์ดของอุปกรณ์ดังนั้นจึงเป็นไปไม่ได้ที่จะรับ IMEI สำหรับอุปกรณ์ที่ไม่ได้ใช้ซิมการ์ด ในอุปกรณ์สองซิมเราจะได้รับ IMEIs 2 แบบสำหรับอุปกรณ์เดียวกันเนื่องจากมี 2 ช่องสำหรับซิมการ์ด

คุณสามารถใช้สตริงที่อยู่ WLAN MAC (ไม่แนะนำสำหรับ Marshmallow และ Marshmallow + เนื่องจากที่อยู่ MAC WLAN MAC ถูกคัดค้านใน Marshmallow ไปข้างหน้าดังนั้นคุณจะได้รับค่าปลอม)

เราสามารถรับ Unique ID สำหรับโทรศัพท์ android โดยใช้ที่อยู่ WLAN MAC ได้เช่นกัน ที่อยู่ MAC นั้นไม่เหมือนใครสำหรับทุกอุปกรณ์และใช้ได้กับอุปกรณ์ทุกประเภท

ข้อดีของการใช้ที่อยู่ WLAN MAC เป็นรหัสอุปกรณ์:

  • มันเป็นตัวระบุที่ไม่ซ้ำกันสำหรับอุปกรณ์ทุกประเภท (สมาร์ทโฟนและแท็บเล็ต)

  • มันยังคงไม่ซ้ำกันหากติดตั้งแอปพลิเคชันใหม่

ข้อเสียของการใช้ WLAN MAC address เป็น Device ID:

  • ให้คุณค่าเป็นการหลอกลวงจาก Marshmallow และสูงกว่า

  • หากอุปกรณ์ไม่มีฮาร์ดแวร์ wifi คุณจะได้รับที่อยู่ MAC เป็นโมฆะ แต่โดยทั่วไปแล้วจะเห็นว่าอุปกรณ์ Android ส่วนใหญ่มีฮาร์ดแวร์ wifi และมีอุปกรณ์น้อยมากในตลาดที่ไม่มีฮาร์ดแวร์ wifi

แหล่งที่มา: technetexperts.com


7
"IMEI ขึ้นอยู่กับซิมการ์ด" ... นี่เป็นเท็จ ดูเหมือนว่าคุณจะสับสนกับ IMEI ด้วยหมายเลข IMSI
— Merlevede

2
รหัสอุปกรณ์สถานีเคลื่อนที่ระหว่างประเทศหรือ IMEI ย่อคือหมายเลขที่ระบุโทรศัพท์มือถือที่ทำงานบนเครือข่าย GSM ฉันลองใช้เป็นการส่วนตัวแล้วมันจะทำให้ฉันไม่มีโปรแกรมถ้าไม่มีผู้ให้บริการโทรศัพท์ GSM smartmobilephonesolutions.com/content/…
— Jamil

3
ถูกต้องฉันไม่ได้อ่านอย่างละเอียด IMEI เชื่อมโยงกับตัวรับส่งสัญญาณซิมการ์ดไม่ใช่ไปที่ซิมการ์ด ความผิดฉันเอง!
— Merlevede

2
ที่อยู่ WLAN MACถูกคัดค้านใน Marshmallow ไปข้างหน้า ดังนั้นคุณจะได้รับค่าปลอม!
— IgorGanapolsky

1
android 6 อย่าส่งคืนที่อยู่ MAC WIFI พร้อมรหัสของคุณ ขอให้สังเกต
— zszen

15

เช่นเดียวกับใน API 26 getDeviceId()จะถูกคิดค่าเสื่อมราคาเพื่อให้คุณสามารถใช้รหัสต่อไปนี้เพื่อรองรับ API 26 และเวอร์ชันก่อนหน้า

TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String imei="";
if (android.os.Build.VERSION.SDK_INT >= 26) {
  imei=telephonyManager.getImei();
}
else
{
  imei=telephonyManager.getDeviceId();
}

อย่าลืมเพิ่มคำขออนุญาตREAD_PHONE_STATEให้ใช้รหัสด้านบน

อัพเดท: จาก Android 10 มันถูก จำกัด ไว้สำหรับแอพผู้ใช้เพื่อรับตัวระบุฮาร์ดแวร์ที่ไม่สามารถรีเซ็ตได้เช่น IMEI


การแบ่งปันความคิดฉันสามารถหาข้อมูลอ้างอิงสำหรับวิธีการ 'getImei () "ได้อย่างไร
— sam byte

2
แน่นอนว่าโปรดใช้developer.android.com/reference/android/telephony/สำหรับการอ้างอิง getImei ()
— Muhammad Hamza Shahid

ทางออกสำหรับ Android 10 คืออะไร?
— Amin Pinjari

1
อามินโชคไม่ดีใน Android 10 เนื่องจากเหตุผลด้านความปลอดภัยตอนนี้แอพของบุคคลที่สามได้รับตัวระบุฮาร์ดแวร์เช่น IMEI สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงความเป็นส่วนตัวใน Android 10 ไปที่developer.android.com/about/versions/10/privacy
— Muhammad Hamza Shahid

ทำงานบน Android Oreo
— Satish Shetty

10

เมธอด getDeviceId () ของ TelephonyManager ส่งคืน ID อุปกรณ์ที่ไม่ซ้ำกันเช่น IMEI สำหรับ GSM และ MEID หรือ ESN สำหรับโทรศัพท์ CDMA ส่งคืน null ถ้า ID อุปกรณ์ไม่พร้อมใช้งาน

รหัส Java

package com.AndroidTelephonyManager;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.TextView;

public class AndroidTelephonyManager extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    TextView textDeviceID = (TextView)findViewById(R.id.deviceid);

    //retrieve a reference to an instance of TelephonyManager
    TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

    textDeviceID.setText(getDeviceID(telephonyManager));

}

String getDeviceID(TelephonyManager phonyManager){

 String id = phonyManager.getDeviceId();
 if (id == null){
  id = "not available";
 }

 int phoneType = phonyManager.getPhoneType();
 switch(phoneType){
 case TelephonyManager.PHONE_TYPE_NONE:
  return "NONE: " + id;

 case TelephonyManager.PHONE_TYPE_GSM:
  return "GSM: IMEI=" + id;

 case TelephonyManager.PHONE_TYPE_CDMA:
  return "CDMA: MEID/ESN=" + id;

 /*
  *  for API Level 11 or above
  *  case TelephonyManager.PHONE_TYPE_SIP:
  *   return "SIP";
  */

 default:
  return "UNKNOWN: ID=" + id;
 }

}
}

XML

<linearlayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
<textview android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="@string/hello">
<textview android:id="@+id/deviceid" android:layout_height="wrap_content" android:layout_width="fill_parent">
</textview></textview></linearlayout> 

ต้องได้รับอนุญาต READ_PHONE_STATE ในไฟล์ Manifest


4

คุณสามารถใช้ฟังก์ชั่นTelephonyManager TELEPHONY_SERVICEเพื่อรับรหัสอุปกรณ์ที่ไม่ซ้ำกันต้องได้รับอนุญาต: READ_PHONE_STATE

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

ตัวอย่างIMEI สำหรับ GSMและMEID หรือ ESN สำหรับโทรศัพท์CDMA

/**
 * Gets the device unique id called IMEI. Sometimes, this returns 00000000000000000 for the
 * rooted devices.
 **/
public static String getDeviceImei(Context ctx) {
    TelephonyManager telephonyManager = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
    return telephonyManager.getDeviceId();
}

กลับ nullถ้ารหัสอุปกรณ์ไม่พร้อมใช้งาน


และทำไมรหัสอุปกรณ์ว่าง? เนื่องจากอุปกรณ์ที่รูท
— Vishal Sojitra

ทางออกสำหรับ Android 10 คืออะไร?
— Amin Pinjari


3

ลองนี้ (จำเป็นต้องได้รับ IMEI ก่อนเสมอ)

TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (ActivityCompat.checkSelfPermission(LoginActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED) {

         return;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (mTelephony.getPhoneCount() == 2) {
                    IME = mTelephony.getImei(0);
                }else{
                    IME = mTelephony.getImei();
                }
            }else{
                if (mTelephony.getPhoneCount() == 2) {
                    IME = mTelephony.getDeviceId(0);
                } else {
                    IME = mTelephony.getDeviceId();
                }
            }
        } else {
            IME = mTelephony.getDeviceId();
        }

ทางออกสำหรับ Android 10 คืออะไร? developer.android.com/about/versions/10/privacy
— Amin Pinjari

2

ใช้รหัสด้านล่างให้หมายเลข IMEI:

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
System.out.println("IMEI::" + telephonyManager.getDeviceId());

1

สำหรับ API ระดับ 11 หรือสูงกว่า:

case TelephonyManager.PHONE_TYPE_SIP: 
return "SIP";

TelephonyManager tm= (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
textDeviceID.setText(getDeviceID(tm));

1

Kotlin Code สำหรับการรับ DeviceId (IMEI) พร้อมการตรวจสอบการอนุญาตและการเปรียบเทียบสำหรับ Android ทุกรุ่น:

 val  telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
        == PackageManager.PERMISSION_GRANTED) {
        // Permission is  granted
        val imei : String? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)  telephonyManager.imei
        // older OS  versions
        else  telephonyManager.deviceId

        imei?.let {
            Log.i("Log", "DeviceId=$it" )
        }

    } else {  // Permission is not granted

    }

เพิ่มสิทธิ์นี้ให้กับ AndroidManifest.xml ด้วย:

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

1

คุณจะต้องได้รับอนุญาตใน AndroidManifest.xml ของคุณ:

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

ในการรับIMEI (ตัวระบุอุปกรณ์พกพาระหว่างประเทศ) และหากอยู่เหนือระดับ API 26 เราจะได้รับtelephonyManager.getImei()เป็นโมฆะดังนั้นเราจึงใช้ANDROID_IDเป็นตัวระบุที่ไม่ซ้ำ

 public static String getIMEINumber(@NonNull final Context context)
            throws SecurityException, NullPointerException {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        String imei;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            assert tm != null;
            imei = tm.getImei();
            //this change is for Android 10 as per security concern it will not provide the imei number.
            if (imei == null) {
                imei = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            }
        } else {
            assert tm != null;
            if (tm.getDeviceId() != null && !tm.getDeviceId().equals("000000000000000")) {
                imei = tm.getDeviceId();
            } else {
                imei = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            }
        }

        return imei;
    }

0

สำหรับผู้ที่มองหาเวอร์ชั่น Kotlin คุณสามารถใช้สิ่งนี้

private fun telephonyService() {
    val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
    val imei = if (android.os.Build.VERSION.SDK_INT >= 26) {
        Timber.i("Phone >= 26 IMEI")
        telephonyManager.imei
    } else {
        Timber.i("Phone IMEI < 26")
        telephonyManager.deviceId
    }

    Timber.i("Phone IMEI $imei")
}

หมายเหตุ: คุณต้องห่อtelephonyService()ด้านบนด้วยการตรวจสอบการอนุญาตโดยใช้checkSelfPermissionหรือวิธีการที่คุณใช้

เพิ่มสิทธิ์นี้ในไฟล์รายการ;

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

0

ใช้รหัสด้านล่าง:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        String[] permissions = {Manifest.permission.READ_PHONE_STATE};
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(permissions, READ_PHONE_STATE);
        }
    } else {
        try {
            TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            String imei = telephonyManager.getDeviceId();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

และเรียกใช้ onRequestPermissionsResult วิธีการรหัสต่อไปนี้:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case READ_PHONE_STATE:
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                try {
                    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    String imei = telephonyManager.getDeviceId();

                } catch (Exception e) {
                    e.printStackTrace();
                }
    }
}

เพิ่มการอนุญาตต่อไปนี้ใน AndroidManifest.xml ของคุณ:

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

0

สำหรับ Android 10 รหัสต่อไปนี้ใช้งานได้สำหรับฉัน

val uid: String = Settings.Secure.getString(ctx.applicationContext.contentResolver, Settings.Secure.ANDROID_ID)
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            imei = when {
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
                    uid
                }
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                    telephonyManager.imei
                }
                else -> {
                    telephonyManager.deviceId
                }
            }
        }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.