diff options
| author | bt <bt@rctt.net> | 2026-05-26 23:13:08 +0200 |
|---|---|---|
| committer | bt <bt@rctt.net> | 2026-05-26 23:19:53 +0200 |
| commit | e787e83e781c999c0555e1db5e99ac5685a84536 (patch) | |
| tree | aceb345ceb4db66c9f1db99085f215b7a3021ef2 /app/src/main/java | |
| parent | e81ce6af3d97a51e51f676f32e739d0f174323c7 (diff) | |
| download | netmon-e787e83e781c999c0555e1db5e99ac5685a84536.tar.gz netmon-e787e83e781c999c0555e1db5e99ac5685a84536.zip | |
Load netmonitor CSV database and show cells descriptions
Diffstat (limited to 'app/src/main/java')
| -rw-r--r-- | app/src/main/java/net/rctt/netmon/CellDbItem.kt | 31 | ||||
| -rw-r--r-- | app/src/main/java/net/rctt/netmon/CellView.kt | 9 | ||||
| -rw-r--r-- | app/src/main/java/net/rctt/netmon/MainActivity.kt | 93 |
3 files changed, 121 insertions, 12 deletions
diff --git a/app/src/main/java/net/rctt/netmon/CellDbItem.kt b/app/src/main/java/net/rctt/netmon/CellDbItem.kt new file mode 100644 index 0000000..2922bb1 --- /dev/null +++ b/app/src/main/java/net/rctt/netmon/CellDbItem.kt @@ -0,0 +1,31 @@ +package net.rctt.netmon + +// NETWORK_TYPE;MCC;MNC;LAC;CID;PSC;CHANNEL;LATITUDE;LONGITUDE;ACCURACY;DESCRIPTION + +/* +NETWORK_TYPE String C (CDMA), G (GSM), W (WCDMA), T (TDSCDMA), L (LTE), N (5G NR) Mandatory for CDMA +MCC String 3 digits Mandatory +MNC String 2 or 3 digits Mandatory +LAC Int NID (CDMA), LAC (GSM, WCDMA, TDSCDMA), TAC (LTE, 5G NR) Mandatory +CID Long BID (CDMA), CID (GSM, WCDMA, TDSCDMA), CI (LTE), NCI (5G NR) Mandatory +PSC Int SID (CDMA), BSIC (GSM), PSC (WCDMA), CPID (TDSCDMA), PCI (LTE, 5G NR) Mandatory for CDMA +CHANNEL Int ARFCN (GSM, 5G NR), UARFCN (WCDMA, TDSCDMA), EARFCN (LTE) +LATITUDE Double [-90;90], . as separator +LONGITUDE Double [-180;180], . as separator +ACCURACY Int in meters +DESCRIPTION String text +*/ + +class CellDbItem { + var Type: String = "" + var MCC: String = "" + var MNC: String = "" + var LAC: Int = 0 + var CID: Long = 0 + var PSC: Int = 0 + var Channel: Int = 0 + var Latitude: Double = 0.0 + var Longitude: Double = 0.0 + var Accuracy: Int = 0 + var Description: String = "" +}
\ No newline at end of file diff --git a/app/src/main/java/net/rctt/netmon/CellView.kt b/app/src/main/java/net/rctt/netmon/CellView.kt index d991d48..051f05a 100644 --- a/app/src/main/java/net/rctt/netmon/CellView.kt +++ b/app/src/main/java/net/rctt/netmon/CellView.kt @@ -23,6 +23,8 @@ class CellView : ConstraintLayout{ var typeView: TextView var idView: TextView var powerView: TextView + var descView: TextView + var powerChartView: XYPlot var powerChartSeries: SimpleXYSeries @@ -34,6 +36,7 @@ class CellView : ConstraintLayout{ typeView = findViewById(R.id.type) idView = findViewById(R.id.id) powerView = findViewById(R.id.power) + descView = findViewById(R.id.desc) powerChartView = findViewById(R.id.power_chart) powerHistory = mutableListOf() powerChartSeries= SimpleXYSeries( @@ -76,6 +79,10 @@ class CellView : ConstraintLayout{ powerView.text = power.toString() } + fun setDesc(desc: String) { + descView.text = desc + } + fun refresh() { powerChartView.removeSeries(powerChartSeries) @@ -96,8 +103,6 @@ class CellView : ConstraintLayout{ val series1Format = LineAndPointFormatter(Color.RED, Color.GREEN, Color.BLUE, null) - Log.d("ASD", seriesData.toString()) - powerChartView.addSeries(powerChartSeries, series1Format) } diff --git a/app/src/main/java/net/rctt/netmon/MainActivity.kt b/app/src/main/java/net/rctt/netmon/MainActivity.kt index bc0f136..66d77c6 100644 --- a/app/src/main/java/net/rctt/netmon/MainActivity.kt +++ b/app/src/main/java/net/rctt/netmon/MainActivity.kt @@ -14,6 +14,7 @@ import android.telephony.CellInfoTdscdma import android.telephony.CellInfoWcdma import android.telephony.TelephonyManager import android.telephony.TelephonyManager.CellInfoCallback +import android.util.Log import android.widget.LinearLayout import android.widget.TextView import androidx.activity.enableEdgeToEdge @@ -22,6 +23,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +import com.jsoizo.kotlincsv.CsvDialect +import com.jsoizo.kotlincsv.csvReader +import com.jsoizo.kotlincsv.reader.readFromFile +import java.io.File +import java.io.IOException +import java.lang.reflect.Type import java.text.SimpleDateFormat import java.util.Date @@ -29,6 +36,7 @@ class MainActivity : AppCompatActivity() { lateinit var cellsListView: LinearLayout lateinit var tel: TelephonyManager lateinit var cellsList: HashMap<Number, CellView> + val cellDb = HashMap<Int, HashMap<Long, CellDbItem>>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -40,6 +48,8 @@ class MainActivity : AppCompatActivity() { insets } + loadDb() + cellsList = HashMap() cellsListView = findViewById(R.id.cellsList) @@ -56,13 +66,53 @@ class MainActivity : AppCompatActivity() { }) } + fun loadDb() { + val reader = csvReader { + dialect = CsvDialect(delimiter = ';') + } + + reader.readFromFile(File("/storage/emulated/0/cells.csv")) { rows -> + rows.forEach { + val item = CellDbItem() + item.Type = it.elementAt(0) + item.MCC = it.elementAt(1) + item.MNC = it.elementAt(2) + item.LAC = it.elementAt(3).toInt() + item.CID = it.elementAt(4).toLong() + if (it.elementAt(5) != "") { + item.PSC = it.elementAt(5).toInt() + } + if (it.elementAt(6) != "") { + item.Channel = it.elementAt(6).toInt() + } + item.Latitude = it.elementAt(7).toDouble() + item.Longitude = it.elementAt(8).toDouble() + if (it.elementAt(9) != "") { + item.Accuracy = it.elementAt(9).toInt() + } + item.Description = it.elementAt(10) + + var lac = cellDb[item.LAC] + if (lac == null) { + cellDb[item.LAC] = HashMap() + lac = cellDb[item.LAC] + } + + lac?.set(item.CID, item) + } + } + } + + fun findInDb(lac: Int, cid: Long): CellDbItem? { + return cellDb[lac]?.get(cid) + } + @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) fun refresh() { tel.requestCellInfoUpdate(mainExecutor, object : CellInfoCallback() { @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) override fun onCellInfo(cellList: List<CellInfo?>) { cellsListView.removeAllViews() - for (cell in cellList) { if (cell == null) { continue @@ -74,35 +124,58 @@ class MainActivity : AppCompatActivity() { } @SuppressLint("SetTextI18n") - fun addCellView(cell :CellInfo){ + fun addCellView(cell: CellInfo) { val id = getCellId(cell) + if (id == 65535 || id == 2147483647) { + return + } + + val lac = getCellLac(cell) + val findInDb = findInDb(lac.toInt(), id.toLong()) + val desc = findInDb?.Description ?: "" + var cellView = cellsList[id] if (cellView == null) { cellView = CellView(this, id) cellsList[id] = cellView + } else { + cellsListView.removeView(cellView) } when (cell) { is CellInfoGsm -> cellView.set(cell) - is CellInfoLte -> cellView.set(cell) - is CellInfoNr -> cellView.set(cell) - is CellInfoTdscdma -> cellView.set(cell) - is CellInfoWcdma -> cellView.set(cell) + is CellInfoLte -> cellView.set(cell) + is CellInfoNr -> cellView.set(cell) + is CellInfoTdscdma -> cellView.set(cell) + is CellInfoWcdma -> cellView.set(cell) } cellView.refresh() + cellView.setDesc(desc) cellsListView.addView(cellView) } } -fun getCellId(cell: CellInfo) : Number { +fun getCellId(cell: CellInfo): Number { when (cell) { is CellInfoGsm -> return cell.cellIdentity.cid - is CellInfoLte -> return cell.cellIdentity.ci - is CellInfoNr -> return (cell.cellIdentity as CellIdentityNr).nci - is CellInfoTdscdma -> return cell.cellIdentity.cid + is CellInfoLte -> return cell.cellIdentity.ci + is CellInfoNr -> return (cell.cellIdentity as CellIdentityNr).nci + is CellInfoTdscdma -> return cell.cellIdentity.cid is CellInfoWcdma -> return cell.cellIdentity.cid } return 0 +} + +fun getCellLac(cell: CellInfo): Number { + when (cell) { + is CellInfoGsm -> return cell.cellIdentity.lac + is CellInfoLte -> return cell.cellIdentity.tac + is CellInfoNr -> return (cell.cellIdentity as CellIdentityNr).tac + is CellInfoTdscdma -> return cell.cellIdentity.lac + is CellInfoWcdma -> return cell.cellIdentity.lac + } + + return 0 }
\ No newline at end of file |
