我从telephonymanager获取IMEI ID为空。该怎么办?
有什么解决方法吗?
答案 0 :(得分:11)
我迟迟未回答。我仍然相信我的回答会帮助某人。 Android 10限制开发人员访问IMEI号码。
您可以通过获取软件ID获得替代解决方案。您可以将软件ID用作唯一ID。请在我在Application中使用以下代码。
public static String getDeviceId(Context context) {
String deviceId;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
} else {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
}
}
return deviceId;
}
答案 1 :(得分:4)
不确定IMEI号码,但是您可以通过这种方式获取simSerialNumber和其他运营商信息。
getSimSerialNumber()需要Android 10及更高版本的特权,第三方应用无法注册此权限。
请参阅:https://developer.android.com/about/versions/10/privacy/changes#non-resettable-device-ids
一个可能的解决方案是使用Android 5.1中的TELEPHONY_SUBSCRIPTION_SERVICE,以获取sim序列号。步骤如下:
从“订阅对象”中获取SIM卡详细信息。
if ( isPermissionGranted(READ_PHONE_STATE) ) {
String simSerialNo="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
SubscriptionManager subsManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subsList = subsManager.getActiveSubscriptionInfoList();
if (subsList!=null) {
for (SubscriptionInfo subsInfo : subsList) {
if (subsInfo != null) {
simSerialNo = subsInfo.getIccId();
}
}
}
} else {
TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
simSerialNo = tMgr.getSimSerialNumber();
}
}
检查是否有帮助
答案 2 :(得分:3)
Android Q已限制访问IMEI和序列号。它仅适用于具有特殊运营商许可的平台和应用。此外,权限READ_PRIVILEGED_PHONE_STATE不适用于非平台应用程序。
如果您尝试访问它,则会抛出以下异常
java.lang.SecurityException: getImeiForSlot: The user 10180 does not meet the requirements to access device identifiers.
请参考文档: https://developer.android.com/preview/privacy/data-identifiers#device-ids
答案 3 :(得分:3)
根据Google docs。
对不可重置的设备标识符的限制
从Android 10开始,应用必须具有READ_PRIVILEGED_PHONE_STATE特权,才能访问设备的不可重置标识符,包括IMEI和序列号。
警告:无法从Google Play商店安装第三方应用 声明特权。
因此,除了imei之外,您还可以获得Android唯一ID。
String imei = "";
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
try {
imei = telephonyManager.getImei();
} catch (Exception e) {
e.printStackTrace();
imei = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
} else {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
imei = telephonyManager.getDeviceId();
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
}
答案 4 :(得分:2)
如最佳做法所建议。 “您可以避免使用硬件标识符,例如SSAID(Android ID)和IMEI,而不会限制所需的功能。”
而是使用实例ID,例如String uniqueID = UUID.randomUUID().toString();
或FirebaseInstanceId.getInstance().getId();
答案 5 :(得分:2)
获取IMEI号码的最佳方法是:
public static String getIMEIDeviceId(Context context) {
String deviceId;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (context.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return "";
}
}
assert mTelephony != null;
if (mTelephony.getDeviceId() != null)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
deviceId = mTelephony.getImei();
}else {
deviceId = mTelephony.getDeviceId();
}
} else {
deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
Log.d("deviceId", deviceId);
return deviceId;
}
只需复制该方法并使用它。一定会的。但是,您可能知道您无法在androi Q(10)中获得IMEI。在此代码中,您可以通过任何设备或任何api级别获取唯一标识符。 有效100% 谢谢!! 享受快乐:)
答案 6 :(得分:1)
要获取IMEI,还需要执行以下步骤:
1)在清单中定义权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
或API级别> 22
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
2)使用 TelephonyManager
在Java中获取IMEI((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()
同时编译(1)和(2)点:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
imei = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
}
} else {
imei = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
}
答案 7 :(得分:0)
Tldr;在Android Q +上无法访问IMEI
定位到Android Q,第三方应用程序完全无法访问IMEI。声明时,Android Q文档具有误导性
从Android Q开始,应用必须具有READ_PRIVILEGED_PHONE_STATE 特权权限以访问设备的不可重置 标识符,包括IMEI和序列号。 https://developer.android.com/preview/privacy/data-identifiers#device-ids
但是当我实际尝试实现它时,我收到了这个异常:
java.lang.SecurityException: getDeviceId: The user 10132 does not meet the requirements to access device identifiers.
有人在Google的问题跟踪器上报告了此情况,其中Google员工表示这是故意的行为,而Q +上的IMEI仅适用于系统级应用。
状态:无法解决(预期行为),此操作按预期进行。 IMEI是个人识别码,不会作为 政策问题。没有解决方法。
答案 8 :(得分:0)
这在Android Q上将无法使用,任何第三方应用都不能使用IMEI no或电话序列号以及其他不可重置的设备标识符
只有能够使用的权限为READ_PRIVILEGED_PHONE_STATE,而任何第三方应用程序都无法使用
制造和软件应用程序
如果您仍然使用所使用的方法,则会收到错误的Security异常或null
您仍然可以尝试使用
获取唯一的ID。import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),Secure.ANDROID_ID);
但是要获得IMEI号码,您将无法做到这一点,除非您不开发的应用程序不是系统应用程序还是非第三方应用程序
答案 9 :(得分:0)
他们提到: 如果您的应用是设备或个人资料所有者应用,则即使您的应用定位到Android 10或更高版本,您也只需READ_PHONE_STATE权限即可访问不可重置的设备标识符。
我尝试通过EMM作为设备所有者应用程序进行部署,但没有成功。
答案 10 :(得分:0)
您可以更改其他方式,我使用uuid替换设备ID。
String uniquePseudoID = "35" +
Build.BOARD.length() % 10 +
Build.BRAND.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;
String serial = Build.getRadioVersion();
String uuid = new UUID(uniquePseudoID.hashCode(), serial.hashCode()).toString();
AppLog.d("Device ID",uuid);
答案 11 :(得分:0)
如果您的应用针对Android 10或更高版本,则会发生SecurityException。
以下模块受到影响...
Build
getSerial()
TelephonyManager
getImei()
getDeviceId()
getMeid()
getSimSerialNumber()
getSubscriberId()
因此您无法获得android 10的IMEI号,您必须为此使用另一个唯一的标识符,例如Android ID
设备唯一的64位十六进制数字
私有字符串android_id = Secure.getString(getContext()。getContentResolver(), Secure.ANDROID_ID);
答案 12 :(得分:0)
如果需要,您可以尝试将工作资料安装到手机中,并将应用程序包含在同一软件包中,反之亦然。
我尝试过并且可以正常工作,很简单,如果您遵循此仓库:https://github.com/googlesamples/android-testdpc
当您安装工作资料时,您的应用程序即安装在此资料中,您将获得IMEI的访问权限。
现在,昨天有一个固定到Android 10的示例: https://github.com/android/enterprise-samples/pull/29