如何在android中以编程方式获取设备的IMEI/ESN?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1972381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:00:05  来源:igfitidea点击:

How to get the device's IMEI/ESN programmatically in android?

androidimei

提问by Tom

To identify each devices uniquely I would like to use the IMEI (or ESN number for CDMA devices). How to access this programmatically?

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

回答by Trevor Johns

You want to call android.telephony.TelephonyManager.getDeviceId().

你想打电话android.telephony.TelephonyManager.getDeviceId()

This will return whatever string uniquely identifies the device (IMEI on GSM, MEID for CDMA).

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

You'll need the following permission in your AndroidManifest.xml:

您将需要以下权限AndroidManifest.xml

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

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

in order to do this.

为此。

That being said, be careful about doing this. Not only will users wonder why your application is accessing their telephony stack, it might be difficult to migrate data over if the user gets a new device.

话虽如此,做这件事要小心。用户不仅会想知道为什么您的应用程序要访问他们的电话堆栈,而且如果用户获得新设备,可能难以迁移数据。

Update:As mentioned in the comments below, this is not a secure way to authenticate users, and raises privacy concerns. It is not recommended. Instead, look at the Google+ Login APIif you want to implement a frictionless login system.

更新:正如在下面的评论中提到的,这不是一种对用户进行身份验证的安全方式,并且会引起隐私问题。不推荐。相反,如果您想实现无摩擦的登录系统,请查看Google+ 登录 API

The Android Backup APIis also available if you just want a lightweight way to persist a bundle of strings for when a user resets their phone (or buys a new device).

Android的备份API也可以,如果你只想要一个轻量级的方式来坚持字符串当用户重新设置自己的手机(或购买新设备)的包。

回答by Taner

In addition to the answer of Trevor Johns, you can use this as follows:

除了 Trevor Johns 的回答之外,您还可以按如下方式使用:

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

And you should add the following permission into your Manifest.xml file:

您应该将以下权限添加到您的 Manifest.xml 文件中:

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

In emulator, you'll probably get a like a "00000..." value. getDeviceId() returns NULL if device ID is not available.

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

回答by Asaf Pinhassi

I use the following code to get the IMEI or use Secure.ANDROID_ID as an alternative, when the device doesn't have phone capabilities:

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

回答by tonys

Or you can use the ANDROID_ID setting from Android.Provider.Settings.System (as described here strazerre.com).

或者您可以使用 Android.Provider.Settings.System 中的 ANDROID_ID 设置(如strazerre.com此处所述)。

This has the advantage that it doesn't require special permissions but can change if another application has write access and changes it (which is apparently unusual but not impossible).

这样做的优点是它不需要特殊权限,但可以在另一个应用程序具有写访问权限并更改它时进行更改(这显然不寻常但并非不可能)。

Just for reference here is the code from the blog:

仅供参考,这里是博客中的代码:

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

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

Implementation note: if the ID is critical to the system architecture you need to be aware that in practice some of the very low end Android phones & tablets have been found reusing the same ANDROID_ID (9774d56d682e549c was the value showing up in our logs)

实施注意事项如果 ID 对系统架构至关重要,您需要注意在实践中发现一些非常低端的 Android 手机和平板电脑重复使用相同的 ANDROID_ID(9774d56d682e549c 是我们日志中显示的值)

回答by alchemist

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

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

The following code helps in obtaining IMEI number of android devices :

以下代码有助于获取安卓设备的 IMEI 号码:

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

Permissions required in Android Manifest:

Android 清单中所需的权限:

android.permission.READ_PHONE_STATE

NOTE: In case of tablets or devices which can't act as Mobile Phone IMEI will be null.

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

回答by Zin Win Htet

to get IMEI(international mobile equipment identifier)

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

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

to get device unique id

获取设备唯一ID

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

回答by The Dead Guy

For Android 6.0+ the game has changed so i suggest you use this;

对于 Android 6.0+,游戏已经改变,所以我建议你使用它;

The best way to go is during runtime else you get permission errors.

最好的方法是在运行时,否则你会遇到权限错误。

   /**
 * 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);
}
}

Hope this helps you or someone.

希望这对您或某人有帮助。

回答by Jamil

New Update:

新更新:

For Android Version 6 And Above, WLAN MAC Address has been deprecated , follow Trevor Johns answer

对于 Android 6 及以上版本,WLAN MAC 地址已被弃用,请遵循 Trevor Johns 的回答

Update:

更新:

For uniquely Identification of devices, You can Use Secure.ANDROID_ID.

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

Old Answer:

旧答案:

Disadvantages of using IMEI as Unique Device ID:

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

  • IMEI is dependent on the Simcard slot of the device, so it is not possible to get the IMEI for the devices that do not use Simcard. In Dual sim devices, we get 2 different IMEIs for the same device as it has 2 slots for simcard.
  • IMEI 依赖于设备的 Simcard 插槽,因此不使用 Simcard 的设备无法获取 IMEI。在双卡设备中,我们为同一设备获得 2 个不同的 IMEI,因为它有 2 个卡槽。

You can Use The WLAN MAC Address string (Not Recommended For Marshmallow and Marshmallow+ as WLAN MAC Address has been deprecated on Marshmallow forward. So you'll get a bogus value)

您可以使用 WLAN MAC 地址字符串(不推荐用于 Marshmallow 和 Marshmallow+,因为 WLAN MAC 地址已在 Marshmallow forward 上弃用。因此您会得到一个虚假值)

We can get the Unique ID for android phones using the WLAN MAC address also. The MAC address is unique for all devices and it works for all kinds of devices.

我们也可以使用 WLAN MAC 地址获取安卓手机的唯一 ID。MAC 地址对所有设备都是唯一的,它适用于所有类型的设备。

Advantages of using WLAN MAC address as Device ID:

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

  • It is unique identifier for all type of devices (smart phones and tablets).

  • It remains unique if the application is reinstalled

  • 它是所有类型设备(智能手机和平板电脑)的唯一标识符。

  • 如果重新安装应用程序,它仍然是唯一的

Disadvantages of using WLAN MAC address as Device ID:

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

  • Give You a Bogus Value from Marshmallow and above.

  • If device doesn't have wifi hardware then you get null MAC address, but generally it is seen that most of the Android devices have wifi hardware and there are hardly few devices in the market with no wifi hardware.

  • 给你一个来自棉花糖及以上的虚假价值。

  • 如果设备没有wifi硬件,那么你会得到空的MAC地址,但通常可以看到大多数Android设备都有wifi硬件,市场上几乎没有没有wifi硬件的设备。

SOURCE : technetexperts.com

来源:technetexperts.com

回答by Muhammad Hamza Shahid

As in API 26 getDeviceId()is depreciated so you can use following code to cater API 26 and earlier versions

由于 API 26getDeviceId()已折旧,因此您可以使用以下代码来满足 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();
}

Don't forget to add permission requests for READ_PHONE_STATEto use the above code.

不要忘记添加READ_PHONE_STATE使用上述代码的权限请求。

UPDATE: From Android 10 its is restricted for user apps to get non-resettable hardware identifiers like IMEI.

更新:从 Android 10 开始,用户应用程序无法获取不可重置的硬件标识符(如 IMEI)。

回答by Muhammad Hamza Shahid

The method getDeviceId() of TelephonyManager returns the unique device ID, for example, the IMEI for GSM and the MEID or ESN for CDMA phones. Return null if device ID is not available.

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

Java Code

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

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> 

Permission RequiredREAD_PHONE_STATE in manifest file.

清单文件中需要READ_PHONE_STATE权限