Android体系ID知多少?【技术类】

摘要:移动Android设备体系ID您知道多少?

既本系列《移动设备ID烦恼知多少?》《IOS体系ID知多少?》后我们来详细看一下Android体系中的各种设备ID吧:

虽然Android相对能获取到的ID的权利没有IOS限制的那么严格,但是也正是Android的山寨机横行、2014年Android2.3基于Google Play推出了IDFA、各种ID满天飞可能导致的麻烦问题比IOS只会多不会少。

一、Android6.0带来的噩耗:

另外还有个噩耗是已发布有一段时间的Android6.0(代号棉花糖)推出了“运行时权限”,简单说就是App若需要获取高密级的权限需要每次询问用户是否同意,如下图所示(左申请单权限、右同时申请多权限):

而不是像之前那样在App安装的时候需要的权限全打上了勾,用户也不在意,安装好之后用户也不能取消这些权限。如下图所示:

Android6.0系统还提供了一个用户可以管理应用权限的界面,通过这个界面用户可以把已经授予的权限再关闭,界面长得是这样的:


二、IMEI

只有Android手机才获取的到, IMEI号是一串15位的号码,比如像这样 359881030314356

获取代码如下:

TelephonyManager TelephonyMgr =(TelephonyManager)getSystemService(TELEPHONY_SERVICE);

String szImei = TelephonyMgr.getDeviceId();

需要权限<uses-permissionandroid:name="android.permission.READ_PHONE_STATE" />

通常用户会因为你向他们要了这个权限而给你一个差评,因为他们觉得你就是在窃取他们的隐私,很明显,你就是在收集一些数据。

注意:Android6.0运行时对此做了权限限制:

其中“READ_PHONE_STATE”权限是用来获取deviceID,即IMEI号码。所以一般建议在完全支持运行时权限之前,将对应的值写入到App本地数据中,对于新安装的,可以采取其他策略减少对统计的影响。

我们大概统计了一下目前Android6.0大体市场占比及IMEI用户关闭获取权限的数据如下:

Android6.0在Android占比20%左右,其中6.0有35%左右的用户会禁止获取IMEI。

三、无线网卡地址:

APP端无线网卡mac地址获取方法:

WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE);

WifiInfowifiInfo=wifiManager.getConnectionInfo();

String mac=wifiInfo.getMacAddress();

这种方法比较通用。


注意:最近在Android 6.0系统上,这个方法失效了,返回了“02:00:00:00:00:00”的常量。这并不是一个BUG,在google的博客中找到如下一段话:

Most notably, Local WiFi and Bluetooth MACaddresses are no longer available. The getMacAddress() method of a WifiInfoobject and the BluetoothAdapter.getDefaultAdapter().getAddress() method willboth return 02:00:00:00:00:00 from now on.

可以考虑使用NetworkInterface.getHardwareAddress。其原理和cat/sys/class/net/wlan0/address是一模一样的,但是这个是上层API,不需要自己处理底层数据,在Android 6.0上测试通过。

NetworkInterface networkInterface =NetworkInterface.getByName("wlan0");

byte[] mac =networkInterface.getHardwareAddress();

问题:

1.如果重启手机后,Wifi没有打开过,是无法获取其Mac地址的。(可以考虑授予CHANGE_WIFI_STATE权限,开关一次wifi刷一下。)

2.有一些定制系统的目录并不一样。 例如三星的目录为"cat/sys/class/net/eth0/address",所以是否对所以机型都有效有待验证。(需要适配)

3.网上也有反映mac变更问题,是不是刷mac或者wifi故障导致,也不确定。

4.并不是所有的设备都有Wifi硬件,硬件不存在自然也就得不到这一信息。(这个还好)

5.需要 ACCESS_WIFI_STATE 权限。(这个权限还好,用户比较容易通过)

B.通过WIFI上网或WIFI AP探针SSID广播扫描WIFI AP均可以获取这个设备的MAC地址。

四、ANDROID_ID

在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID,当设备被恢复出厂设置后该值会被重置。可以通过下面的方法获取:

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

ANDROID_ID可以作为设备标识,但需要注意:
它在Android <=2.1 or Android>=2.3的版本是可靠、稳定的,但在2.2的版本并不是100%可靠的。
厂商定制系统的Bug:不同的设备可能会产生相同的ANDROID_ID:9774d56d682e549c。(摩托罗拉好像出现过这个问题)
厂商定制系统的Bug:有些设备返回的值为null。
设备差异:对于CDMA设备,ANDROID_ID和TelephonyManager.getDeviceId() 返回相同的值。
并且,如果某个Andorid手机被Root过的话,这个ID也可以被改变。

五、设备序列号(Serial Number, SN)

获取办法:

String serialNum = android.os.Build.SERIAL;

装有SIM卡的设备获取办法:getSystemService(Context.TELEPHONY_SERVIEC).getSimSerialNumber();

注意对CDMA设备,返回的是一个空值。

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

在少数的一些设备上,会返回垃圾数据。对于没有通话功能的设备,它可能会返回一个固定的值。

六、IDFA

2014年Android2.3基于Google Play推出了IDFA,功能同IOS的IDFA一样,允许用户重置或禁用该ID,由用户决定是否愿意被追踪。由此就出现了各种各种ID的问题。设置界面如下图所示:


但是在中国发行的国行手机由于某些原因,google地图、Play等基础App被阉割掉了,这样导致在中国国行手机中都获取不到该IDFA。(除非用户自行Root并安装google Play)


所以这也是市场中Android体系ID混乱的根本点所在。尤其突出的是google Adx在中国大量的Android流量长期无可用的ID标识的尴尬局面,这个问题google Adx今年应该有所调整。

七、OpenUDID

非Android官方提供的Api,由于Android体系ID较混乱,所以也有很多大厂在使用该ID。原代码地址如下:github.com/vieux/OpenUD

用法如下:

* Addthis to your manifest:

<serviceandroid:name="org.openudid.OpenUDID_service">

<intent-filter>

<actionandroid:name="org.openudid.GETUDID" />

</intent-filter>

</service>

* Call`void OpenUDID_manager.sync(Context yourContext);` to initialize the OpenUDID

* Call`boolean OpenUDID_manager.isInitialized();` to check if the initialization isover (it's asynchronous)

* Call`String OpenUDID_manager.getOpenUDID();` to retrieve your OpenUDID

目前国内市场上Android主要以IMEI作为广告流量标识为主,国外市场主要以IDFA为主,但是随着Android6.0的运行时权限限制,Android体系中的ID将面临洗牌。


(转载请注明出处:微信订阅号:ad_automation)


文字的表现力毕竟有限,若大家还比较迷糊的话,欢迎参加“1.7号的线下大课堂”专门增加了针对移动ID的专题,可面对面为您答疑解惑讲透这些问题。

编辑于 2017-11-08

文章被以下专栏收录

    分享程序化广告实战系列基础知识及经验,让更多入门同学更熟练运用程序化,推动程序化行业更加繁荣。让大家尽量少走弯路、少踩坑