如何确定Android设备是否具有蜂窝无线电模块?

4
如何确定设备确实具有gsm、cdma或其他蜂窝网络设备(而不仅仅是WiFi)?我不想检查当前连接的网络状态,因为设备可能处于离线状态。我也不想通过((TelephonyManager) act.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()来检查设备ID,因为某些设备只会给你多态或虚拟的设备ID。
实际上,我需要精确检查蜂窝设备,以跳过TelephonyManager.getDeviceId,并在那些没有蜂窝电台的设备上执行Settings.Secure.ANDROID_ID检查。我至少有一台平板电脑(Storage Options Scroll Excel 7"),每次询问它时都会返回不同的IMEI,尽管它应该返回null,因为它没有蜂窝电台(这里也是相同的情况:Android: getDeviceId() returns an IMEI, adb shell dumpsys iphonesubinfo returns Device ID=NULL)。但我需要可靠的设备ID,每次询问时都是相同的。
期待听到您的想法!

请重新阅读问题。我需要过滤掉看起来像真实值但实际上是虚假的虚拟值。 - Tertium
2个回答

1
如果您要在商店发布应用程序,并且希望将应用程序仅限于实际手机上可见,您可以在清单中添加一个<uses-feature>,请求android.hardware.telephony。请查看文档以确定是否适用于您。

4
如果你只是想在运行时找到这个信息,而不是进行过滤,PackageManagerhasSystemFeature("android.hardware.telephony") 将告诉你是否以某种方式可用电话功能。 - CommonsWare
@jlindenbaum 我想支持所有设备。commonsware,谢谢,我会去看看的。 - Tertium

1

如果有人需要完整的解决方案,可以使用反射,因为某些东西在某些固件版本上可能不存在。 MainContext - 主活动上下文。

    static public int getSDKVersion()
{
    Class<?> build_versionClass = null;

    try
    {
        build_versionClass = android.os.Build.VERSION.class;
    }
    catch (Exception e)
    {
    }

    int retval = -1;
    try
    {
        retval = (Integer) build_versionClass.getField("SDK_INT").get(build_versionClass);
    }
    catch (Exception e)
    {
    }

    if (retval == -1)
        retval = 3; //default 1.5

    return retval;
}

static public boolean hasTelephony()
{
    TelephonyManager tm = (TelephonyManager) Hub.MainContext.getSystemService(Context.TELEPHONY_SERVICE);
    if (tm == null)
        return false;

    //devices below are phones only
    if (Utils.getSDKVersion() < 5)
        return true;

    PackageManager pm = MainContext.getPackageManager();

    if (pm == null)
        return false;

    boolean retval = false;
    try
    {
        Class<?> [] parameters = new Class[1];
        parameters[0] = String.class;
        Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
        Object [] parm = new Object[1];
        parm[0] = "android.hardware.telephony";
        Object retValue = method.invoke(pm, parm);
        if (retValue instanceof Boolean)
            retval = ((Boolean) retValue).booleanValue();
        else
            retval = false;
    }
    catch (Exception e)
    {
        retval = false;
    }

    return retval;
}

注意:这似乎只适用于能够进行实际电话通话的设备,但大多数3G/4G平板电脑仅具有3G/4G功能,无法进行电话通话。 - David Liu
这就是我需要知道的。因为没有无线电的设备通常有假 IMEI,有时每次查询时都会给出不同的 IMEI。 - Tertium
你好,我已经被这个问题困扰了4-5天,仍然感到困惑。我问了这个,答案与你的完全相同。我仍然不确定try块内的代码是做什么的。你介意解释一下吗?谢谢! - Ruchir Baronia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接