You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

荣耀9n(Android Oreo)GPS关闭时获取Cell ID与LAC的问题

解决荣耀9n(Android Oreo)GPS关闭时获取Cell ID和LAC的问题

我之前碰到过类似的厂商定制系统权限限制问题,给你梳理下原因和可行的解决思路:

问题根源

Android 8.0(Oreo)开始,系统对位置权限与蜂窝数据获取的关联做了更严格的限制,再加上荣耀这类厂商的定制ROM可能额外加了校验逻辑,导致:

  • 主动调用getAllCellInfo()时直接返回空列表
  • getCellLocation()仅在GPS开启(即授予ACCESS_FINE_LOCATION且GPS开关打开)时才返回有效数据

解决思路与代码调整

1. 简化权限检查,优先申请ACCESS_COARSE_LOCATION

获取蜂窝小区信息(Cell ID、LAC)只需要ACCESS_COARSE_LOCATION权限,不需要ACCESS_FINE_LOCATION(GPS权限)。你原来的权限判断要求两个权限都授予,这会导致用户只给了网络定位权限时无法执行后续逻辑,调整如下:

TelephonyManager tel = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);

// 只检查COARSE_LOCATION即可,这是获取蜂窝数据的最低要求
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(
        getActivity(),
        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
        1001 // 自定义请求码
    );
    return;
}

2. 使用PhoneStateListener监听小区位置变化

主动调用getCellLocation()容易被系统限制,而通过监听回调的方式,能在小区信息更新时主动获取数据,即使GPS关闭也能生效:

// 注册PhoneStateListener监听CellLocation变化
PhoneStateListener cellLocationListener = new PhoneStateListener() {
    @Override
    public void onCellLocationChanged(CellLocation location) {
        super.onCellLocationChanged(location);
        if (location == null) {
            Log.e("CellInfo", "获取到的小区位置为空");
            return;
        }

        // 先判断当前手机网络类型,避免强制转换出错
        if (tel.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
            GsmCellLocation gsmLocation = (GsmCellLocation) location;
            int cellId = gsmLocation.getCid();
            int lac = gsmLocation.getLac();
            Log.e("CellInfo", "Cell ID: " + cellId + " | LAC: " + lac);
        }
    }
};

// 启动监听
tel.listen(cellLocationListener, PhoneStateListener.LISTEN_CELL_LOCATION);

3. 确保系统位置开关处于开启状态

即使关闭GPS,也需要打开系统的「位置信息」开关,并选择「仅使用网络定位」模式——这是很多厂商ROM的强制要求,否则蜂窝数据接口会被屏蔽。

4. 关于getAllCellInfo()返回空的补充

如果需要使用getAllCellInfo(),除了上述权限和位置开关的要求,还可以尝试通过监听回调获取(部分厂商在主动调用时会限制,但回调能拿到数据):

PhoneStateListener cellInfoListener = new PhoneStateListener() {
    @Override
    public void onCellInfoChanged(List<CellInfo> cellInfo) {
        super.onCellInfoChanged(cellInfo);
        if (cellInfo != null && !cellInfo.isEmpty()) {
            // 遍历处理CellInfo数据
            for (CellInfo info : cellInfo) {
                if (info instanceof CellInfoGsm) {
                    CellInfoGsm gsmInfo = (CellInfoGsm) info;
                    CellIdentityGsm identity = gsmInfo.getCellIdentity();
                    Log.e("CellInfo", "Cell ID: " + identity.getCid() + " | LAC: " + identity.getLac());
                }
            }
        }
    }
};

tel.listen(cellInfoListener, PhoneStateListener.LISTEN_CELL_INFO);

注意事项

  • 记得在页面销毁时停止监听,避免内存泄漏:tel.listen(cellLocationListener, PhoneStateListener.LISTEN_NONE);
  • 部分地区的运营商网络可能不返回完整的LAC/Cell ID,需要做好空值处理

内容的提问来源于stack exchange,提问作者Jeosh Kurian E J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:07:32