为了唯一地识别每个设备,我想使用IMEI(或CDMA设备的ESN号码)。如何以编程方式访问?
答案 0 :(得分:361)
您想致电android.telephony.TelephonyManager.getDeviceId()
。
这将返回唯一标识设备的字符串(GSM上的IMEI,CDMA的MEID)。
您需要AndroidManifest.xml
中的以下权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
为了做到这一点。
话虽如此,小心这样做。用户不仅会想知道您的应用程序为何要访问其电话堆栈,而且如果用户获得新设备,则可能难以迁移数据。
更新:如下面的评论中所述,这不是一种对用户进行身份验证的安全方式,并引发了隐私问题。不推荐。相反,如果要实现无摩擦登录系统,请查看Google+ Login API。
如果您只是想要一种轻量级的方式来保存用户重置手机(或购买新设备)时的字符串,那么Android Backup API也可用。
答案 1 :(得分:272)
除了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。
答案 2 :(得分:55)
当设备没有电话功能时,我使用以下代码获取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;
}
答案 3 :(得分:35)
或者您可以使用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手机&amp;已发现平板电脑重复使用相同的ANDROID_ID(9774d56d682e549c是我们日志中显示的值)
答案 4 :(得分:32)
来自: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 Manifest中所需的权限:
android.permission.READ_PHONE_STATE
注意:如果平板电脑或设备无法充当移动电话 IMEI将为空。
答案 5 :(得分:21)
获取 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;
}
答案 6 :(得分:17)
对于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);
}
}
希望这可以帮助你或某人。
答案 7 :(得分:16)
新更新:
对于Android版本6及以上版本,WLAN MAC地址已弃用,请按照Trevor Johns的说法进行操作
<强> 更新 强>
对于设备的唯一标识,您可以使用Secure.ANDROID_ID。
旧答案:
将IMEI用作唯一设备ID的缺点:
您可以使用WLAN MAC地址字符串(不推荐用于Marshmallow和Marshmallow +,因为WLAN MAC地址已被Marshmallow转发使用。因此您将获得虚假价值)
我们也可以使用WLAN MAC地址获取Android手机的唯一ID。 MAC地址对所有设备都是唯一的,适用于各种设备。
使用WLAN MAC地址作为设备ID的优点:
它是所有类型设备(智能手机和智能手机)的唯一标识符 片)。
如果重新安装该应用程序,它仍然是唯一的
使用WLAN MAC地址作为设备ID的缺点:
从Marshmallow及以上给你一个虚假价值。
如果设备没有wifi硬件,那么你得到空的MAC地址, 但一般来说,大多数Android设备都有wifi 硬件和市场上几乎没有设备没有wifi 硬件
消息来源:technetexperts.com
答案 8 :(得分:12)
与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”的权限请求以使用上面的代码。
答案 9 :(得分: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。
答案 10 :(得分:4)
您可以使用此TelephonyManager TELEPHONY_SERVICE 功能获取 唯一设备ID , 需要权限:READ_PHONE_STATE
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
例如, IMEI for GSM 和 MEID或ESN for 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
。答案 11 :(得分:3)
不建议使用方法getDeviceId()
。
为此getImei(int)
答案 12 :(得分:2)
使用以下代码为您提供IMEI号码:
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
System.out.println("IMEI::" + telephonyManager.getDeviceId());
答案 13 :(得分:1)
适用于API等级11或以上:
case TelephonyManager.PHONE_TYPE_SIP:
return "SIP";
TelephonyManager tm= (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
textDeviceID.setText(getDeviceID(tm));
答案 14 :(得分:1)
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-->
答案 15 :(得分:1)
您在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;
}
答案 16 :(得分:1)
使用以下代码:
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" />
答案 17 :(得分:1)
您无法从安卓 10+ 或 29+ 手机获取 imei 号码,这里是用于为设备创建 imei 号码的替代功能。
public static String getDeviceID(){
String devIDShort = "35" + //we make this look like a valid IMEI
Build.BOARD.length()%10+ Build.BRAND.length()%10 +
Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +
Build.DISPLAY.length()%10 + Build.HOST.length()%10 +
Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +
Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +
Build.TAGS.length()%10 + Build.TYPE.length()%10 +
Build.USER.length()%10 ; //13 digits
return devIDShort;
}
答案 18 :(得分: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")
}
注意:您必须使用checkSelfPermission或您使用的任何方法对上述telephonyService()
进行权限检查。
还要将此权限添加到清单文件中;
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
答案 19 :(得分:0)
尝试一下(需要始终获得第一个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();
}
答案 20 :(得分:0)
对于Android 10,以下代码对我有效。
@AfterReturning(value = "@annotation(Metric)", returning = "response")
public void afterReturning(JoinPoint joinPoint, ResponseWithStatus response) {
final Signature signature = joinPoint.getSignature();
final int responseStatus = response.getStatus();
metrics.putIfAbsent(signature, resultCounters);
if (responseStatus == ResponseStatus.SUCCESS.getValue()) {
System.out.println("Method " + signature + " returned its result");
metrics.get(signature).get(SUCCESS).increment();
} else if (errorCodes.contains(responseStatus)) {
System.out.println("Method " + signature + " returned error");
metrics.get(signature).get(ERROR).increment();
} else if (businessErrorCodes.contains(responseStatus)) {
System.out.println("Method " + signature + " returned business error");
metrics.get(signature).get(BUSINESS_ERROR).increment();
}
}
@AfterThrowing(value = "@annotation(Metric)", throwing = "exception")
public void afterThrowing(JoinPoint joinPoint, Exception exception) {
final Signature signature = joinPoint.getSignature();
final Class<? extends Exception> exceptionClass = exception.getClass();
final String exceptionName = exceptionClass.getName();
metrics.putIfAbsent(signature, resultCounters);
if (exceptionClass.equals(ValidationWebFault_Exception.class)) {
System.out.println("Method " + signature + " threw " + exceptionName);
metrics.get(signature).get(ERROR).increment();
}
}
答案 21 :(得分:0)
对不可重置设备标识符的限制
从 Android 10 开始,应用必须拥有 READ_PRIVILEGED_PHONE_STATE
特权才能访问设备的不可重置标识符,包括 IMEI 和序列号。