为了唯一地标识每个设备,我想使用IMEI(或CDMA设备的ESN编号)。如何以编程方式访问它?

评论

要在双SIM卡电话中同时获取两个SIM卡的IMEI,请使用Java反射。看到这里是演示

@PiedPiper:IMEI不是特定于SIM卡的。您正在考虑IMSI。

@Phillip感谢队友。我已经更新了答案:)

每个人.. android 6有什么变化吗?我们还能通过某种方式访问​​IMEI吗?

您需要在运行时请求权限READ_PHONE_STATE,然后仍然可以获得IMEI

#1 楼

您想致电android.telephony.TelephonyManager.getDeviceId()

这将返回唯一标识设备的任何字符串(GSM上的IMEI,CDMA的MEID)。

您需要以下权限AndroidManifest.xml

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

为了做到这一点。

话虽这么说,请谨慎做。用户不仅会想知道为什么您的应用程序正在访问他们的电话堆栈,而且如果用户获得了新设备,可能很难迁移数据。

更新:如下面的评论中所述,这不是一种验证用户身份的安全方法,并引起了隐私方面的顾虑。不推荐。相反,如果您想实现无摩擦的登录系统,请查看Google+登录API。

如果您只想以轻量级的方式为用户保留字符串的捆绑包,那么也可以使用Android Backup API。重置他们的手机(或购买新设备)。

评论


那么,有什么更好的解决方案可以使他们将来迁移数据呢? Google电子邮件地址?如果是这样,我如何将其从系统中取出?

–汤姆
09年12月30日在11:17

最可靠的方法是让他们在首次启动您的应用程序时创建一个帐户。有多种方法可以获取用户的电子邮件地址(请参阅AccountManager上的文档),但是要验证恶意用户没有伪造此信息,则需要对Google Data API的工作原理有一些了解,这比我可以提供的更多。小评论框。 ;)

–特雷弗·约翰斯(Trevor Johns)
09年12月30日在22:48

实际上,就此而言,您不能保证用户也没有伪造其IMEI / MEID。如果需要考虑安全性,则确实需要在AccountManager中使用用户名/密码或getAuthToken()方法(同样,您需要使用最初发出该令牌的服务器来验证此令牌)。

–特雷弗·约翰斯(Trevor Johns)
09年12月30日在22:51

阿迪:获取设备ID的代码?我上面提到的只是一种方法+权限。也就是说,您应该研究Google+登录API,这是最近几天用于验证用户身份的推荐方法:developer.android.com/google/play-services/auth.html

–特雷弗·约翰斯(Trevor Johns)
13年6月18日在2:05

它正在运行Android 6吗?您是否定位到SDK 23?然后,您需要在运行时请求READ_PHONE_STATE,然后再查询IMEI

– Flo我们
16年6月6日在8:08

#2 楼

除了Trevor Johns的答案以外,您还可以按以下方式使用它:

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


并且应该在Manifest.xml文件中添加以下权限:

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


在模拟器中,您可能会得到一个类似于“ 00000 ...”的值。如果设备ID不可用,则getDeviceId()返回NULL。

评论


有没有办法让仿真器返回IMEI号码?

– MikeSchem
17年3月13日在21:03

@MikeSchem,模拟器没有有意义的IMEI字符串。

–石振
18年11月23日在1:59

尝试不要使用:此权限非常敏感,您可以从Google Play小组获得App Rejected(2018年末添加的新安全规则)。作为建议,最好使用广告ID。

–金枪鱼
19年5月5日在18:51



@Taner可以在Dual sim设备上使用吗? (仅需要获得第一个IMEI)

–阿诺德·布朗
19-6-25在10:51



使用READ_PHONE_STATE权限是否有安全方面的考虑?

–毒蛇
19年8月26日在4:48

#3 楼

当设备不具有电话功能时,我使用以下代码获取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;
}


评论


TextUtils.isEmpty()-> if(标识符== null ||标识符.length()== 0)

