วิธีรับ 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.