1.落笔缘由
最近需要获取能够标志Android设备的唯一标识,但是由于Android系统版本不同或者root等诸多原因,造成有些设备标识为NULL或者标识相同的问题,在网上搜索了相关资料,总结一下各种情况。
2.代码
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
/**
* @author Administrator
* 2017-1-13
* 测试机型:
* S7-601w 4.1.2系统
* IMEI,Serial,Mac,AndroidId都有
* FDR-A01w 5.1.1系统
* IMEI=null
* 其他Serial,Mac,AndroidId都有
* 坚果
* IMEI,Serial,Mac,AndroidId都有
*/
public class Test extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
Log.i("lgy", "IMEI:"+ getLocalIMEI(this));
Log.i("lgy", "Serial:"+getSerial());
Log.i("lgy", "Mac:"+getMac(this));
Log.i("lgy", "AndroidId:"+getAndroidId(this));
}
/**
*TODO 序列号
*从Android 2.3 (“Gingerbread”)开始可用,可以通过android.os.Build.SERIAL获取,对于没有通话功能的设备,它会
*返回一个唯一的device ID
* @return
*/
public String getSerial()
{
try
{
String str = android.os.Build.class.getField("SERIAL").get(null).toString();
return str;
} catch (IllegalAccessException | IllegalArgumentException
| NoSuchFieldException e)
{
e.printStackTrace();
}
return null;
}
/**
*
* 获取设备的IMEI
* IMEI
*方式:TelephonyManager.getDeviceId():
*问题
*范围:网上说“只能支持拥有通话功能的设备,对于平板不可以”,但是我测试了型号FDR-A01w平板确实拿到的是null,
*而 型号S7-601的平板却能拿到。
*持久性:返厂,数据擦除的时候不彻底,保留了原来的标识。
*权限:需要权限:android.permission.READ_PHONE_STATE
*bug: 有些厂家的实现有bug,返回一些不可用的数据
* @return
*/
public String getLocalIMEI(Context context)
{
TelephonyManager tm = null;
try
{
tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (null != tm)
{
return tm.getDeviceId();
}
} catch (Exception ex)
{
} finally
{
tm = null;
}
return null;
}
/**
* Administrator
* 2017-1-13
*TODO
* Mac地址
*ACCESS_WIFI_STATE权限
*有些设备没有WiFi,或者蓝牙,就不可以,如果WiFi没有打开,硬件也不会返回Mac地址
* @return
*/
public String getMac(Context context)
{
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
return info.getMacAddress();
}
// Android Id
/**
* Administrator
* 2017-1-13
*TODO
* ANDROID_ID
*2.2(Froyo,8)版本系统会不可信,来自主要生产厂商的主流手机,至少有一个普遍发现的bug,这些有问题的手机相同的ANDROID_ID: 9774d56d682e549c
*但是如果返厂的手机,或者被root的手机,可能会变
* @param context
* @return
*/
private static String getAndroidId(Context context) {
String androidId = Settings.Secure.getString(
context.getContentResolver(), Settings.Secure.ANDROID_ID);
return androidId;
}
}
- android.os.Build能获取的设备信息
由于在获取序列号的时候使用到了Build,所以总结一下这里能获取的设备信息,网上也有总结过,所以我就不在一一去认真了解了,直接复制一下过来记录一下,不过具体使用的时候还是要去看一下源码,因为有些可能已经Deprecated了。
android.os.Build.BOARD:获取设备基板名称
android.os.Build.BOOTLOADER:获取设备引导程序版本号
android.os.Build.BRAND:获取设备品牌
android.os.Build.CPU_ABI:获取设备指令集名称(CPU的类型)
android.os.Build.CPU_ABI2:获取第二个指令集名称
android.os.Build.DEVICE:获取设备驱动名称
android.os.Build.DISPLAY:获取设备显示的版本包(在系统设置中显示为版本号)和ID一样
android.os.Build.FINGERPRINT:设备的唯一标识。由设备的多个信息拼接合成。
android.os.Build.HARDWARE:设备硬件名称,一般和基板名称一样(BOARD)
android.os.Build.HOST:设备主机地址
android.os.Build.ID:设备版本号。
android.os.Build.MODEL :获取手机的型号 设备名称。
android.os.Build.MANUFACTURER:获取设备制造商
android:os.Build.PRODUCT:整个产品的名称
android:os.Build.RADIO:无线电固件版本号,通常是不可用的 显示unknown
android.os.Build.TAGS:设备标签。如release-keys 或测试的 test-keys
android.os.Build.TIME:时间
android.os.Build.TYPE:设备版本类型 主要为"user" 或"eng".
android.os.Build.USER:设备用户名 基本上都为android-build
android.os.Build.VERSION.RELEASE:获取系统版本字符串。如4.1.2 或2.2 或2.3等
android.os.Build.VERSION.CODENAME:设备当前的系统开发代号,一般使用REL代替
android.os.Build.VERSION.INCREMENTAL:系统源代码控制值,一个数字或者git hash值
android.os.Build.VERSION.SDK:系统的API级别 一般使用下面大的SDK_INT 来查看
android.os.Build.VERSION.SDK_INT:系统的API级别 数字表示
android.os.Build.VERSION_CODES类 中有所有的已公布的Android版本号。全部是Int常亮。可用于与SDK_INT进行比较来判断当前的系统版本
4.总结
以上的内容大多是从网上摘抄过来的,是本着验证内容是否正确并做笔记的目的写这篇文章的,没有用这篇文章盈利应该不算犯法吧!最后会附上摘抄文章的地址。
5.源码地址
http://download.csdn.net/detail/lgywsdy/9736577
6.参考文章
http://blog.csdn.net/ioiol/article/details/45535601
http://m.blog.csdn.net/article/details?id=50767326