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

Tom*_*Tom 321 android imei

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

Tre*_*hns 372

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

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

您需要以下权限AndroidManifest.xml:

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

为此.

话虽如此,小心这样做.用户不仅会想知道您的应用程序为何要访问其电话堆栈,而且如果用户获得新设备,则可能难以迁移数据.

更新:如下面的评论中所述,这不是一种对用户进行身份验证的安全方法,并引发了隐私问题.不推荐.相反,如果您要实施无摩擦登录系统,请查看Google+登录API.

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

  • 最可靠的方法是让他们在第一次启动您的应用时创建一个帐户.有一些方法可以获取用户的电子邮件地址(请参阅AccountManager上的文档),但验证恶意用户是否未伪造此信息需要了解Google数据API的工作方式 - 这比我可以提供的更多小评论框.;) (3认同)
  • 我认为 getDeviceId 不再工作了,伙计们,getDeviceId() 此方法在 API 级别 O 中已被弃用。使用 (@link getImei} 为 GSM 返回 IMEI,或 (@link getMeid} 为 CDMA 返回 MEID。 (3认同)
  • 阿迪:获取设备ID的代码?我上面提到的只是一种方法+权限。也就是说,您应该研究Google+登录API,这是最近几天用于验证用户身份的推荐方法:https://developer.android.com/google/play-services/auth.html (2认同)
  • 它运行的是Android 6吗?你是否针对SDK 23?然后,您需要在运行时请求READ_PHONE_STATE,然后再查询IMEI (2认同)

Tan*_*ner 276

除了Trevor Johns的答案,你可以使用如下:

TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.getDeviceId();
Run Code Online (Sandbox Code Playgroud)

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

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Run Code Online (Sandbox Code Playgroud)

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


Asa*_*ssi 58

我用下面的代码来获取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;
}
Run Code Online (Sandbox Code Playgroud)

  • TextUtils.isEmpty() - > if(identifier == null || identifier .length()== 0) (16认同)
  • 据我所知,这是没有SIM卡的平板电脑(但我不是100%肯定). (4认同)
  • 你好Pinhassi,电话管理器返回的设备ID是空还是空,你有没有任何情况,但从Secure.ANDROID_ID读取的值是非空的?谢谢 (2认同)

ton*_*nys 36

或者您可以使用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);
Run Code Online (Sandbox Code Playgroud)

实施说明:如果ID是系统架构,你需要知道,在实践中一些非常低端的Android手机和平板已发现重复使用相同的ANDROID_ID关键(9774d56d682e549c是显示我们的原木达价值)

  • 不推荐使用此常量.你需要使用android.provider.Settings.Secure.ANDROID_ID; (15认同)
  • @meowmeo为我做了同样的事情,直到我使用了现在已经成为答案(ish)一部分的代码。`String androidID = android.provider.Settings.System.getString(this.getContentResolver(),Secure.ANDROID_ID);` (2认同)

alc*_*ist 33

来自: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();
Run Code Online (Sandbox Code Playgroud)

Android Manifest中所需的权限:

android.permission.READ_PHONE_STATE
Run Code Online (Sandbox Code Playgroud)

注意:如果平板电脑或设备无法充当移动电话,则IMEI将为空.

  • 不幸的是,使用 Marshmallow forward,您现在必须在运行时请求此权限。此权限并不理想,因为它会干扰用户体验,并且可能会使一些用户产生怀疑。 (2认同)
  • android 10 的解决方案是什么? (2认同)

Zin*_*tet 22

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

public String getIMEI(Activity activity) {
    TelephonyManager telephonyManager = (TelephonyManager) activity
            .getSystemService(Context.TELEPHONY_SERVICE);
    return telephonyManager.getDeviceId();
}
Run Code Online (Sandbox Code Playgroud)

获取设备唯一ID

public String getDeviceUniqueID(Activity activity){
    String device_unique_id = Secure.getString(activity.getContentResolver(),
            Secure.ANDROID_ID);
    return device_unique_id;
}
Run Code Online (Sandbox Code Playgroud)

  • 显示device_unique_id替代方案非常有用 (2认同)

The*_*Guy 19

对于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);
}
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助你或某人.


Jam*_*mil 16

新更新:

对于Android版本6及以上版本,WLAN MAC地址已被弃用,请按照Trevor Johns的说法进行操作

更新:

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

旧答案:

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

  • IMEI依赖于设备的SIM卡插槽,因此无法为不使用Simcard的设备获取IMEI.在双SIM卡设备中,我们为同一设备获得2个不同的IMEI,因为它有2个用于SIM卡的插槽.

您可以使用WLAN MAC地址字符串(不推荐用于Marshmallow和Marshmallow +,因为WLAN MAC地址已被Marshmallow转发使用.因此您将获得虚假值)

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

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

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

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

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

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

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

消息来源:technetexperts.com

  • "IMEI依赖于Simcard"......这是错误的.您似乎将IMEI与IMSI号码混淆 (6认同)
  • 你是对的,我没有仔细阅读.IMEI与SIM卡收发器相关联,而不与SIM卡相关联.我的错! (3认同)
  • 国际移动台设备标识或简称IMEI是识别在GSM网络上运行的移动电话的编号.我亲自尝试过,如果GSM手机上没有无线运营商,它会给我带来无效的程序.http://www.smartmobilephonesolutions.com/content/imei-vs-meid-vs-esn-purpose-of-a-device-identifier (2认同)
  • **WLAN MAC地址**已在Marshmallow转发中弃用.所以你会得到一个虚假的价值! (2认同)

Muh*_*hid 13

与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();
}
Run Code Online (Sandbox Code Playgroud)

不要忘记添加"READ_PHONE_STATE"的权限请求以使用上面的代码.

  • 当然请使用 https://developer.android.com/reference/android/telephony/TelephonyManager.html#getImei(int) for getImei() 参考 (2认同)

小智 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;
 }

}
}
Run Code Online (Sandbox Code Playgroud)

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> 
Run Code Online (Sandbox Code Playgroud)

清单文件中的权限 READ_PHONE_STATE.


A-D*_*ech 5

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

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Run Code Online (Sandbox Code Playgroud)

例如,GSMIMEICDMA手机的MEID 或 ESN

/**
 * 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();
}
Run Code Online (Sandbox Code Playgroud)

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

  • android 10 的解决方案是什么? (2认同)

Arn*_*own 5

试试这个(始终需要获取第一个 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();
        }
Run Code Online (Sandbox Code Playgroud)