You get latest content at a time when data will updated
Automaticaly take backup as par schedule
Allow to show public user message
错误提示 `java.lang.SecurityException: getUniqueDeviceId: T...
错误提示 `java.lang.SecurityException: getUniqueDeviceId: The uid 10604 does not meet the requirements to access device identifiers` 说明你的应用尝试获取设备唯一标识符(如 `IMEI`、`Android ID` 等),但是由于权限限制未能成功访问。
在 Android 10(API Level 29)及之后的版本中,访问设备标识符变得更加严格,Google 限制了应用程序对这些信息的访问,以增强用户隐私保护。
– Android 10 及以上版本中,直接获取 `IMEI` 或设备唯一标识符需要特殊权限。
– 你的应用可能没有请求相关权限,或者当前的权限策略不允许应用访问这些标识符。
1. **确保权限声明**:
在 `AndroidManifest.xml` 中确保声明了以下权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
2. **请求运行时权限**:
从 Android 6.0(API Level 23)开始,访问敏感数据需要动态请求权限。在获取设备标识符之前,请求权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE},
REQUEST_CODE_READ_PHONE_STATE);
}
3. **使用 `TelephonyManager.getImei()`** 方式获取IMEI号:
如果你是在 Android 10 以下的设备上,确认使用了 `TelephonyManager.getImei()` 方法获取 IMEI,而不是 `getUniqueDeviceId()` 方法。
4. **考虑替代方案**:
从 Android 10 开始,Google 建议使用 `Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID)` 作为设备唯一标识符。`ANDROID_ID` 不再需要特殊权限。
String androidId = Settings.Secure.getString(
getContentResolver(), Settings.Secure.ANDROID_ID);
– 如果目标设备是 Android 10 及以上版本,即使声明了 `READ_PHONE_STATE` 权限,系统仍会限制访问 IMEI 以及其他设备标识符。
为了让你的代码在 Android 10 及以上版本中能够完美运行,我将做以下修改:
1. 检查设备的 Android 版本,避免在 Android 10 及以上版本中调用 `getDeviceId()`。
2. 使用 `Settings.Secure.ANDROID_ID` 作为设备标识符,避免潜在权限问题。
3. 增加动态权限请求,确保在 Android 6.0 及以上版本中正常获取 `READ_PHONE_STATE` 权限。
修改后的代码如下:
public static String getDeviceId(Context context) {
String deviceId = null;
// 检查是否为 Android 10 及以上版本
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
// 尝试获取设备ID (IMEI),需要在 Android 10 以下版本中执行
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm != null && ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
deviceId = tm.getDeviceId();
if (deviceId != null && !deviceId.isEmpty()) {
return deviceId;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 如果无法获取设备ID,或在 Android 10 及以上版本,则使用Android ID
try {
deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
if (deviceId != null && !deviceId.isEmpty()) {
return deviceId;
}
} catch (Exception e) {
e.printStackTrace();
}
// 如果无法获取Android ID,则生成一个UUID
try {
deviceId = UUID.randomUUID().toString();
} catch (Exception e) {
e.printStackTrace();
}
return deviceId;
}
1. **运行时权限请求**:
在 Android 6.0(API 23)及以上的设备上,你需要在使用 `getDeviceId()` 时动态请求 `READ_PHONE_STATE` 权限。
2. **兼容性考虑**:
Android 10 及以上版本直接使用 `ANDROID_ID`,无需 `READ_PHONE_STATE` 权限。对于 Android 10 以下版本,确保请求权限以获取设备标识符。
这样可以确保代码在所有版本上都能正常运行,并且兼容最新的隐私政策。