【android】关于如何惟一地标识一台Android设备的总结性讨论

2024-06-09 22:48

本文主要是介绍【android】关于如何惟一地标识一台Android设备的总结性讨论,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

想必大家在开发Android项目的时候,多多少少会遇到“如何惟一地标识一台Android设备”等类似的问题。不只是以前,即使是现在乃至可以预见的将来,这个问题都将一直存在。

如果大家使用搜索工具搜索的话,大家也能够找到很多的解决方案,但每种方式都多多少少有些缺陷。

我在这里呢,将向大家解释一下诸多常见方案的不足之处,以及推荐一种相对而言比较靠谱的方法。

首先先要说明一下Android设备的情况。我们大家都知道,在起初的时候,Android设备仅仅意味着是“手机”。如果情况一直是这样就好了。可是事实并不是这样的,我们知道,随着Google以及Android的发展壮大,Android系统在除了支持手机之外,也开始向其它领域发展。截止到Android 5.0的时候,Android系统已经能够支持诸如手持设备、可穿戴设备等,详细来说就是已经支持手机、平板、手表、眼镜、电视、盒子以及汽车。所有的这些情况将影响各个解决方案的实际效果。

好,下面我们来一一揭开各个解决方案不足之处的神秘面纱。

ANDROID_ID

ANDROID_ID存在于android.provider.Settings.Secure.ANDROID_ID.它可以通过下面的方式获取得到:

1 String android_id = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
View Code

这一个64位的16进制字符串。它在设备首次启动时被创建并存储起来。但是在设备恢复出厂设置或者刷机之时,将不得存在,只能在再次启动时重新生成。这是它的劣势之一。然后,还有,在2.2之前,这种方式并不是百分百可靠的。其次,在主要手持设备生产商生产的流行设备中,还有一个可以被显著观测到的bug,那就是诸多设备拥有相同的ANDROID_ID。所以,ANDROID_ID并不是一个完美的解决方案。

DEVICEID

DEVICEID,顾名思义,“设备id”。是由手机运营商添加进手机中的。它可以通过以下方式获取到:

1 TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
2 String tmDevice = "" + tm.getDeviceId();
View Code

它的返回值将依据运营商的不同,可能返回手机的IMEI或MEID或ESN。由于它是手机运营商添加进去的,所以可能存在收下诸多问题:

非手机:对于不能打电话的平板、智能手表、电视甚至汽车等非手机设备,并不存在这种惟一的标识符。

持续性问题:在拥有DEVICEID的设备上,在经过刷机或者工厂设置后,这个值有可能没有被清理干净。如果是这种情况,我们可能将它们认为是同一设备。

优先级问题:想要获取deviceid需要READ_PHONE_STATE权限。如果你在应用中并未使用到电话,使用这个权限将会很令人不安。 

已知Bug问题:这种方式的实现在有些机器上是有bug的,会返回一些垃圾信息,比如0或者"*".

所以,DEVICEID也不能完美的解决这个问题。

SIMSERIALNUMBER

SimSerialNumber也是由手机运营商放进去的,它的获取方式是这样的:

1 TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
2 String tmSerial = "" + tm.getSimSerialNumber();
View Code

它的不靠谱之处也尤如DeviceId。

SERIALNUMBER

它是2.3之后才引入的。它的值存在于android.os.Build.SERIAL.SerialNumber。但是对于不支持通话的设备,得先需要唯一的deviceid。

Mac地址

也许有人可能想到依据设备的WiFi或者蓝牙硬件来获取Mac地址来惟一标识设备。但是这种方式是不值得推荐的。因为它并非问题可以获取得到的,因为它需要设备WiFi或者蓝牙开着。所以,如果设备不打开蓝牙呢?如果设备没有打开WiFi而是使用的2G、3G或者4G呢?所以这也是一个不靠谱的方式。

UUID

以上几种标识Android设备的方式都不尽如人意思。难道就没有一种方式可以稳定、可靠且唯一地标识Androi硬件设备的吗?

诶,等一等,标识Android设备非得使用设备的硬件信息吗?难得使用非硬件就不能标识设备了吗?

好吧,答案是UUID。UUID(Universal Unique ID)是软件界的“通用唯一ID”, 是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字

UUID由以下几部分的组合:

  1. 当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
  2. 时钟序列。
  3. 全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。

UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函数很简单地生成UUID,其格式为:xxxxxxxx-xxxx- xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx (8-4-4-4-12),可以从cflib 下载CreateGUID() UDF进行转换。

对于一个开发人员而言,想要追踪应用的每一次安装,是非常普遍,也十分合乎情理的。 要追踪应用的安装,你可以使用 UUID 来作为标识,在安装之后应用首次运行之时创建它。下面是一个叫作“ Intallation ”的类,带有一个静态方法id(Context context),返回应用的UUID 。你可以将更多有关安装的数据写入”ISTALLATION”文件中。

 1 public class Installation {
 2     private static String sID = null;
 3     private static final String INSTALLATION = "INSTALLATION";
 4 
 5     public synchronized static String id(Context context) {
 6         if (sID == null) {  
 7             File installation = new File(context.getFilesDir(), INSTALLATION);
 8             try {
 9                 if (!installation.exists())
10                     writeInstallationFile(installation);
11                 sID = readInstallationFile(installation);
12             } catch (Exception e) {
13                 throw new RuntimeException(e);
14             }
15         }
16         return sID;
17     }
18 
19     private static String readInstallationFile(File installation) throws IOException {
20         RandomAccessFile f = new RandomAccessFile(installation, "r");
21         byte[] bytes = new byte[(int) f.length()];
22         f.readFully(bytes);
23         f.close();
24         return new String(bytes);
25     }
26 
27     private static void writeInstallationFile(File installation) throws IOException {
28         FileOutputStream out = new FileOutputStream(installation);
29         String id = UUID.randomUUID().toString();
30         out.write(id.getBytes());
31         out.close();
32     }
33 }
Installation.java

它是通过软件产生的UUId来惟一地标识软件在该设备上的安装来标识这台设备,而非通过硬件信息。当然,这种方式是通过将UUID保存在本地文件中来实现的,如果你清空了本应用数据或者删除了该文件的话,应用将重新生成一个UUID,这也就意味着设备的惟一标识符发生了变化,这是一台新设备。

UUID是一个随机的数值,那么它万一发生了重复值呢?好吧,这是一串32位的十六进制的数字,它产生重复值的概率是16的32次方之一,自己去算概率!!!



转载:http://www.cnblogs.com/littlepanpc/p/4198604.html

这篇关于【android】关于如何惟一地标识一台Android设备的总结性讨论的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1046521

相关文章

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

如何在一台服务器上使用docker运行kafka集群

《如何在一台服务器上使用docker运行kafka集群》文章详细介绍了如何在一台服务器上使用Docker运行Kafka集群,包括拉取镜像、创建网络、启动Kafka容器、检查运行状态、编写启动和关闭脚本... 目录1.拉取镜像2.创建集群之间通信的网络3.将zookeeper加入到网络中4.启动kafka集群

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超