Android设备的唯一ID

问题描述:

我想要一些Android设备的唯一ID。我用下面的代码试过它Android设备的唯一ID

String ts = Context.TELEPHONY_SERVICE; 
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(ts); 

但是我知道这只适用于手机。

如果我的应用程序在某些笔记本,上网本或其他类型的设备上运行,该怎么办?在这种情况下,我如何获得唯一的ID?

+2

@Mudassir:所以基本上你想要的东西,是 '一成不变', '硬编码',这永远不会改变和100%可靠?英特尔尝试过...阅读此schneier.com/essay-187.html – Squonk 2010-12-17 08:00:17

+0

@MisterSquonk我想要的东西。我喜欢“镶石头”。 :-) – Mudassir 2010-12-17 08:43:50

+0

@Mudassir:祝你好运,但如果你能找到它,我会感到惊讶。至多我会研究最不可能被改变/被黑客攻击的东西的原则,或者将其作为可能的'独特'的基础。之后,尝试编写代码以弥补一路上的任何问题。 – Squonk 2010-12-17 09:00:58

看看常量 ANDROID_IDandroid.provider.Secure.Settings看看是否有帮助。

我在官方文档中添加了一些有用的链接;

+0

http://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID – Mudassir 2010-12-17 07:23:16

+0

手机重置为出厂默认设置时可以更改。请参阅之前评论中的链接。 – Mudassir 2010-12-17 07:23:42

+1

@Mudassir:这个问题确实会说“如果我的应用程序在某些笔记本,上网本或其他类型的设备上运行,如何在这种情况下获得唯一的ID? – 2010-12-17 07:25:57

使用MAC address

媒体访问控制地址(MAC 地址)是分配给网络接口

连接到网络的任何装置被保证有一个唯一的标识符 MAC地址,你可以通过转到设置>关于手机>状态在Android上找到它。

您应该能够使用Bluetooth API获取蓝牙Mac地址。

+0

我不知道Android是否免疫,但MAC地址可能伪造在许多系统上。 – Squonk 2010-12-17 07:23:45

+0

它可用于上网本或平板电脑类设备?我怎样才能以编程方式获得它? – Mudassir 2010-12-17 07:28:30

+2

是的任何设备上的MAC(或至少是本地报告)都可以被覆盖。 – 2010-12-17 07:29:26

我不能写评论现在,所以我写在这里。

如果网络设备(蓝牙等)在系统中启用(打开),您可以获得MAC地址。但是设备可能有蓝牙或Wi-Fi等,或没有

您可以编写自己的唯一ID发生器(20个数字或符号随机为例)

+0

我想识别唯一的设备。我怎样才能使用随机数字发生器? – Mudassir 2010-12-17 08:50:22

+0

这是个大问题,因为UID应该由设备开发人员实施。 生成ID,保存在SharedPrefference中并用于识别设备 – mysuperass 2010-12-17 09:04:12

有三种类型的Android手机上的标识符。

  1. IMEI
  2. IMSI

    String ts = Context.TELEPHONY_SERVICE; 
    TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts); 
    String imsi = mTelephonyMgr.getSubscriberId(); 
    String imei = mTelephonyMgr.getDeviceId(); 
    
  3. 的Android ID 它是其上的设备的第一引导所生成的64位的十六进制字符串。 一般情况下,除非出厂重置,否则不会更改。

    Secure.getString(getContentResolver(), Secure.ANDROID_ID); 
    
+3

已更新3:String unique_id = android.provider.Settings.Secure.getString(getContentResolver(),android.provider.Settings.Secure.ANDROID_ID);参考:http://developer.android。com/reference/android/provider/Settings.Secure.html#ANDROID_ID – 2011-08-04 06:56:54

有关如何获得一个唯一标识您的应用程序是从安装在每台Android设备,看到这个官方Android开发者博客中详细说明:

http://android-developers.blogspot.com/2011/03/identifying-app-installations.html

看来最好的方法是在安装时生成一个自己的文件,然后在应用程序重新启动时读取它。

我个人觉得这可以接受但并不理想。没有任何一个由Android提供的标识符在所有情况下工作,因为大多数标识符都依赖于手机的无线电状态(无线开/关,手机开/关,蓝牙开/关)。其他像Settings.Secure.ANDROID_ID必须由制造商实施,并不保证是唯一的。

以下是将数据写入INSTALLATION文件的示例,该文件可与应用程序在本地保存的任何其他数据一起存储。

