博客摘要:很简单,就是获取设备的唯一ID,直接上正文。

先来看看几种比较单一的方式:

IMEI

方式:TelephonyManager.getDeviceId():

问题

范围:只能支持拥有通话功能的设备,对于平板不可以。

持久性:返厂,数据擦除的时候不彻底,保留了原来的标识。

权限:需要权限:android.permission.READ_PHONE_STATE

bug: 有些厂家的实现有bug,返回一些不可用的数据

Mac地址

ACCESS_WIFI_STATE权限

有些设备没有WiFi,或者蓝牙,就不可以,如果WiFi没有打开,硬件也不会返回Mac地址,不建议使用

ANDROID_ID

2.2(Froyo,8)版本系统会不可信,来自主要生产厂商的主流手机,至少有一个普遍发现的bug,这些有问题的手机相同的ANDROID_ID: 9774d56d682e549c

但是如果返厂的手机,或者被root的手机,可能会变

Serial Number

从Android 2.3 (“Gingerbread”)开始可用,可以通过android.os.Build.SERIAL获取,对于没有通话功能的设备,它会

返回一个唯一的device ID,

以下几个是stackoverflow上评论较多的几个,没贴完,还有其他,综合的,用到以上的部分方式:

有兴趣的朋友可以再仔细看看

支持率比较高的(支持票数157):androidID --> 剔除2.2版本(API 8)中有问题的手机,使用UUID替代

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 volatile 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;

}

}

根据版本进行判断的方式:Serial序列号-->UUID (支持数31)

通过Serial 即可,在覆盖率上,你已经成功的获得了98.4%的用户,剩下的1.6%的用户系统是在9 以下的。

通过AndroidID获取,前面已经说过,在8上,有些商家的手机会有一些bug,返回相同的AndroidID,如果Serial和AndroidID都不行

/**

Return pseudo unique ID

@return ID

*/

public static String getUniquePsuedoID()

{

// If all else fails, if the user does have lower than API 9 (lower

// than Gingerbread), has reset their phone or 'Secure.ANDROID_ID'

// returns 'null', then simply the ID returned will be solely based

// off their Android device information. This is where the collisions

// can happen.

// Thanks http://www.pocketmagic.net/?p=1662!

// Try not to use DISPLAY, HOST or ID - these items could change.

// If there are collisions, there will be overlapping data

String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);

// Thanks to @Roman SL!

// http://stackoverflow.com/a/4789483/950427

// Only devices with API >= 9 have android.os.Build.SERIAL

// http://developer.android.com/reference/android/os/Build.html#SERIAL

// If a user upgrades software or roots their phone, there will be a duplicate entry

String serial = null;

try

{

serial = android.os.Build.class.getField("SERIAL").get(null).toString();

// Go ahead and return the serial for api => 9

return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();

}

catch (Exception e)

{

// String needs to be initialized

serial = "serial"; // some value

}

// Thanks @Joe!

// http://stackoverflow.com/a/2853253/950427

// Finally, combine the values we have found by using the UUID class to create a unique identifier

return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();

}

不用READ_PHONE_STATE权限直接获取ROM信息的方式:(支持率较低 16)

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

最后贴上自己在项目中用的:

public static String getDeviceId(Context context) {

String deviceId = "";

if (deviceId != null && !"".equals(deviceId)) {

return deviceId;

}

if (deviceId == null || "".equals(deviceId)) {

try {

deviceId = getLocalMac(context).replace(":", "");

} catch (Exception e) {

e.printStackTrace();

}

}

if (deviceId == null || "".equals(deviceId)) {

try {

deviceId = getAndroidId(context);

} catch (Exception e) {

e.printStackTrace();

}

}

if (deviceId == null || "".equals(deviceId)) {

if (deviceId == null || "".equals(deviceId)) {

UUID uuid = UUID.randomUUID();

deviceId = uuid.toString().replace("-", "");

writeDeviceID(deviceId);

}

}

return deviceId;

}

// IMEI码

private static String getIMIEStatus(Context context) {

TelephonyManager tm = (TelephonyManager) context

.getSystemService(Context.TELEPHONY_SERVICE);

String deviceId = tm.getDeviceId();

return deviceId;

}

// Mac地址

private static String getLocalMac(Context context) {

WifiManager wifi = (WifiManager) context

.getSystemService(Context.WIFI_SERVICE);

WifiInfo info = wifi.getConnectionInfo();

return info.getMacAddress();

}

// Android Id

private static String getAndroidId(Context context) {

String androidId = Settings.Secure.getString(

context.getContentResolver(), Settings.Secure.ANDROID_ID);

return androidId;

}

public static void saveDeviceID(String str) {

try {

FileOutputStream fos = new FileOutputStream(file);

Writer out = new OutputStreamWriter(fos, "UTF-8");

out.write(str);

out.close();

} catch (IOException e) {

e.printStackTrace();

}

}

public static String readDeviceID() {

StringBuffer buffer = new StringBuffer();

try {

FileInputStream fis = new FileInputStream(file);

InputStreamReader isr = new InputStreamReader(fis, "UTF-8");

Reader in = new BufferedReader(isr);

int i;

while ((i = in.read()) > -1) {

buffer.append((char) i);

}

in.close();

return buffer.toString();

} catch (IOException e) {

e.printStackTrace();

return null;

}

}