– Mikhaili
2013年6月11日14:27在

您好,Pinhassi,您是否遇到过电话管理器返回的设备ID为空或为空,但从Secure.ANDROID_ID读取的值为非空的情况?谢谢

–布达
2013年6月20日22:36



据我所记得,这是针对没有SIM卡的平板电脑(但我不确定100%)。

–阿萨夫·皮纳西(Asaf Pinhassi)
13年6月21日在21:50

如果设备已格式化或ROM已恢复出厂设置,则Secure.ANDROID_ID会更改

–shridutt kothari
14年4月14日在11:26

我的Nexus7(1stGen)为电话deviceId返回null。有人知道如何从平板电脑获取IMEI吗?

– Sakiboy
16-2-4在21:35



#4 楼

或者,您可以使用Android.Provider.Settings.System中的ANDROID_ID设置(如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是我们的日志中显示的值)

评论


不建议使用此常数。相反,您需要使用android.provider.Settings.Secure.ANDROID_ID;

–mcorley
2011年5月18日在21:33

@mcorley当我为Nexus 7平板电脑和Nexus 4使用android.provider.Settings.Secure.ANDROID_ID时,它返回相同的值'android_id'

–vuhung3990
2014年9月15日上午8:07

@meowmeo为我做了同样的事情,直到我使用了现在已经成为答案(ish)一部分的代码。字符串androidID = android.provider.Settings.System.getString(this.getContentResolver(),Secure.ANDROID_ID);

–马特西亚斯
16年4月28日在18:48

但是,恢复出厂设置后,会不会重置为新的ANDROID_ID吗?如果我需要一个持久的ANDROID_ID可以在重置后保留,该怎么办。

– IgorGanapolsky
2016年9月9日在21:40



#5 楼

来自:http://mytechead.wordpress.com/2011/08/28/how-to-get-imei-number-of-android-device/:

以下代码有助于获取IMEI android设备的数量:

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


Android清单中所需的权限:

 android.permission.READ_PHONE_STATE
 


注意:如果平板电脑或设备不能用作手机
IMEI将为空。

评论


这是我要获取IMEI的实际代码

– Anand Savjani
2015年9月10日于12:29

不幸的是,使用棉花糖转发,您现在必须在运行时请求此权限。此权限并不理想,因为它会干扰用户体验,并可能使某些用户可疑。

– IgorGanapolsky
16 Sep 9'在21:42



尝试不要使用:此权限非常敏感,您可以从Google Play小组获得App Rejected(在2018年末添加了新的安全规则)。作为建议,最好使用广告ID代替IMEI

–金枪鱼
19年5月5日在18:54

Android 10的解决方案是什么?

– Amin Pinjari
19-10-14在6:17

#6 楼

获取IMEI(国际移动设备标识符)

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


获得设备唯一ID

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


评论


显示device_unique_id替代品确实很有帮助

–JoeGalind
16年6月21日在23:40

#7 楼

对于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);
}
}


希望对您或某人有帮助。

#8 楼

与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字节
18年4月17日在6:10

当然,请使用developer.android.com/reference/android/telephony/…获取getImei()参考

–穆罕默德·哈姆扎·沙希德(Muhammad Hamza Shahid)
18年4月17日在9:37

Android 10的解决方案是什么?

– Amin Pinjari
19-10-14在6:17

不幸的是,由于安全原因,Amin在Android 10中受到限制,现在第三方应用只能获取IMEI等硬件标识符,以获取有关Android 10中隐私更改的更多信息,请访问developer.android.com/about/versions/10/privacy

–穆罕默德·哈姆扎·沙希德(Muhammad Hamza Shahid)
19/12/6在10:07

适用于Android Oreo。

–沙蒂·谢蒂(Satish Shetty)
4月5日20:12

#9 楼

新更新:

对于Android 6及更高版本,WLAN MAC地址已被弃用,请按照Trevor Johns的回答

