Android 10下如何获取SIM卡连接的基站数据?
Android 10 获取SIM卡基站数据的正确实现方案
在Android 10系统中尝试获取SIM卡连接的基站数据,已授予全部必要权限(Permission.INTERNET、Permission.ACCESS_NETWORK_STATE、Permission.ACCESS_COARSE_LOCATION、Permission.ACCESS_FINE_LOCATION、Permission.READ_PHONE_STATE)且开启定位功能,但所有直接调用getAllCellInfo()的实现中,for cell_info in cell_info_list循环都未执行。查阅官方文档得知,Android 10及以上版本必须使用回调机制获取基站数据,手动开启工程菜单的基站数据更新功能也无法解决问题,需要实现完整的更新请求与回调逻辑。
尝试过的无效实现版本
版本1:直接判断CellInfo类型
def get_cell_location(): try: PythonActivity = autoclass('org.kivy.android.PythonActivity') android_context = PythonActivity.mActivity TelephonyManager = autoclass('android.telephony.TelephonyManager') tel_manager = cast('android.telephony.TelephonyManager', android_context.getSystemService(android_context.TELEPHONY_SERVICE)) cell_info_list = tel_manager.getAllCellInfo() for cell_info in cell_info_list: if isinstance(cell_info, autoclass('android.telephony.CellInfoGsm')): cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc() mnc = cell_identity.getMnc() lac = cell_identity.getLac() cid = cell_identity.getCid() network_type = TelephonyManager.NETWORK_TYPE_GSM elif isinstance(cell_info, autoclass('android.telephony.CellInfoCdma')): cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getSystemId() mnc = cell_identity.getNetworkId() lac = cell_identity.getBasestationId() cid = cell_identity.getBasestationId() network_type = TelephonyManager.NETWORK_TYPE_CDMA elif isinstance(cell_info, autoclass('android.telephony.CellInfoLte')): cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMccString() mnc = cell_identity.getMncString() lac = cell_identity.getTac() cid = cell_identity.getCi() network_type = TelephonyManager.NETWORK_TYPE_LTE elif isinstance(cell_info, autoclass('android.telephony.CellInfoWcdma')): cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc() mnc = cell_identity.getMnc() lac = cell_identity.getLac() cid = cell_identity.getCid() network_type = TelephonyManager.NETWORK_TYPE_UMTS elif isinstance(cell_info, autoclass('android.telephony.CellInfoNr')): cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMccString() mnc = cell_identity.getMncString() lac = cell_identity.getTac() cid = cell_identity.getNci() network_type = TelephonyManager.NETWORK_TYPE_NR else: mcc = "" mnc = "" lac = "" cid = "" network_type = "" continue print(f"{mcc}\n{mnc}\n{lac}\n{cid}\n{str(network_type)}") except Exception as e: print(str(e))
版本2:通过CellType枚举判断
def get_cell_location(): try: PythonActivity = autoclass('org.kivy.android.PythonActivity') android_context = PythonActivity.mActivity TelephonyManager = autoclass('android.telephony.TelephonyManager') tel_manager = cast('android.telephony.TelephonyManager', android_context.getSystemService(android_context.TELEPHONY_SERVICE)) cell_info_list = tel_manager.getAllCellInfo() for cell_info in cell_info_list: cell_type = cell_info.get_cell_type() if cell_type == autoclass('android.telephony.CellInfo$CellType').GSM: cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc(), mnc = cell_identity.getMnc() lac = cell_identity.getLac() cid = cell_identity.getCid() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_GSM elif cell_type == autoclass('android.telephony.CellInfo$CellType').CDMA: cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getSystemId() mnc = cell_identity.getNetworkId() lac = cell_identity.getBasestationId() cid = cell_identity.getBasestationId() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_CDMA elif cell_type == autoclass('android.telephony.CellInfo$CellType').LTE: cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMccString() mnc = cell_identity.getMncString() lac = cell_identity.getTac() cid = cell_identity.getCi() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_LTE elif cell_type == autoclass('android.telephony.CellInfo$CellType').WCDMA: cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc() mnc = cell_identity.getMnc() lac = cell_identity.getLac() cid = cell_identity.getCid() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_UMTS elif cell_type == autoclass('android.telephony.CellInfo$CellType').NR: cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMccString() mnc = cell_identity.getMncString() lac = cell_identity.getTac() cid = cell_identity.getNci() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_NR else: mcc = "" mnc = "" lac = "" cid = "" network_type = "" continue print(f"{mcc}\n{mnc}\n{lac}\n{cid}\n{str(network_type)}") except Exception as e: print(str(e))
版本3:通过类名判断
def get_cell_location(): try: PythonActivity = autoclass('org.kivy.android.PythonActivity') android_context = PythonActivity.mActivity TelephonyManager = autoclass('android.telephony.TelephonyManager') tel_manager = cast('android.telephony.TelephonyManager', android_context.getSystemService(android_context.TELEPHONY_SERVICE)) cell_info_list = tel_manager.getAllCellInfo() for cell_info in cell_info_list: cell_type = cell_info.getClass().getSimpleName() if cell_type == "CellInfoGsm": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc() mnc = cell_identity.getMnc() lac = cell_identity.getLac() cid = cell_identity.getCid() network_type = TelephonyManager.NETWORK_TYPE_GSM elif cell_type == "CellInfoCdma": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getSystemId() mnc = cell_identity.getNetworkId() lac = cell_identity.getBasestationId() cid = cell_identity.getBasestationId() network_type = TelephonyManager.NETWORK_TYPE_CDMA elif cell_type == "CellInfoLte": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMccString() mnc = cell_identity.getMncString() lac = cell_identity.getTac() cid = cell_identity.getCi() network_type = TelephonyManager.NETWORK_TYPE_LTE elif cell_type == "CellInfoWcdma": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc() mnc = cell_identity.getMnc() lac = cell_identity.getLac() cid = cell_identity.getCid() network_type = TelephonyManager.NETWORK_TYPE_UMTS elif cell_type == "CellInfoNr": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMccString() mnc = cell_identity.getMncString() lac = cell_identity.getTac() cid = cell_identity.getNci() network_type = TelephonyManager.NETWORK_TYPE_NR else: mcc = "" mnc = "" lac = "" cid = "" network_type = "" continue print(f"{mcc}\n{mnc}\n{lac}\n{cid}\n{str(network_type)}") except Exception as e: print(str(e))
版本4:使用CellLocation接口
def get_cell_location(): try: service_state = tel_manager.getServiceState() cell_location = tel_manager.getCellLocation() if isinstance(cell_location, autoclass('android.telephony.gsm.GsmCellLocation')): gsm_cell_location = cell_location mcc = gsm_cell_location.getMobileCountryCode() mnc = gsm_cell_location.getMobileNetworkCode() lac = gsm_cell_location.getLac() cid = gsm_cell_location.getCid() network_type = TelephonyManager.NETWORK_TYPE_GSM elif isinstance(cell_location, autoclass('android.telephony.cdma.CdmaCellLocation')): cdma_cell_location = cell_location mcc = service_state.getSystemId() mnc = service_state.getNetworkId() lac = cdma_cell_location.getBaseStationId() cid = cdma_cell_location.getBaseStationId() network_type = TelephonyManager.NETWORK_TYPE_CDMA elif isinstance(cell_location, autoclass('android.telephony.CellIdentityLte')): lte_cell_identity = cell_location mcc = lte_cell_identity.getMccString() mnc = lte_cell_identity.getMncString() lac = lte_cell_identity.getTac() cid = lte_cell_identity.getCi() network_type = TelephonyManager.NETWORK_TYPE_LTE elif isinstance(cell_location, autoclass('android.telephony.CellIdentityWcdma')): wcdma_cell_identity = cell_location mcc = wcdma_cell_identity.getMcc() mnc = wcdma_cell_identity.getMnc() lac = wcdma_cell_identity.getLac() cid = wcdma_cell_identity.getCid() network_type = TelephonyManager.NETWORK_TYPE_UMTS elif isinstance(cell_location, autoclass('android.telephony.CellIdentityLte')): nr_cell_identity = cell_location mcc = nr_cell_identity.getMccString() mnc = nr_cell_identity.getMncString() lac = nr_cell_identity.getTac() cid = nr_cell_identity.getNCi() network_type = TelephonyManager.NETWORK_TYPE_NR else: mcc = "" mnc = "" lac = "" cid = "" network_type = "" continue print(f"{mcc}\n{mnc}\n{lac}\n{cid}\n{str(network_type)}") except Exception as e: print(str(e))
版本5:使用CellInfoManager
def get_cell_location(): try: PythonActivity = autoclass('org.kivy.android.PythonActivity') android_context = PythonActivity.mActivity cell_info_manager = cast('android.telephony.CellInfoManager', android_context.getSystemService(android_context.CELL_INFO_SERVICE)) cell_info_list = cell_info_manager.getCellInfo() print(len(cell_info_list)) for cell_info in cell_info_list: cell_type = type(cell_info) if cell_type == autoclass('android.telephony.CellInfoGsm'): gsm_cell_info = cell_info.getCellIdentity() mcc = gsm_cell_info.getMcc() mnc = gsm_cell_info.getMnc() lac = gsm_cell_info.getLac() cid = gsm_cell_info.getCid() network_type = 'GSM' elif cell_type == autoclass('android.telephony.CellInfoCdma'): cdma_cell_info = cell_info.getCellIdentity() mcc = cdma_cell_info.getSystemId() mnc = cdma_cell_info.getNetworkId() lac = cdma_cell_info.getBasestationId() cid = cdma_cell_info.getBasestationId() network_type = 'CDMA' elif cell_type == autoclass('android.telephony.CellInfoLte'): lte_cell_info = cell_info.getCellIdentity() mcc = lte_cell_info.getMccString() mnc = lte_cell_info.getMncString() lac = lte_cell_info.getTac() cid = lte_cell_info.getCi() network_type = 'LTE' elif cell_type == autoclass('android.telephony.CellInfoWcdma'): wcdma_cell_info = cell_info.getCellIdentity() mcc = wcdma_cell_info.getMcc() mnc = wcdma_cell_info.getMnc() lac = wcdma_cell_info.getLac() cid = wcdma_cell_info.getCid() network_type = 'WCDMA' elif cell_type == autoclass('android.telephony.CellInfoNr'): nr_cell_info = cell_info.getCellIdentity() mcc = nr_cell_info.getMccString() mnc = nr_cell_info.getMncString() lac = nr_cell_info.getTac() cid = nr_cell_info.getNci() network_type = 'NR' else: mcc = "" mnc = "" lac = "" cid = "" network_type = "" continue print(f"{mcc}\n{mnc}\n{lac}\n{cid}\n{str(network_type)}") except Exception as e: print(str(e))
正确实现:Android 10+ 回调机制
Android 10(API 29)及以上版本,getAllCellInfo()可能返回空列表,必须通过requestCellInfoUpdate()方法结合回调获取实时基站数据。以下是基于Kivy+Jnius的完整实现:
步骤1:创建回调类
通过Jnius定义CellInfoCallback类,实现TelephonyManager.CellInfoCallback接口:
from jnius import PythonJavaClass, java_method, autoclass, cast class CellInfoCallback(PythonJavaClass): __javainterfaces__ = ['android/telephony/TelephonyManager$CellInfoCallback'] @java_method('(Ljava/util/List;I)V') def onCellInfoChanged(self, cell_info_list, status): # 处理回调返回的基站数据 if status == autoclass('android.telephony.TelephonyManager').CELL_INFO_STATUS_SUCCESS: for cell_info in cell_info_list: cell_type = cell_info.getClass().getSimpleName() mcc = "" mnc = "" lac = "" cid = "" network_type = "" if cell_type == "CellInfoGsm": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc() mnc = cell_identity.getMnc() lac = cell_identity.getLac() cid = cell_identity.getCid() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_GSM elif cell_type == "CellInfoCdma": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getSystemId() mnc = cell_identity.getNetworkId() lac = cell_identity.getBasestationId() cid = cell_identity.getBasestationId() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_CDMA elif cell_type == "CellInfoLte": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMccString() mnc = cell_identity.getMncString() lac = cell_identity.getTac() cid = cell_identity.getCi() network_type = autoclass('android.telephony.TelephonyManager').NETWORK_TYPE_LTE elif cell_type == "CellInfoWcdma": cell_identity = cell_info.getCellIdentity() mcc = cell_identity.getMcc() mnc = cell_identity.getMnc() lac = cell_identity.getL
相关产品推荐
相关产品推荐

