Android设备有唯一的ID吗?如果有,使用Java访问它的简单方法是什么?
当前回答
我几年前就遇到过这个问题,并学会了基于各种答案来实现一个通用的解决方案。
我已经在一个真实世界的产品中使用通用解决方案好几年了。到目前为止,这对我来说很好。以下是基于提供的各种答案的代码片段。
注意,getEmail大多数时候都会返回null,因为我们没有明确请求权限。
private static UniqueId getUniqueId() {
MyApplication app = MyApplication.instance();
// Our prefered method of obtaining unique id in the following order.
// (1) Advertising id
// (2) Email
// (2) ANDROID_ID
// (3) Instance ID - new id value, when reinstall the app.
////////////////////////////////////////////////////////////////////////////////////////////
// ADVERTISING ID
////////////////////////////////////////////////////////////////////////////////////////////
AdvertisingIdClient.Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(app);
} catch (IOException e) {
Log.e(TAG, "", e);
} catch (GooglePlayServicesNotAvailableException e) {
Log.e(TAG, "", e);
} catch (GooglePlayServicesRepairableException e) {
Log.e(TAG, "", e);
}
if (adInfo != null) {
String aid = adInfo.getId();
if (!Utils.isNullOrEmpty(aid)) {
return UniqueId.newInstance(aid, UniqueId.Type.aid);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
// EMAIL
////////////////////////////////////////////////////////////////////////////////////////////
final String email = Utils.getEmail();
if (!Utils.isNullOrEmpty(email)) {
return UniqueId.newInstance(email, UniqueId.Type.eid);
}
////////////////////////////////////////////////////////////////////////////////////////////
// ANDROID ID
////////////////////////////////////////////////////////////////////////////////////////////
final String sid = Settings.Secure.getString(app.getContentResolver(), Settings.Secure.ANDROID_ID);
if (!Utils.isNullOrEmpty(sid)) {
return UniqueId.newInstance(sid, UniqueId.Type.sid);
}
////////////////////////////////////////////////////////////////////////////////////////////
// INSTANCE ID
////////////////////////////////////////////////////////////////////////////////////////////
final String iid = com.google.android.gms.iid.InstanceID.getInstance(MyApplication.instance()).getId();
if (!Utils.isNullOrEmpty(iid)) {
return UniqueId.newInstance(iid, UniqueId.Type.iid);
}
return null;
}
public final class UniqueId implements Parcelable {
public enum Type implements Parcelable {
aid,
sid,
iid,
eid;
////////////////////////////////////////////////////////////////////////////
// Handling Parcelable nicely.
public static final Parcelable.Creator<Type> CREATOR = new Parcelable.Creator<Type>() {
public Type createFromParcel(Parcel in) {
return Type.valueOf(in.readString());
}
public Type[] newArray(int size) {
return new Type[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(this.name());
}
// Handling Parcelable nicely.
////////////////////////////////////////////////////////////////////////////
}
public static boolean isValid(UniqueId uniqueId) {
if (uniqueId == null) {
return false;
}
return uniqueId.isValid();
}
private boolean isValid() {
return !org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) && type != null;
}
private UniqueId(String id, Type type) {
if (org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) || type == null) {
throw new java.lang.IllegalArgumentException();
}
this.id = id;
this.type = type;
}
public static UniqueId newInstance(String id, Type type) {
return new UniqueId(id, type);
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + id.hashCode();
result = 31 * result + type.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof UniqueId)) {
return false;
}
UniqueId uniqueId = (UniqueId)o;
return this.id.equals(uniqueId.id) && this.type == uniqueId.type;
}
@Override
public String toString() {
return type + ":" + id;
}
////////////////////////////////////////////////////////////////////////////
// Handling Parcelable nicely.
public static final Parcelable.Creator<UniqueId> CREATOR = new Parcelable.Creator<UniqueId>() {
public UniqueId createFromParcel(Parcel in) {
return new UniqueId(in);
}
public UniqueId[] newArray(int size) {
return new UniqueId[size];
}
};
private UniqueId(Parcel in) {
this.id = in.readString();
this.type = in.readParcelable(Type.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(this.id);
parcel.writeParcelable(this.type, 0);
}
// Handling Parcelable nicely.
////////////////////////////////////////////////////////////////////////////
public final String id;
public final Type type;
}
public static String getEmail() {
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
AccountManager accountManager = AccountManager.get(MyApplication.instance());
Account[] accounts = accountManager.getAccountsByType("com.google");
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
return possibleEmail;
}
}
accounts = accountManager.getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
return possibleEmail;
}
}
return null;
}
其他回答
这里有相当有用的信息。
它包括五种不同的ID类型:
IMEI(仅适用于使用手机的Android设备;需要Android.permission.READ_Phone_STATE)伪唯一ID(适用于所有Android设备)Android ID(可以为空,可以在工厂重置时更改,可以在根手机上更改)WLAN MAC地址字符串(需要android.permission.ACCESS_WIFI_STATE)BT MAC地址字符串(带蓝牙的设备,需要android.permission.蓝牙)
使用TelephonyManager和Android_ID,通过以下方式获得Android操作系统设备的唯一设备ID(字符串):
String deviceId;
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
}
else {
deviceId = Secure.getString(
getApplicationContext().getContentResolver(),
Secure.ANDROID_ID);
}
但我强烈推荐谷歌建议的方法,参见识别应用程序安装。
使用下面的代码,您可以以字符串形式获取Android OS设备的唯一设备ID。
deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID);
我几年前就遇到过这个问题,并学会了基于各种答案来实现一个通用的解决方案。
我已经在一个真实世界的产品中使用通用解决方案好几年了。到目前为止,这对我来说很好。以下是基于提供的各种答案的代码片段。
注意,getEmail大多数时候都会返回null,因为我们没有明确请求权限。
private static UniqueId getUniqueId() {
MyApplication app = MyApplication.instance();
// Our prefered method of obtaining unique id in the following order.
// (1) Advertising id
// (2) Email
// (2) ANDROID_ID
// (3) Instance ID - new id value, when reinstall the app.
////////////////////////////////////////////////////////////////////////////////////////////
// ADVERTISING ID
////////////////////////////////////////////////////////////////////////////////////////////
AdvertisingIdClient.Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(app);
} catch (IOException e) {
Log.e(TAG, "", e);
} catch (GooglePlayServicesNotAvailableException e) {
Log.e(TAG, "", e);
} catch (GooglePlayServicesRepairableException e) {
Log.e(TAG, "", e);
}
if (adInfo != null) {
String aid = adInfo.getId();
if (!Utils.isNullOrEmpty(aid)) {
return UniqueId.newInstance(aid, UniqueId.Type.aid);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
// EMAIL
////////////////////////////////////////////////////////////////////////////////////////////
final String email = Utils.getEmail();
if (!Utils.isNullOrEmpty(email)) {
return UniqueId.newInstance(email, UniqueId.Type.eid);
}
////////////////////////////////////////////////////////////////////////////////////////////
// ANDROID ID
////////////////////////////////////////////////////////////////////////////////////////////
final String sid = Settings.Secure.getString(app.getContentResolver(), Settings.Secure.ANDROID_ID);
if (!Utils.isNullOrEmpty(sid)) {
return UniqueId.newInstance(sid, UniqueId.Type.sid);
}
////////////////////////////////////////////////////////////////////////////////////////////
// INSTANCE ID
////////////////////////////////////////////////////////////////////////////////////////////
final String iid = com.google.android.gms.iid.InstanceID.getInstance(MyApplication.instance()).getId();
if (!Utils.isNullOrEmpty(iid)) {
return UniqueId.newInstance(iid, UniqueId.Type.iid);
}
return null;
}
public final class UniqueId implements Parcelable {
public enum Type implements Parcelable {
aid,
sid,
iid,
eid;
////////////////////////////////////////////////////////////////////////////
// Handling Parcelable nicely.
public static final Parcelable.Creator<Type> CREATOR = new Parcelable.Creator<Type>() {
public Type createFromParcel(Parcel in) {
return Type.valueOf(in.readString());
}
public Type[] newArray(int size) {
return new Type[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(this.name());
}
// Handling Parcelable nicely.
////////////////////////////////////////////////////////////////////////////
}
public static boolean isValid(UniqueId uniqueId) {
if (uniqueId == null) {
return false;
}
return uniqueId.isValid();
}
private boolean isValid() {
return !org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) && type != null;
}
private UniqueId(String id, Type type) {
if (org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) || type == null) {
throw new java.lang.IllegalArgumentException();
}
this.id = id;
this.type = type;
}
public static UniqueId newInstance(String id, Type type) {
return new UniqueId(id, type);
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + id.hashCode();
result = 31 * result + type.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof UniqueId)) {
return false;
}
UniqueId uniqueId = (UniqueId)o;
return this.id.equals(uniqueId.id) && this.type == uniqueId.type;
}
@Override
public String toString() {
return type + ":" + id;
}
////////////////////////////////////////////////////////////////////////////
// Handling Parcelable nicely.
public static final Parcelable.Creator<UniqueId> CREATOR = new Parcelable.Creator<UniqueId>() {
public UniqueId createFromParcel(Parcel in) {
return new UniqueId(in);
}
public UniqueId[] newArray(int size) {
return new UniqueId[size];
}
};
private UniqueId(Parcel in) {
this.id = in.readString();
this.type = in.readParcelable(Type.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(this.id);
parcel.writeParcelable(this.type, 0);
}
// Handling Parcelable nicely.
////////////////////////////////////////////////////////////////////////////
public final String id;
public final Type type;
}
public static String getEmail() {
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
AccountManager accountManager = AccountManager.get(MyApplication.instance());
Account[] accounts = accountManager.getAccountsByType("com.google");
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
return possibleEmail;
}
}
accounts = accountManager.getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
return possibleEmail;
}
}
return null;
}
Settings.Secure#ANDROID_ID返回每个用户64位十六进制字符串的唯一ANDROID ID。
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
另请阅读唯一标识符的最佳实践:https://developer.android.com/training/articles/user-data-ids
推荐文章
- BottomSheetDialogFragment的圆角
- 在应用程序启动时出现“无法获得BatchedBridge,请确保您的bundle被正确打包”的错误
- 我如何改变默认对话框按钮的文本颜色在安卓5
- 更改单选按钮的圆圈颜色
- 如何在android中复制一个文件?
- adb找不到我的设备/手机(MacOS X)
- 如何在新的材质主题中改变背面箭头的颜色?
- androidviewpager与底部点
- 相同的导航抽屉在不同的活动
- 如何从视图中获得托管活动?
- 单一的TextView与多种颜色的文本
- 如何在非活动类(LocationManager)中使用getSystemService ?
- 在清单中注册应用程序类?
- Android:从数组中编程创建旋转器
- 如何在Java中创建唯一的ID ?