我在Android Q中收到IMEI null吗?

时间:2019-03-15 00:13:51

标签: android imei

我从telephonymanager获取IMEI ID为空。该怎么办?

有什么解决方法吗?

13 个答案:

答案 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序列号。步骤如下:

  • 检查READ_PHONE_STATE权限。
  • 获取活动订阅列表。(返回所有活动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

Also refer Issue

答案 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是个人识别码,不会作为   政策问题。没有解决方法。

https://issuetracker.google.com/issues/129583175#comment10

答案 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