0

我正在寻找使用 TelephonyManager.getAllCellInfo() 的邻居小区 rssi 信号,它返回包含我需要的所有信息的 CellInfo(为不同的小区塔类型、gsm、lte、cdma ecc 扩展的抽象类)对象的列表。

我的应用程序是使用 android API 级别 17 构建的,并且运行良好。

当我在刚刚升级到 Android 4.3(API 级别 18)的新手机上运行应用程序时,调用 getAllCellInfo() 返回 CellInfoWcdma 列表(API 级别 18 中添加的新类)。

由于多种原因,我无法升级我的 sdk。

如何在不升级我的 sdk 的情况下从此类对象中获取单元格 id 和 rssi?

谢谢!

4

1 回答 1

0

使用反射:

private static class CellIdentityWcdma {
    private static Class<?> mCls;
    private static Method mGetCid;
    private static Method mGetLac;
    private static Method mGetMcc;
    private static Method mGetMnc;
    private static Method mGetPsc;
    static {
        try {
            mCls = Class.forName("android.telephony.CellIdentityWcdma");
            mGetCid = mCls.getMethod("getCid");
            mGetLac = mCls.getMethod("getLac");
            mGetMcc = mCls.getMethod("getMcc");
            mGetMnc = mCls.getMethod("getMnc");
            mGetPsc = mCls.getMethod("getPsc");
        } catch (final ClassNotFoundException e) {
        } catch (final NoSuchMethodException e) {
        }
    }
    private final Object mObj;
    public CellIdentityWcdma(final Object obj) {
        mObj = obj;
    }
    public int getCid() throws IllegalAccessException, InvocationTargetException {
        return ((Integer)mGetCid.invoke(mObj)).intValue();
    }
    public int getLac() throws IllegalAccessException, InvocationTargetException {
        return ((Integer)mGetLac.invoke(mObj)).intValue();
    }
    public int getMcc() throws IllegalAccessException, InvocationTargetException {
        return ((Integer)mGetMcc.invoke(mObj)).intValue();
    }
    public int getMnc() throws IllegalAccessException, InvocationTargetException {
        return ((Integer)mGetMnc.invoke(mObj)).intValue();
    }
    public int getPsc() throws IllegalAccessException, InvocationTargetException {
        return ((Integer)mGetPsc.invoke(mObj)).intValue();
    }
}

private static class CellSignalStrengthWcdma {
    private static Class<?> mCls;
    private static Method mGetAsuLevel;
    static {
        try {
            mCls = Class.forName("android.telephony.CellSignalStrengthWcdma");
            mGetAsuLevel = mCls.getMethod("getAsuLevel");
        } catch (final ClassNotFoundException e) {
        } catch (final NoSuchMethodException e) {
        }
    }
    private final Object mObj;
    public CellSignalStrengthWcdma(final Object obj) {
        mObj = obj;
    }
    public int getAsuLevel() throws IllegalAccessException, InvocationTargetException {
        return ((Integer)mGetAsuLevel.invoke(mObj)).intValue();
    }
}

private static class CellInfoWcdma {
    private static Class<?> mCls;
    private static Method mGetCellIdentity;
    private static Method mGetCellSignalStrength;
    static {
        try {
            mCls = Class.forName("android.telephony.CellInfoWcdma");
            mGetCellIdentity = mCls.getMethod("getCellIdentity");
            mGetCellSignalStrength = mCls.getMethod("getCellSignalStrength");
        } catch (final ClassNotFoundException e) {
        } catch (final NoSuchMethodException e) {
        }
    }
    private final Object mObj;
    public CellInfoWcdma(final Object obj) {
        mObj = obj;
    }
    public static boolean isInstance(final Object obj) {
        return null != mCls && mCls.isInstance(obj);
    }
    public CellIdentityWcdma getCellIdentity()
            throws IllegalAccessException, InvocationTargetException {
        return new CellIdentityWcdma(mGetCellIdentity.invoke(mObj));
    }
    public CellSignalStrengthWcdma getCellSignalStrength()
            throws IllegalAccessException, InvocationTargetException {
        return new CellSignalStrengthWcdma(mGetCellSignalStrength.invoke(mObj));
    }
}

private static void useCellInfo(final CellInfo cellInfo) {
    if (cellInfo instanceof CellInfoGsm) {
        useGsm((CellInfoGsm)cellInfo);
    } else if (cellInfo instanceof CellInfoLte) {
        useLte((CellInfoLte)cellInfo);
    } else if (cellInfo instanceof CellInfoCdma) {
        useCdma((CellInfoCdma)cellInfo);
    } else if (CellInfoWcdma.isInstance(cellInfo)) {
        useWcdma(new CellInfoWcdma(cellInfo));
    }
}
于 2014-01-13T18:26:55.687 回答