android 获取蓝牙设备id_获取设备唯一ID的几种方式
博客摘要:很简单,就是获取设备的唯一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的几种方式相关推荐
- 全局唯一递增的id_生成全局唯一id的几种方式
生成全局唯一id的几种方式: 1.uuid生成全球唯一id,生成方式简单粗暴,本地生成,没有网络开销,效率高:缺点长度较长,没有递增趋势性,不易维护,常用于生成token令牌. 2.mysql自带自增 ...
- 获取设备唯一ID的几种方式
博客摘要:很简单,就是获取设备的唯一ID,直接上正文. 先来看看几种比较单一的方式: IMEI 方式:TelephonyManager.getDeviceId(): 问题 范围:只能支持拥有通话功能 ...
- JavaScript 生成唯一ID的几种方式
这篇文章主要介绍了JavaScript 生成唯一ID的几种方式,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下. 编程的世界里,在很多的时候,我们都需要一个唯一的ID来代表一些数 ...
- Java生成唯一id的几种方式(已验证)
1.数据库自增序列方式 数据库方式比较简单,比如oracle可以用序列生成id,Mysql中的AUTO_INCREMENT等,这样可以生成唯一的ID,性能和稳定性依赖于数据库!如mysql主键递增: ...
- java唯一id_生成唯一ID的四种办法 程序员必备
我们在实际编程过程中会经常遇到需要用唯一ID的场合,这些唯一ID还会存到数据库中以便于我们将来进行查询. 例如用户编号.订单编号.客户编号等等,几乎凡是需要用来严格划分用户数据归属性的地方就需要用到唯 ...
- 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 实现方 ...
- 获取android设备唯一ID和用途
获取android设备唯一ID和用途 编者:李国帅 qq:9611153 微信lgs9611153 时间:2021/5/16 获取android设备唯一ID: 在android9及之前,我们还是可以获 ...
- SpringBoot实战:设备唯一ID生成【雪花算法、分布式应用】
目录 SpringBoot实战:设备唯一ID生成[雪花算法.分布式应用] 背景: snowflake(雪花算法)方案: 实现: 雪花算法生成ID: 二维码打包: 多线程优化-批量插入: 二维码识别+扫 ...
- 生成唯一id的几种方法
生成唯一id的几种方法 生成唯一id的方式有很多,UUID,自动增长列,雪花算法,redis等等. 生成id的要求: 全局唯一 趋势递增 效率高(生成.使用.索引) 控制并发 1.雪花算法(twitt ...
最新文章
- 依赖注入与Unity
- 引用asp.net母版页后,母版页和内容页的页面事件执行顺序
- 2016年10月CPU天梯图
- “混合”成为IBM Cognos新法宝
- 净值:测试编码器/解码器
- Linux内核设计与实现 总结笔记(第五章)系统调用
- HTML引入vue.js,在ie浏览器中不显示
- oracle 会话实例,返璞归真:Oracle实例级别和会话级别的参数设置辨析
- php重度写如何优化,win10玩游戏掉帧严重怎么处理
- dubbo源码解析-spi(二)
- SCPPO(十):网站发布中的问题锦集—手动发布网站
- 如何远程linux服务器桌面,LINUX操作系统如何远程登录桌面
- 台灯的内置和外置是什么意思_外置污水提升装置有哪些优势
- java spring 数据库_JAVA - SpringBoot项目引用MyBatis操作数据库
- 远程桌面连接的几种方法
- USB Still Image Capture设备类
- 教你如何攻克Kotlin中泛型型变的难点(下篇)
- 面试后HR让你等通知的真相
- PowerDesigner创始人的个人成长经历
- Oracle+Sql Server相关查询语句
热门文章
- 奇数值结点链表 (20 分)
- pandas爬虫爬取网页表格
- 科创人·望繁信创始人索强:中国版流程挖掘注定有完全不同的活法
- linux下scp的常见问题解决方法
- oj记录 牛客 高校赛 C派蒙的奇妙冒险------石之海
- GDAL综合整理--7:GDAL实用工具简介
- 计算机的新兴技术在测绘工程领域的应用,测绘新技术在测绘工程测量中应用探讨.doc...
- 局域中找不到Synology (搜索不到NAS服务器)
- Python | 阿尔法程序的控制结构
- EKL日志分析平台-kibana数据可视化