获取android设备唯一编号_详解Android获取设备唯一ID的几种方式

2023-05-16

先来看看几种比较单一的方式:

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的官方博客中也提到了,不过以上几种方案,应该可以满足平时的需求,大家可以选择其中自己认为比较好的,用于自己的项目中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取android设备唯一编号_详解Android获取设备唯一ID的几种方式 的相关文章

随机推荐