Android设备有唯一的ID吗?如果有,使用Java访问它的简单方法是什么?
当前回答
使用下面的代码,您可以以字符串形式获取Android OS设备的唯一设备ID。
deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID);
其他回答
以下代码使用隐藏的Android API返回设备序列号。但是,这个代码在三星Galaxy Tab上不起作用,因为这个设备上没有设置“ro.seriano”。
String serial = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {
}
我的两美分-注意,这是一个设备(错误)唯一ID,而不是Android开发者博客中讨论的安装ID。
值得注意的是,@emmby提供的解决方案在每个应用程序ID中都有所不同,因为SharedPreferences没有跨进程同步(请参阅此处和此处)。所以我完全避免了这一点。
相反,我封装了在枚举中获取(设备)ID的各种策略-更改枚举常量的顺序会影响获取ID的各种方式的优先级。返回第一个非空ID或抛出异常(根据不赋予空含义的良好Java实践)。例如,我先有一个TELEPHONY,但一个好的默认选择是ANDROID_ID贝塔:
import android.Manifest.permission;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.WifiManager;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.util.Log;
// TODO : hash
public final class DeviceIdentifier {
private DeviceIdentifier() {}
/** @see http://code.google.com/p/android/issues/detail?id=10603 */
private static final String ANDROID_ID_BUG_MSG = "The device suffers from "
+ "the Android ID bug - its ID is the emulator ID : "
+ IDs.BUGGY_ANDROID_ID;
private static volatile String uuid; // volatile needed - see EJ item 71
// need lazy initialization to get a context
/**
* Returns a unique identifier for this device. The first (in the order the
* enums constants as defined in the IDs enum) non null identifier is
* returned or a DeviceIDException is thrown. A DeviceIDException is also
* thrown if ignoreBuggyAndroidID is false and the device has the Android ID
* bug
*
* @param ctx
* an Android constant (to retrieve system services)
* @param ignoreBuggyAndroidID
* if false, on a device with the android ID bug, the buggy
* android ID is not returned instead a DeviceIDException is
* thrown
* @return a *device* ID - null is never returned, instead a
* DeviceIDException is thrown
* @throws DeviceIDException
* if none of the enum methods manages to return a device ID
*/
public static String getDeviceIdentifier(Context ctx,
boolean ignoreBuggyAndroidID) throws DeviceIDException {
String result = uuid;
if (result == null) {
synchronized (DeviceIdentifier.class) {
result = uuid;
if (result == null) {
for (IDs id : IDs.values()) {
try {
result = uuid = id.getId(ctx);
} catch (DeviceIDNotUniqueException e) {
if (!ignoreBuggyAndroidID)
throw new DeviceIDException(e);
}
if (result != null) return result;
}
throw new DeviceIDException();
}
}
}
return result;
}
private static enum IDs {
TELEPHONY_ID {
@Override
String getId(Context ctx) {
// TODO : add a SIM based mechanism ? tm.getSimSerialNumber();
final TelephonyManager tm = (TelephonyManager) ctx
.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null) {
w("Telephony Manager not available");
return null;
}
assertPermission(ctx, permission.READ_PHONE_STATE);
return tm.getDeviceId();
}
},
ANDROID_ID {
@Override
String getId(Context ctx) throws DeviceIDException {
// no permission needed !
final String andoidId = Secure.getString(
ctx.getContentResolver(),
android.provider.Settings.Secure.ANDROID_ID);
if (BUGGY_ANDROID_ID.equals(andoidId)) {
e(ANDROID_ID_BUG_MSG);
throw new DeviceIDNotUniqueException();
}
return andoidId;
}
},
WIFI_MAC {
@Override
String getId(Context ctx) {
WifiManager wm = (WifiManager) ctx
.getSystemService(Context.WIFI_SERVICE);
if (wm == null) {
w("Wifi Manager not available");
return null;
}
assertPermission(ctx, permission.ACCESS_WIFI_STATE); // I guess
// getMacAddress() has no java doc !!!
return wm.getConnectionInfo().getMacAddress();
}
},
BLUETOOTH_MAC {
@Override
String getId(Context ctx) {
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba == null) {
w("Bluetooth Adapter not available");
return null;
}
assertPermission(ctx, permission.BLUETOOTH);
return ba.getAddress();
}
}
// TODO PSEUDO_ID
// http://www.pocketmagic.net/2011/02/android-unique-device-id/
;
static final String BUGGY_ANDROID_ID = "9774d56d682e549c";
private final static String TAG = IDs.class.getSimpleName();
abstract String getId(Context ctx) throws DeviceIDException;
private static void w(String msg) {
Log.w(TAG, msg);
}
private static void e(String msg) {
Log.e(TAG, msg);
}
}
private static void assertPermission(Context ctx, String perm) {
final int checkPermission = ctx.getPackageManager().checkPermission(
perm, ctx.getPackageName());
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Permission " + perm + " is required");
}
}
// =========================================================================
// Exceptions
// =========================================================================
public static class DeviceIDException extends Exception {
private static final long serialVersionUID = -8083699995384519417L;
private static final String NO_ANDROID_ID = "Could not retrieve a "
+ "device ID";
public DeviceIDException(Throwable throwable) {
super(NO_ANDROID_ID, throwable);
}
public DeviceIDException(String detailMessage) {
super(detailMessage);
}
public DeviceIDException() {
super(NO_ANDROID_ID);
}
}
public static final class DeviceIDNotUniqueException extends
DeviceIDException {
private static final long serialVersionUID = -8940090896069484955L;
public DeviceIDNotUniqueException() {
super(ANDROID_ID_BUG_MSG);
}
}
}
这个示例演示了如何在Android中获取和存储设备ID,但我使用的是Kotlin。
val textView: TextView = findViewById(R.id.textView)
val uniqueId: String = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
textView.text = "Device ID: $uniqueId"
android.telephony.TelephonyManager.getDeviceId()
这将返回唯一标识设备的任何字符串(GSM上的IMEI,CDMA上的MEID)。
在AndroidManifest.xml中需要以下权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
经过多次搜索。我意识到没有确定的方法可以拥有唯一的ID。
假设我们希望每个用户只能在一部手机上使用该应用程序。
我所做的是:
当用户在我的应用程序中注册时,我将当前时间保存为服务器和应用程序数据库中的唯一ID。
当用户尝试登录另一个电话时,我从服务器获取用户信息,并意识到该用户已经登录,因为唯一ID字段已满,所以向他/她显示一个对话框,表明他/她已经登录到另一个设备,无论他/她是否想离开上一个会话,如果他说是,我将为他创建一个新的唯一ID,并更新服务器上的唯一ID详细信息。
在我自己的应用程序中,每次运行时,我都会从服务器获取用户配置文件。如果存储在服务器上的唯一ID与存储在应用程序数据库中的唯一ID不同,我将自动注销用户。
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件