Unity获取手机设备唯一标识

您所在的位置:网站首页 设备imei异常 Unity获取手机设备唯一标识

Unity获取手机设备唯一标识

2024-07-14 00:21| 来源: 网络整理| 查看: 265

前言

公司开发的游戏需要对用户设备进行标识,获得一个稳定可靠并且唯一的识别码,来作游客登录。并考虑后续玩家从游客换成账户登录数据要同步过来。

虽然Android系统中提供了这样设备识别码,但是由于Android系统版本、厂商定制系统中的Bug等限制,稳定性和唯一性并不理想。而通过其他硬件信息标识也因为系统版本、手机硬件等限制存在不同程度的问题。

下面汇总了一些能作为设备唯一标识的方案。

方案

方案大致分为三个方向,第一个方向就是安卓系统提供的一系列接口,获取具有唯一属性的码,比如imei,MAC,android_id等;第二个方向就是unity自带的API;第三个方向就是自定义计算ID。

一.安卓系统原生

如果不会unity与安卓交互可参考我的上一篇博客:Android与Unity交互及手机震动控制

安卓系统获取串码 参考资料: 获取Android设备唯一标识码 参考资料: 获取Android设备的唯一标识符 参考资料: Android设备唯一标识 参考资料: Android 手机获取Mac地址的方法

主要串码:

IMEI:(国际移动设备识别码(IMEI:International Mobile Equipment Identification Number)是区别移动设备的标志,储存在移动设备中,可用于监控被窃或无效的移动设备。

android系统中通常用下面这段代码获取:

/** * 获取手机IMEI号 * * 需要动态权限: android.permission.READ_PHONE_STATE */ public static String getIMEI(Context context) { TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE); String imei = telephonyManager.getDeviceId(); return imei; }

MEID:Mobile Equipment IDentifier(MEID)是全球唯一的56bit移动终端标识号。标识号会被烧入终端里,并且不能被修改。 没有统一的获取方法!

MAC ADDRESS:(Media Access Control Address),直译为媒体存取控制位址,也称为局域网地址(LAN Address),MAC位址,以太网地址(Ethernet Address)或物理地址(Physical Address),它是一个用来确认网络设备位置的位址。

android系统中通常用下面这段代码获取:

/** * 通过WiFiManager获取mac地址 * @param context * @return */ private static String tryGetWifiMac(Context context) { WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); WifiInfo wi = wm.getConnectionInfo(); if (wi == null || wi.getMacAddress() == null) { return null; } if ("02:00:00:00:00:00".equals(wi.getMacAddress().trim())) { return null; } else { return wi.getMacAddress().trim(); } }

ANDROID_ID:在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID,当设备被wipe后该值会被重置。

android系统中通常用下面这段代码获取:

String ANDROID_ID = Settings.System.getString(getContentResolver(), Settings.System.ANDROID_ID);

android.os.Build:根据手机硬件的型号返回串码,所以不同手机具有不同的串码,但是同型号的手机会重码。

android系统中通常用下面这段代码获取:

设备序列号(Serial Number, SN) String serialNum = android.os.Build.SERIAL; 制造商 (Manufacturer) String manufacturer = android.os.Build.MANUFACTURER; 型号(Model) String model = android.os.Build.MODEL; 品牌(Brand) String brand = android.os.Build.BRAND; 设备名 (Device) String device = android.os.Build.DEVICE; 二.Unity自带API

参考资料官方API文档 使用Unity自带的API,SystemInfo.deviceUniqueIdentifier获取。

string 设备唯一标识符= SystemInfo.deviceUniqueIdentifier; 三.自定义计算ID

这一套方案就是,服务器端采用流水号算法生成唯一码,然后下推给客户端,客户端将这个唯一码保存,最好设置为初始时自动截屏把唯一码保存在相册里。

方案对比

在这里插入图片描述

踩坑与解决

天坑1:在采用安卓系统原生的方案时,起初使用的是imei码,装上手机发现重号。后来发现这个码在安卓P之后压根不让你获取,会返回空值,所以重号。

天坑2:后来加上设备硬件计算串码,刚开始还好,没什么问题,后来两台同型号的手机鬼使神差般的重号了,原因是当手机型号相同,通过手机硬件获取的串码就会一样,那么重号就不奇怪了。

天坑3:在采用了 imei和硬件设备串码后,还得继续添加新的串码段,经研究android_id的串码是imei后最为合适的,然后就把android_id加上了,这下很欣喜发现不重号了,同型号手机也不同号,好了可以放心了。好景不长,原先打包的同学没在不能打包了,于是用自己的电脑打包,这下好,一安装,全体的ID都成新的了,之前升级了的数据都不在了。研究了好久,发现自Android 8.0(API级别26)起,ANDROID_ID取决于应用程序的签名密钥。这意味着“未签名”构建(默认情况下使用调试密钥库进行签名)的值将不同于已签名构建(使用播放器设置中提供的密钥进行签名)。所以也就有了换一台机器打包就有不同的串码值。

解决:踩了这么多坑怎么解决呢?如上面所说,想要达到不同的机器打包出的串码都是一致的,需要做一个密钥,然后大家的电脑都使用这个密钥,然后结合 ANDROID_ID返回的串码使用。这样 获取手机设备唯一标识算告一段落了。但仍不是完美的方案。

不完美 :为什么上述的不是完美的方案呢?因为各手机厂商不同ANDROID_ID的计算方式有所不同,会可能出现重号的现象,概率很小。除此之外由于Android系统版本、厂商定制系统中的Bug等限制,稳定性和唯一性并不理想。使用的体量一大,说不定也会出现重号和换号的情况。那有没有更好的方案,我想没有,但有可选方案,就是我上面说的自定义ID,这个方案的好处是,可以保证ID的唯一性,缺点就是玩家一旦卸载,再重新安装就会视为新用户,如果想找回账户,得查看手机里自动保存到相册的账号图片,经过一番找回操作才行。万一玩家将这张图片删除或清除了,那想要找回就只能是天方夜谭。

总结

获取设备唯一标识符没有完美的方案,做联网手游应当拒绝这个需求,直接引导玩家进行账号注册。 当然在临时测试阶段使用安卓系统原生的方式,是一个不错的选择。

文中的代码及工程下载:Android2Unity.zip



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3