Получить данные о вышках сотовой связи

Вопрос или проблема

Как получить данные о сотовой башне, к которой подключена SIM-карта на Android 10?

Я пробовал несколько вариантов, и ни один из них не сработал. Все права предоставлены (Permission.INTERNET, Permission.ACCESS_NETWORK_STATE, Permission.ACCESS_COARSE_LOCATION, Permission.ACCESS_FINE_LOCATION, Permission.READ_PHONE_STATE). Геолокация включена. Но цикл for cell_info in cell_info_list не выполняется

from kivy.app import App

if (platform == 'android'):
    import android
    from android.permissions import request_permissions, Permission
    from jnius import autoclass, cast

    request_permissions([
        Permission.INTERNET,
        Permission.ACCESS_NETWORK_STATE,
        Permission.ACCESS_COARSE_LOCATION,
        Permission.ACCESS_FINE_LOCATION,
        Permission.READ_PHONE_STATE,
    ])

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))

class MyApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.screen = Builder.load_string(KV)

    def build(self):
        get_cell_location()
        return self.screen

if __name__ == "__main__":
    MyApp().run()

дальнейшие варианты для функции получения

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))
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))
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))
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))

        # Или попробуйте вместо первых строк
        # android_context = android_activity.get_context()
        # cell_info_manager = cast('android.telephony.CellInfoManager', context.getSystemService(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 необходимо вызывать обратный вызов, но из-за нехватки знаний я не знаю, как это реализовать.

UPD:
У меня также отключено обновление данных о башнях в инженерном меню. Включение ничего не изменило. Но из документации нужно как-то реализовать запрос на обновление, а затем обратный вызов

Ответ или решение

Чтобы получить данные о сотовых вышках, к которым подключена SIM-карта на Android 10 и выше, вам нужно выполнить несколько шагов и использовать подходящие методы для получения информации с учетом новых ограничений, связанных с доступом к данным о местоположении. В вашем коде отсутствует правильная реализация обратного вызова для получения данных о вышках.

Вот исправленный пример кода, который должен помочь вам получить данные о сотовых вышках:

from kivy.app import App
from kivy.clock import Clock
from jnius import autoclass, cast
from android.permissions import request_permissions, Permission

class MyApp(App):
    def build(self):
        self.request_permissions()
        Clock.schedule_once(self.get_cell_location, 1)  # Запускаем получение данных через 1 секунду после запуска приложения
        return None  # Здесь можно добавить ваш GUI, если нужно

    def request_permissions(self):
        request_permissions([
            Permission.INTERNET,
            Permission.ACCESS_NETWORK_STATE,
            Permission.ACCESS_FINE_LOCATION,
            Permission.READ_PHONE_STATE,
        ])

    def get_cell_location(self, *args):
        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))

            # Проверка разрешений
            if not self.check_permissions():
                print("Необходимы разрешения.")
                return

            cell_info_list = tel_manager.getAllCellInfo()

            if cell_info_list:
                for cell_info in cell_info_list:
                    self.process_cell_info(cell_info)
            else:
                print("Нет информации о сотовых вышках.")
        except Exception as e:
            print(f"Ошибка: {str(e)}")

    def check_permissions(self):
        # Проверка разрешений (вы можете добавить проверку статуса разрешений)
        return True

    def process_cell_info(self, cell_info):
        TelephonyManager = autoclass('android.telephony.TelephonyManager')

        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:
            return  # Неподдерживаемый тип вышки

        print(f"MCC: {mcc}, MNC: {mnc}, LAC: {lac}, CID: {cid}, Network Type: {network_type}")

if __name__ == "__main__":
    MyApp().run()

Важные моменты:

  1. Проверка разрешений: Убедитесь, что ваше приложение имеет все необходимые разрешения, чтобы получить доступ к информации о сотовых вышках. Вы можете использовать функции для проверки и запроса разрешений.

  2. Используйте Clock.schedule_once: Это гарантирует, что ваш код для получения данных о сотовых вышках будет запущен после того, как ваше приложение инициализируется.

  3. Обработка информации о вышках: Убедитесь, что вы обрабатываете данные, полученные из cell_info, и выводите их для отладки.

  4. Проверка состояния сети: Убедитесь, что ваше устройство подключено к сети и может получать данные о вышках. Если данные отключены из меню инженера, попробуйте включить их.

  5. Обратный вызов: Если вы хотите использовать обратный вызов (например, слушателя для обновления данных), вам нужно будет реализовать соответствующий механизм, чтобы ваше приложение могло получать обновления в фоновом режиме.

Если проблемы сохраняются, убедитесь, что ваш код работает на реальном устройстве с поддержкой необходимых функций, так как эмуляторы могут не предоставлять правильную информацию о сотовых вышках.

Оцените материал
Добавить комментарий

Капча загружается...