`

Android 手机上获取物理唯一标识码

阅读更多

 

   唯一标识码这东西在网络应用中非常有用,例如检测是否重复注册之类的。

 

import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
 
 

 

   我们在项目过程中或多或少会使用到设备的唯一识别码,我们希望能够得到一个稳定、可靠的设备唯一识别码。今天我们将介绍几种方式。

 

1. DEVICE_ID

 

 

假设我们确实需要用到真实设备的标识,可能就需要用到DEVICE_ID。在以前,我们的Android设备是手机,这个DEVICE_ID可以同通过 TelephonyManager.getDeviceId()获取,它根据不同的手机设备返回IMEI,MEID或者ESN码,但它在使用的过程中会遇 到很多问题:

  • 非手机设备: 如果只带有Wifi的设备或者音乐播放器没有通话的硬件功能的话就没有这个DEVICE_ID
  • 权限: 获取DEVICE_ID需要READ_PHONE_STATE权限,但如果我们只为了获取它,没有用到其他的通话功能,那这个权限有点大才小用
  • bug:在少数的一些手机设备上,该实现有漏洞,会返回垃圾,如:zeros或者asterisks的产品

 

2. MAC ADDRESS

 

我们也可以通过手机的Wifi或者蓝牙设备获取MAC ADDRESS作为DEVICE ID,但是并不建议这么做,因为并不是所有的设备都有Wifi,并且,如果Wifi没有打开,那硬件设备无法返回MAC ADDRESS.

 

3. Serial Number

在Android 2.3可以通过android.os.Build.SERIAL获取,非手机设备可以通过该接口获取。

 

4. ANDROID_ID

ANDROID_ID是设备第一次启动时产生和存储的64bit的一个数,当设备被wipe后该数重置

ANDROID_ID似乎是获取Device ID的一个好选择,但它也有缺陷:

 

  • 它在Android <=2.1 or Android >=2.3的版本是可靠、稳定的,但在2.2的版本并不是100%可靠的
  • 在主流厂商生产的设备上,有一个很经常的bug,就是每个设备都会产生相同的ANDROID_ID:9774d56d682e549c

 

5. Installtion ID : UUID

以上四种方式都有或多或少存在的一定的局限性或者bug,在这里,有另外一种方式解决,就是使用UUID,该方法无需访问设备的资源,也跟设备类型无关。

这 种方式是通过在程序安装后第一次运行后生成一个ID实现的,但该方式跟设备唯一标识不一样,它会因为不同的应用程序而产生不同的ID,而不是设备唯一 ID。因此经常用来标识在某个应用中的唯一ID(即Installtion ID),或者跟踪应用的安装数量。很幸运的,Google Developer Blog提供了这样的一个框架:

 

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();
    }
}
 

 

总结:

综 合以上所述,为了实现在设备上更通用的获取设备唯一标识,我们可以实现这样的一个类,为每个设备产生唯一的UUID,以ANDROID_ID为基础,在获 取失败时以TelephonyManager.getDeviceId()为备选方法,如果再失败,使用UUID的生成策略。

重申下,以下方法是生成Device ID,在大多数情况下Installtion ID能够满足我们的需求,但是如果确实需要用到Device ID,那可以通过以下方式实现:

 

import android.content.Context;
import android.content.SharedPreferences;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
public class DeviceUuidFactory {
    protected static final String PREFS_FILE = "device_id.xml";
    protected static final String PREFS_DEVICE_ID = "device_id";
    protected static UUID uuid;

    public DeviceUuidFactory(Context context) {
        if( uuid ==null ) {
            synchronized (DeviceUuidFactory.class) {
                if( uuid == null) {
                    final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE, 0);
                    final String id = prefs.getString(PREFS_DEVICE_ID, null );
                    if (id != null) {
                        // Use the ids previously computed and stored in the prefs file
                        uuid = UUID.fromString(id);
                    } else {
                        final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
                        // Use the Android ID unless it's broken, in which case fallback on deviceId,
                        // unless it's not available, then fallback on a random number which we store
                        // to a prefs file
                        try {
                            if (!"9774d56d682e549c".equals(androidId)) {
                                uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
                            } else {
                                final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();
                                uuid = deviceId!=null ? UUID.nameUUIDFromBytes(deviceId.getBytes("utf8")) : UUID.randomUUID();
                            }
                        } catch (UnsupportedEncodingException e) {
                            throw new RuntimeException(e);
                        }
                        // Write the value out to the prefs file
                        prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
                    }
                }
            }
        }
    }

    /**
     * Returns a unique UUID for the current android device.  As with all UUIDs, this unique ID is "very highly likely"
     * to be unique across all Android devices.  Much more so than ANDROID_ID is.
     *
     * The UUID is generated by using ANDROID_ID as the base key if appropriate, falling back on
     * TelephonyManager.getDeviceID() if ANDROID_ID is known to be incorrect, and finally falling back
     * on a random UUID that's persisted to SharedPreferences if getDeviceID() does not return a
     * usable value.
     *
     * In some rare circumstances, this ID may change.  In particular, if the device is factory reset a new device ID
     * may be generated.  In addition, if a user upgrades their phone from certain buggy implementations of Android 2.2
     * to a newer, non-buggy version of Android, the device ID may change.  Or, if a user uninstalls your app on
     * a device that has neither a proper Android ID nor a Device ID, this ID may change on reinstallation.
     *
     * Note that if the code falls back on using TelephonyManager.getDeviceId(), the resulting ID will NOT
     * change after a factory reset.  Something to be aware of.
     *
     * Works around a bug in Android 2.2 for many devices when using ANDROID_ID directly.
     *
     * @see http://code.google.com/p/android/issues/detail?id=10603
     *
     * @return a UUID that may be used to uniquely identify your device for most purposes.
     */
    public UUID getDeviceUuid() {
        return uuid;
    }
}
 

如何获取Android手机的唯一标识?

代码: 这里是你在Android里读出 唯一的 IMSI-ID / IMEI-ID 的方法。 
Java:

String myIMSI = android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMSI); 
// within my emulator it returns: 310995000000000 

String myIMEI = android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMEI); 
// within my emulator it returns: 000000000000000 
 

注:android.os.SystemProperties的标签被打上@hide了,所以sdk中并不会存在。如果需要使用,需要有android的source code支持。 

 

 

转自:http://hi.baidu.com/weizi/item/f1d6671030e7e68d88a95638

 

分享到:
评论

相关推荐

    Android手机唯一标识

    在Android操作系统中,寻找一个设备的唯一标识是一个常见的需求,特别是在开发...综上所述,"Android手机唯一标识"涉及多个标识的获取、使用和组合,需要在尊重用户隐私的同时,找到一个尽可能稳定且独特的设备标识。

    Android-一个获取Android设备唯一id的工具类

    1. **IMEI(国际移动设备识别码)**:这是GSM和UMTS网络中手机的唯一标识,可以通过`TelephonyManager`获取。IMEI对于具有物理SIM卡槽的设备是有效的,但在没有SIM卡或使用Wi-Fi连接的设备上可能不可用。 2. **...

    安卓登录注册相关-唯一标识一台Android设备手机平板手表电视.rar

    1. **IMEI(国际移动设备识别码)**:这是手机硬件的全球唯一标识,通常用于区分物理设备。每个带有蜂窝数据功能的Android设备都有一个IMEI。不过,IMEI在非手机设备(如平板、手表、电视)上可能不可用。 2. **...

    Android生成唯一标识符UUID(完全替代IMEI)

    在早期,IMEI(国际移动设备识别码)是广泛使用的设备唯一标识,但随着隐私保护政策的加强,IMEI的获取和使用受到了限制。在这种背景下,使用UUID作为IMEI的替代方案变得越来越常见。本文将深入探讨如何在Android中...

    android 获取手机上面的IMSI序列号

    在Android平台上,开发人员有时需要访问设备的特定标识符,以实现特定功能,如设备唯一标识、定位服务或网络状态检测。本文将详细介绍如何在Android应用中获取IMSI(国际移动用户识别码)、IMEI(国际移动设备识别码...

    Android_获取手机IP和MAC地址

    而MAC地址(Media Access Control Address)则是物理网络接口控制器的唯一标识,通常用于局域网内的设备识别。 在Android应用中获取IP地址,我们主要依赖于网络连接的状态。以下是一段简单的代码示例,展示了如何...

    获取 Windows Mobile 设备的唯一标识

    在开发针对Windows Mobile设备的应用程序时,...需要注意的是,随着移动平台的发展,如Windows Phone和现代的Android、iOS,获取设备唯一标识的方法可能会有所变化,因此开发者应始终关注最新的平台文档和技术更新。

    Android应用源码获取手机信息.zip源码资源下载

    2. **IMEI(国际移动设备识别码)**:IMEI是手机的唯一标识,通常用于区分不同的手机。在Android中,可以通过`TelephonyManager`的`getDeviceId()`方法获取,但需要注意,这需要`READ_PHONE_STATE`权限。 3. **MAC...

    android 获取系统信息

    MAC地址是设备在网络中的唯一物理标识。在Android中,可以通过`WifiManager`类来获取MAC地址。首先需要请求`ACCESS_WIFI_STATE`权限,然后通过`Context.getSystemService(Context.WIFI_SERVICE)`获取`WifiManager`...

    Android 移动端获取设备MAC Demo

    在Android平台上,开发移动应用时有时需要获取设备的物理MAC(Media Access Control)地址,这在设备定位、网络连接管理或者其他需要唯一标识设备的场景中非常有用。MAC地址是网络接口控制器(NIC)的硬件地址,它在...

    获取手机上的各种信息

    5. **手机MAC地址**:物理设备的唯一标识,但出于隐私考虑,Android 6.0及以后版本不再允许直接访问,需要依赖网络接口。在iOS中,自iOS 7起,Apple也限制了直接获取MAC地址,通常会返回一个随机值。 6. **IMEI...

    Android 获取手机imei值和mac值.zip

    在Android平台上,IMEI(International Mobile Equipment Identity)和MAC(Media Access Control)地址是两种用于唯一标识设备的重要标识。IMEI是手机的国际移动设备识别码,通常用于区分不同的手机设备,而MAC地址...

    jni获取Android设备MAC Address最完美解决方案

    MAC地址(Media Access Control Address)是网络设备的物理地址,每个网络接口控制器都有一个唯一的MAC地址,用于标识网络上的设备。在Android系统中,由于隐私和安全原因,直接通过Java API获取MAC地址的方法已被...

    通过NDK获得UUID

    标题"通过NDK获得UUID"和描述涉及到利用Native Development Kit (NDK) 在Android系统底层获取UUID,以及通过Java层获取Android的唯一标识码。NDK允许开发者用C/C++编写部分应用,从而提高性能,特别是对于计算密集型...

    Android获取MAC

    MAC地址是一个物理网络接口控制器的唯一标识符,用于在局域网(LAN)中区分不同的设备。以下是Android获取MAC地址的三种常见方法: ### 1. 使用`WifiManager` `WifiManager`是Android提供的一个系统服务,主要用于...

    android设备信息获取源码

    IMSI(International Mobile Subscriber Identity)是国际移动用户识别码,是运营商分配给SIM卡的唯一标识。获取IMSI同样需要`TelephonyManager`: ```java if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {...

    安卓手机mac物理地址修改工具

    在现代网络通信中,MAC(Media Access Control)地址是设备在网络中的唯一标识,通常由六组两进制数字组成,用于区分同一网络中的不同设备。在Android操作系统中,出于某些特殊需求,例如测试、隐私保护或者模拟不同...

    android 获取mac地址源码

    在Android平台上,获取设备的MAC地址是一个常见的需求,特别是在实现设备唯一标识或者网络通信时。MAC(Media Access Control)地址是设备在网络层的物理地址,它是一个48位的二进制数,通常以冒号或破折号分隔的12...

    如何使用Java代码获取Android移动终端Mac地址.zip

    在Android平台上,Mac地址是设备网络接口控制器的物理地址,通常用于唯一标识网络硬件。由于隐私和安全原因,从Android 6.0(API级别23)开始,系统对此进行了限制,不再允许应用直接获取Mac地址。不过,仍有一些...

    安卓获取手机系统内核wifi的mac地址等信息

    4. **Wi-Fi MAC地址**:在安卓设备上,每个无线网络接口都有一个物理地址,即MAC地址,用于在网络中唯一识别设备。Wi-Fi MAC地址可通过编程方式获取,一般使用`WifiManager`类的`getMacAddress()`方法。然而,从...

Global site tag (gtag.js) - Google Analytics