public class Installation { 
    private static String sID = null; 
    private static final String INSTALLATION = "INSTALLATION"; 

    public synchronized static String id(Context context) { 
     if (sID == null) { 
      File installation = new File(context.getFilesDir(), INSTALLATION); 
      try { 
       if (!installation.exists()) 
        writeInstallationFile(installation); 
       sID = readInstallationFile(installation); 
      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
     } 
     return sID; 
    } 

    private static String readInstallationFile(File installation) throws IOException { 
     RandomAccessFile f = new RandomAccessFile(installation, "r"); 
     byte[] bytes = new byte[(int) f.length()]; 
     f.readFully(bytes); 
     f.close(); 
     return new String(bytes); 
    } 

    private static void writeInstallationFile(File installation) throws IOException { 
     FileOutputStream out = new FileOutputStream(installation); 
     String id = UUID.randomUUID().toString(); 
     out.write(id.getBytes()); 
     out.close(); 
    } 
} 
+0

博客说:“对于绝大多数应用程序,要求是识别特定的安装,而不是物理设备”,但上面的代码创建的id不是' t可靠,就好像用户清除应用程序数据一样,设备ID被移除并且它创建新的设备ID。测试10次,每次创建新的ID。 :( – junto 2012-03-11 18:16:21

Secure.getString(getContentResolver(), Secure.ANDROID_ID); 

这不会对所有的设备上工作。

某些android设备出现问题有些设备在我们尝试获取设备ID时返回null。解决此问题的唯一方法是生成应该由我们生成的伪设备ID。此功能将生成一个唯一的设备ID。您可以根据需要对此功能进行更改。我也为解决此问题而苦苦挣扎。

public String getDeviceID() { 

/*String Return_DeviceID = USERNAME_and_PASSWORD.getString(DeviceID_key,"Guest"); 
return Return_DeviceID;*/ 

TelephonyManager TelephonyMgr = (TelephonyManager) getApplicationContext().getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); 
String m_szImei = TelephonyMgr.getDeviceId(); // Requires 
// READ_PHONE_STATE 

// 2 compute DEVICE ID 
String m_szDevIDShort = "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 
// 3 android ID - unreliable 
String m_szAndroidID = Secure.getString(getContentResolver(),Secure.ANDROID_ID); 
// 4 wifi manager, read MAC address - requires 
// android.permission.ACCESS_WIFI_STATE or comes as null 
WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress(); 
// 5 Bluetooth MAC address android.permission.BLUETOOTH required 
BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter 
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
String m_szBTMAC = m_BluetoothAdapter.getAddress(); 
System.out.println("m_szBTMAC "+m_szBTMAC); 

// 6 SUM THE IDs 
String m_szLongID = m_szImei + m_szDevIDShort + m_szAndroidID+ m_szWLANMAC + m_szBTMAC; 
System.out.println("m_szLongID "+m_szLongID); 
MessageDigest m = null; 
try { 
m = MessageDigest.getInstance("MD5"); 
} catch (NoSuchAlgorithmException e) { 
e.printStackTrace(); 
       } 
m.update(m_szLongID.getBytes(), 0, m_szLongID.length()); 
byte p_md5Data[] = m.digest(); 

String m_szUniqueID = new String(); 
for (int i = 0; i < p_md5Data.length; i++) { 
int b = (0xFF & p_md5Data[i]); 
// if it is a single digit, make sure it have 0 in front (proper 
// padding) 
if (b <= 0xF) 
m_szUniqueID += "0"; 
// add number to string 
m_szUniqueID += Integer.toHexString(b); 
} 
m_szUniqueID = m_szUniqueID.toUpperCase(); 

Log.i("-------------DeviceID------------", m_szUniqueID); 
Log.d("DeviceIdCheck", "DeviceId that generated MPreferenceActivity:"+m_szUniqueID); 

return m_szUniqueID; 

} 
+0

不错,谢谢。:) – Mudassir 2012-04-24 08:46:22

+0

如果你把它正确接受答案...高兴地帮助你:-) – 2012-04-24 08:49:09

Settings.Secure#ANDROID_ID返回Android ID作为唯一的64位十六进制字符串。

import android.provider.Settings.Secure; 

private String android_id = Secure.getString(getContext().getContentResolver(), 
                 Secure.ANDROID_ID); 

对不起碰到一个古老的线程,但这个问题让我头疼,我发现有人读的好文章,这真的帮助了我很多。