对于获取设备唯一ID并没有绝对的方案,这一点在android的官方博客中也提到了,不过以上几种方案,应该可以满足平时的需求,大家可以选择其中自己认为比较好的,用于自己的项目中。不知道其他朋友在项目中是如何处理的,欢迎交流讨论。

android 获取蓝牙设备id_获取设备唯一ID的几种方式相关推荐

  1. 全局唯一递增的id_生成全局唯一id的几种方式

    生成全局唯一id的几种方式: 1.uuid生成全球唯一id,生成方式简单粗暴,本地生成,没有网络开销,效率高:缺点长度较长,没有递增趋势性,不易维护,常用于生成token令牌. 2.mysql自带自增 ...

  2. 获取设备唯一ID的几种方式

    博客摘要:很简单,就是获取设备的唯一ID,直接上正文. 先来看看几种比较单一的方式:  IMEI 方式:TelephonyManager.getDeviceId(): 问题 范围:只能支持拥有通话功能 ...

  3. JavaScript 生成唯一ID的几种方式

    这篇文章主要介绍了JavaScript 生成唯一ID的几种方式,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下. 编程的世界里,在很多的时候,我们都需要一个唯一的ID来代表一些数 ...

  4. Java生成唯一id的几种方式(已验证)

    1.数据库自增序列方式 数据库方式比较简单,比如oracle可以用序列生成id,Mysql中的AUTO_INCREMENT等,这样可以生成唯一的ID,性能和稳定性依赖于数据库!如mysql主键递增: ...

  5. java唯一id_生成唯一ID的四种办法 程序员必备

    我们在实际编程过程中会经常遇到需要用唯一ID的场合,这些唯一ID还会存到数据库中以便于我们将来进行查询. 例如用户编号.订单编号.客户编号等等,几乎凡是需要用来严格划分用户数据归属性的地方就需要用到唯 ...

  6. Android Q 获取设备唯一ID(UDID\GUID\UUID\SSAID\GAID)

    Android Q获取设备唯一ID(UDID\GUID\UUID\SSAID\GAID) 一.简介 1.1 问题背景 1.2 关键技术 二.解决方案 2.1 谷歌官方推荐方案 (4种) 2.2 实现方 ...

  7. 获取android设备唯一ID和用途

    获取android设备唯一ID和用途 编者:李国帅 qq:9611153 微信lgs9611153 时间:2021/5/16 获取android设备唯一ID: 在android9及之前,我们还是可以获 ...

  8. SpringBoot实战:设备唯一ID生成【雪花算法、分布式应用】

    目录 SpringBoot实战:设备唯一ID生成[雪花算法.分布式应用] 背景: snowflake(雪花算法)方案: 实现: 雪花算法生成ID: 二维码打包: 多线程优化-批量插入: 二维码识别+扫 ...

  9. 生成唯一id的几种方法

    生成唯一id的几种方法 生成唯一id的方式有很多,UUID,自动增长列,雪花算法,redis等等. 生成id的要求: 全局唯一 趋势递增 效率高(生成.使用.索引) 控制并发 1.雪花算法(twitt ...

最新文章

  1. 依赖注入与Unity
  2. 引用asp.net母版页后,母版页和内容页的页面事件执行顺序
  3. 2016年10月CPU天梯图
  4. “混合”成为IBM Cognos新法宝
  5. 净值:测试编码器/解码器
  6. Linux内核设计与实现 总结笔记(第五章)系统调用
  7. HTML引入vue.js,在ie浏览器中不显示
  8. oracle 会话实例,返璞归真:Oracle实例级别和会话级别的参数设置辨析
  9. php重度写如何优化,win10玩游戏掉帧严重怎么处理
  10. dubbo源码解析-spi(二)
  11. SCPPO(十):网站发布中的问题锦集—手动发布网站
  12. 如何远程linux服务器桌面,LINUX操作系统如何远程登录桌面
  13. 台灯的内置和外置是什么意思_外置污水提升装置有哪些优势
  14. java spring 数据库_JAVA - SpringBoot项目引用MyBatis操作数据库
  15. 远程桌面连接的几种方法
  16. USB Still Image Capture设备类
  17. 教你如何攻克Kotlin中泛型型变的难点(下篇)
  18. 面试后HR让你等通知的真相
  19. PowerDesigner创始人的个人成长经历
  20. Oracle+Sql Server相关查询语句

热门文章

  1. 奇数值结点链表 (20 分)
  2. pandas爬虫爬取网页表格
  3. 科创人·望繁信创始人索强:中国版流程挖掘注定有完全不同的活法
  4. linux下scp的常见问题解决方法
  5. oj记录 牛客 高校赛 C派蒙的奇妙冒险------石之海
  6. GDAL综合整理--7:GDAL实用工具简介
  7. 计算机的新兴技术在测绘工程领域的应用,测绘新技术在测绘工程测量中应用探讨.doc...
  8. 局域中找不到Synology (搜索不到NAS服务器)
  9. Python | 阿尔法程序的控制结构
  10. EKL日志分析平台-kibana数据可视化