更新:

用于唯一标识设备,您可以使用Secure.ANDROID_ID。

旧答案:

将IMEI用作唯一设备ID的缺点:


IMEI取决于设备的Simcard插槽,因此
不可能为不使用Simcard的设备获取IMEI。
在Dual sim设备中,对于同一SIM卡,我们会获得2个不同的IMEI设备,因为它有2个用于Simcard的插槽。

您可以使用WLAN MAC地址字符串(不推荐用于棉花糖和棉花糖+,因为棉花糖转发不推荐使用WLAN MAC地址。因此,您会得到虚假信息值)

我们还可以使用WLAN MAC地址获取Android手机的唯一ID。 MAC地址对于所有设备都是唯一的,并且适用于各种设备。

使用WLAN MAC地址作为设备ID的优点:


它是唯一的所有类型的设备(智能手机和
平板电脑)的标识符。
如果重新安装该应用程序,它仍然是唯一的

使用WLAN MAC地址作为设备ID的缺点:


为您提供棉花糖及以上的假值。
如果设备没有wifi硬件,则您将获得空MAC地址,
但通常可以看到,大多数Android设备具有wifi
硬件,并且市场上几乎没有没有wifi的设备


来源:technetexperts.com

评论


“ IMEI取决于Simcard” ...这是错误的。您似乎将IMEI与IMSI号码混淆了

– Merevede
16年7月26日在14:46

国际移动站设备标识(IMEI)是一个数字,用于标识在GSM网络上运行的移动电话。我亲自尝试过,如果GSM Phone上没有无线运营商,它会以编程方式使我无效。 smartmobilephonesolutions.com/content/…

–贾米尔
16年7月27日在6:50

您是对的,我没有仔细阅读。 IMEI与SIM卡收发器关联,而不与SIM卡关联。我的错!

– Merevede
16年7月27日在21:57

棉花糖转发不推荐使用WLAN MAC地址。这样您将获得虚假的价值!

– IgorGanapolsky
2016年9月9日在21:45

android 6不会使用您的代码返回正确的WIFI MAC地址。注意。

–zszen
17年6月27日在15:19

#10 楼

TelephonyManager的getDeviceId()方法返回唯一的设备ID,例如,GSM的IMEI和CDMA电话的MEID或ESN。如果设备ID不可用,则返回null。

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。

#11 楼

您可以使用此TelephonyManager TELEPHONY_SERVICE函数来获取唯一的设备ID,
需要权限:READ_PHONE_STATE

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


例如,IMEI用于GSM,MEEI或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();
}


如果设备ID不可用,则返回null。

评论


以及为什么设备ID为null?因为植根设备。

– Vishal Sojitra
18 Mar 28 '18 at 11:09

Android 10的解决方案是什么?

– Amin Pinjari
19-10-14在6:17

#12 楼

不建议使用getDeviceId()方法。
对此getImei(int)有新方法

在这里检查

评论


Android 10的解决方案是什么?

– Amin Pinjari
19-10-14在6:18

#13 楼

试试这个(需要总是先获得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
19-10-14在6:19

#14 楼

使用以下代码为您提供IMEI编号:

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


#15 楼

适用于API级别11或更高版本:

case TelephonyManager.PHONE_TYPE_SIP: 
return "SIP";

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


#16 楼

Kotlin代码,用于获取具有适用于所有android版本的操作权限和可比性检查的DeviceId(IMEI):

 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-->


#17 楼

您需要在AndroidManifest.xml中获得以下权限:

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


要获取IMEI(国际移动设备标识符),并且如果它高于API级别26,那么我们得到telephonyManager.getImei()为null,因此,我们将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;
    }


#18 楼

使用以下代码:

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" />


#19 楼

对于寻找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")
}


注意:您必须使用checkSelfPermission或任何使用的方法对telephonyService()进行权限检查。

也将此权限添加到清单文件中;

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


#20 楼

对于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
                }
            }
        }