{"id":25422970,"url":"https://github.com/mroczis/netmonster-core","last_synced_at":"2026-01-11T17:05:38.108Z","repository":{"id":37737460,"uuid":"199189308","full_name":"mroczis/netmonster-core","owner":"mroczis","description":"Android Telephony SDK bridge with some additional features","archived":false,"fork":false,"pushed_at":"2025-07-13T19:21:28.000Z","size":608,"stargazers_count":379,"open_issues_count":21,"forks_count":77,"subscribers_count":52,"default_branch":"master","last_synced_at":"2025-07-13T21:24:11.540Z","etag":null,"topics":["4g","5g","android","lte","netmonster","nr","telephonymanager"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mroczis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-07-27T16:32:13.000Z","updated_at":"2025-07-13T19:21:31.000Z","dependencies_parsed_at":"2023-02-16T02:15:53.138Z","dependency_job_id":"86f88d52-bfa9-4060-985a-95b1fe705d5c","html_url":"https://github.com/mroczis/netmonster-core","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/mroczis/netmonster-core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mroczis%2Fnetmonster-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mroczis%2Fnetmonster-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mroczis%2Fnetmonster-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mroczis%2Fnetmonster-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mroczis","download_url":"https://codeload.github.com/mroczis/netmonster-core/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mroczis%2Fnetmonster-core/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28314264,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["4g","5g","android","lte","netmonster","nr","telephonymanager"],"created_at":"2025-02-16T22:00:58.737Z","updated_at":"2026-01-11T17:05:38.091Z","avatar_url":"https://github.com/mroczis.png","language":"Kotlin","funding_links":[],"categories":["Closed Source"],"sub_categories":["Android"],"readme":"# NetMonster Core\n\nLightweight Android library that is build over [Telephony SDK](https://developer.android.com/reference/android/telephony/package-summary). NetMonster core is extracted from [NetMonster](https://play.google.com/store/apps/details?id=cz.mroczis.netmonster) application and backports several Telephony features to older Android devices.  \n  \nWhy use NetMonster Core instead of legacy API?  \n - Validation - library validates data from RIL and corrects them if possible \n - Richer information - additional functions for cell identity and cell signal that will make your code more understandable  \n - Backport - several non-accessible signal or identity fields are now accessible without boilerplate code  \n - Tested - tested on real devices, 50 000+ active users\n\n![Latest version](https://img.shields.io/maven-central/v/app.netmonster/core \"Latest lib version\")\n```groovy\nimplementation 'app.netmonster:core:$version'\n```\n\n### New functions\nHere's small comparison for each of voice / data network you can meet.\n\n#### GSM\n|function    |Min SDK Android|Min SDK NetMonster Core |\n|------------|---------------|------------------------|\n|CGI         |-              |I (14)                  |\n|NCC         |-              |N (24)                  |\n|BCC         |-              |N (24)                  |\n|Band        |-              |N (24)                  |\n|TA          |O (26)         |N (24)                  |\n\n#### WCDMA  \n|function    |Min SDK Android|Min SDK NetMonster Core |  \n|------------|---------------|------------------------|\n|CGI         |-              |I (14)                  |\n|CID (16b)   |-              |I (14)                  |  \n|RNC         |-              |I (14)                  |\n|Ec/Io       |-              |M (23)                  |  \n|Band        |-              |N (24)                  |  \n|BER         |-              |Q (29)                  |  \n|Ec/No       |-              |Q (29)                  |  \n|RSCP        |-              |Q (29)                  |\n\n#### LTE\n|function    |Min SDK Android|Min SDK NetMonster Core |\n|------------|---------------|------------------------|\n|eCGI        |-              |I (14)                  |\n|CID (8b)    |-              |I (14)                  |\n|eNb         |-              |I (14)                  | \n|RSSI        |Q (29)         |I (14)                  |\n|RSRP        |O (26)         |I (14)                  |\n|CQI         |O (26)         |I (14)                  |\n|SNR         |O (26)         |I (14)                  |\n|TA          |O (26)         |I (14)                  |\n|Band        |-              |N (24)                  |  \n\n\n### Usage\n\nThere are basically two ways you can use this library - as a validation library that will sanitize\ndata from AOSP cause lots of manufacturers modify source code and do not follow public documentation.\nIn that case you'll only need `ITelephonyManagerCompat` to retrieve AOSP-like models that are properly\nvalidated.\n\nThe second option is to use advantages of additional postprocessing of NetMonster Core. As a result\nyou'll get more data but correctness is not 100 % guaranteed. \n\n#### Without additional postprocessing\n\nNetMonster Core focuses on mapping of two AOSP's ways to fetch current cell information:\n - [TelephonyManager.getAllCellInfo()](https://developer.android.com/reference/android/telephony/TelephonyManager#getAllCellInfo())\n - [TelephonyManager.getCellLocation()](https://developer.android.com/reference/android/telephony/TelephonyManager.html#getCellLocation()) (deprecated in AOSP)\n - TelephonyManager.getNeighbouringCellInfo() (removed from AOSP)\n\nNote that some of those methods are deprecated or even removed from AOSP - for more info see documentation of each method.\n\n```kotlin\nNetMonsterFactory.getTelephony(context, SUBSCRIPTION_ID).apply {\n    val allCellInfo : List\u003cICell\u003e = getAllCellInfo() \n    val cellLocation : List\u003cICell\u003e = getCellLocation()\n    val neighbouringCells : List\u003cICell\u003e = getNeighbouringCellInfo()\n}\n```\n\n#### Postprocessing\n\nIn this case you'll need to interact with `INetMonster` class. Here's list of problems \nthat this library solves.\n\n##### Merging data from multiple sources\nIssue:\n - Android offers multiple ways how to get cell information.\n - Not all devices support one unified way how to access all the data.\n\nSolution:\n - NetMonster Core grabs data from sources you specify, validates and merges them.\n\n```kotlin\nNetMonsterFactory.get(context).apply {\n    val allSources : List\u003cICell\u003e = getCells() // all sources\n    val subset : List\u003cICell\u003e = getCells( // subset of available sources\n        CellSource.ALL_CELL_INFO, \n        CellSource.CELL_LOCATION\n    ) \n}\n```\n\n##### Detection of LTE-A \u0026 HSPA+42\nIssue:\n - AOSP cannot detect HSPA+42, only HSPA+.\n - AOSP does not offer a way to distinguish whether current network is using carrier aggregation or not.\n\nSolution:\n - NetMonster Core attempts to guess HSPA+ 42 availability.\n - LTE-CA presence can be guessed based on cell info or detected using hidden APIs.\n\nUsing `getNetworkType(vararg detectors: INetworkDetector)` you can specify which `INetworkDetector` to use\nwhen detecting current network type.\n\n```kotlin\nNetMonsterFactory.get(context).apply {\n    // All detectors that are bundled in NetMonster Core\n    val networkType : NetworkType = getNetworkType(SUBSCRIPTION_ID)\n    \n    // Only HSPA+42 (guess, not from RIL)\n    val isHspaDc: NetworkType? = getNetworkType(SUBSCRIPTION_ID, DetectorHspaDc())\n    // LTE-A from CellInfo (guess, not from RIL), NSA NR\n    val isLteCaCellInfo: NetworkType? = getNetworkType(SUBSCRIPTION_ID, DetectorCellInfo())\n    // LTE-A from ServiceState (from RIL, Android P+)\n    val isLteCaServiceState: NetworkType? = getNetworkType(SUBSCRIPTION_ID, DetectorLteAdvancedNrServiceState())\n    // LTE-A from PhysicalChannel (from RIL, Android P+)\n    val isLteCaPhysicalChannel: NetworkType? = getNetworkType(SUBSCRIPTION_ID, DetectorLteAdvancedPhysicalChannel())\n    // LTE-A and NR from DisplayInfo (marketing purposes, might result false-positive data, Android R+)\n    // You can also detect only LTE-A or NR using one of classes:\n    // - DetectorLteAdvancedServiceState ... for LTE-A\n    // - DetectorNsaNr ... for NR NSA\n    val isLteCaOrNsaNrDisplayInfo: NetworkType? = getNetworkType(SUBSCRIPTION_ID, DetectorLteAdvancedNrDisplayInfo())\n}\n```\n\n##### Detection of NR NSA\nIssue:\n - AOSP does not provide any information about NR NSA connection status.\n - The only official available information is in `TelephonyDisplayInfo` which provide inaccurate (marketing-based) data.\n\nSolution:\n - In order to obtain detailed connection info about NR NSA you need to get `NetworkType` instance.\n```kotlin\nval networkType : NetworkType = NetMonsterFactory.get(context).getNetworkType(SUBSCRIPTION_ID)\nif (networkType is NetworkType.Nr.Nsa) {\n    val state: NrNsaState = networkType.nrNsaState // For more info refer to NrNsaState class\n}\n```\n\n##### Other features\n - Detection of serving cells in 'emergency calls only' mode.\n - PLMN addition to non-serving cells in GSM, WCDMA, LTE, TD-SCDMA and NR networks.\n\nLicense\n-------\n\n    Copyright 2019 Michal Mroček\n    \n    Licensed under the Apache License, Version 2.0 (the \"License\");\n\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n    \n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n    \n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmroczis%2Fnetmonster-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmroczis%2Fnetmonster-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmroczis%2Fnetmonster-core/lists"}