有时在Android应用程序开发期间需要获取基于Android的智能手机设备的唯一ID。当用户想要跟踪应用程序的独特设备安装时,这是非常必要的。

这对于Android开发人员只想将推送消息发送给少数特定设备的情况也很有用。因此,在这里,每个设备都需要有一个UDID。

在Android中,有许多设备UDID的替代品。下面列出了在android应用程序中获取UDID的一些方法,其优点和缺点以及获取设备ID的任何必要权限。

  • 的IMEI:(国际移动设备身份)
  • Android的ID
  • 的WLAN MAC地址串
  • 蓝牙地址串

1)IMEI:(国际移动设备标识)

IMEI号码是一个很好的并获取设备ID的主要来源。它对于每个设备都是独一无二的,并且依赖于设备硬件。所以它对于每一个设备都是独一无二的,它在设备的使用寿命中是永久的。

的代码片段来获得设备IMEI是如下,

TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); 
String m_deviceId = TelephonyMgr.getDeviceId(); 

对于这个应用程序将需要在清单文件中给出的许可“android.permission.READ_PHONE_STATE”。使用IMEI作为设备ID的

优点:

该IMEI是为每个设备是唯一的。 即使应用程序已重新安装,或者设备已植根或出厂重置,它仍然是唯一的设备。使用IMEI作为设备ID的

缺点:

IMEI是依赖于装置的simcard的狭槽,因此,不可能得到用于IMEI不使用simcard的设备。 在Dual sim设备中,我们为同一设备获得2个不同的IMEI,因为它有2个SIM卡插槽。

2)的Android ID

的Android_ID是生成并当设备首次引导存储一个唯一的64位数字。设备出厂重置并生成新设备时,Android_ID将被清除。

的代码即可获得Android_ID如下所示,使用作为Android_ID设备ID的

String m_androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID); 

优点:

它是所有类型的设备的唯一标识符(智能手机和片剂)。 不需要任何许可。

它将在所有设备中保持唯一性,并且适用于没有SIM卡插槽的手机。

缺点使用Android_ID设备ID的:

如果Android操作系统版本用户升级那么这可能会改变。 如果设备在设备上进行了根或出厂重置,则ID将被更改。 另外还有一个中国的Android设备制造商的一个已知的问题,一些设备具有相同的Android_ID。

3)WLAN MAC地址字符串

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

的代码片段来获得WLAN MAC地址的装置如下所示,

WifiManager m_wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); 
String m_wlanMacAdd = m_wm.getConnectionInfo().getMacAddress(); 

你的应用程序将需要在清单文件给出的许可“android.permission.ACCESS_WIFI_STATE”。

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

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

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

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

4)蓝牙地址字符串

我们可以得到使用蓝牙设备还Android手机的唯一ID。蓝牙设备地址对于具有蓝牙硬件的每个设备是唯一的。

的代码片段,以获得蓝牙设备地址是如下,

BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
String m_bluetoothAdd = m_BluetoothAdapter.getAddress(); 

要得到上面的代码,你的应用程序需要在清单文件中给出的许可“android.permission.BLUETOOTH”。

使用蓝牙设备地址作为设备ID的优点设备ID: 它是所有类型设备(智能手机和平板电脑)的唯一标识符。 所有设备中通常都有一个蓝牙硬件,它不会被更改。

使用蓝牙设备地址作为设备ID的缺点设备ID: 如果设备没有蓝牙硬件,那么您将得到空。

正如我所知,这些都是获得Android智能手机设备唯一设备ID和使用它的优点和缺点的最佳方式。现在,您可以根据Android应用程序开发需求决定使用哪种方法。

如果还有其他的方法来获取UDID,并且掩盖了上述方法的缺点,那么我很乐意在我的Android应用程序中探索这些方法。 PL。分享评论框中的内容以及任何建议或疑问。

Here's the article

TextView textAndroidId = (TextView)findViewById(R.id.androidid); 
String AndroidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); 
textAndroidId.setText("My ID is: " + AndroidId); 

final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE); 

    final String tmDevice, tmSerial, tmPhone, androidId; 
    tmDevice = "" + tm.getDeviceId(); 
    tmSerial = "" + tm.getSimSerialNumber(); 
    androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); 

    UUID deviceUuid = new UUID(androidId.hashCode(), ((<span id="IL_AD3" class="IL_AD">long</span>)tmDevice.hashCode() << 32) | tmSerial.hashCode()); 
    String deviceId = deviceUuid.toString(); 

你可以试试这个:

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