summaryrefslogtreecommitdiffstats
path: root/app/src/main/java
diff options
context:
space:
mode:
authorbt <bt@rctt.net>2026-06-04 22:02:14 +0200
committerbt <bt@rctt.net>2026-06-04 22:02:14 +0200
commita50e09b8583c60cdb9316baa5a5550d9b16bc0f9 (patch)
tree1356a5eb1cb5c5b26c4ad423571555f541c8fb67 /app/src/main/java
parent094a09ebfe142334f7b89ad2f03f17ed4dc1180e (diff)
downloadnetmon-a50e09b8583c60cdb9316baa5a5550d9b16bc0f9.tar.gz
netmon-a50e09b8583c60cdb9316baa5a5550d9b16bc0f9.zip
New uinew-ui
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/net/rctt/netmon/LogFragment.kt59
-rw-r--r--app/src/main/java/net/rctt/netmon/MainActivity.kt198
-rw-r--r--app/src/main/java/net/rctt/netmon/MapFragment.kt59
3 files changed, 135 insertions, 181 deletions
diff --git a/app/src/main/java/net/rctt/netmon/LogFragment.kt b/app/src/main/java/net/rctt/netmon/LogFragment.kt
new file mode 100644
index 0000000..3755b0a
--- /dev/null
+++ b/app/src/main/java/net/rctt/netmon/LogFragment.kt
@@ -0,0 +1,59 @@
+package net.rctt.netmon
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ * Use the [LogFragment.newInstance] factory method to
+ * create an instance of this fragment.
+ */
+class LogFragment : Fragment() {
+ // TODO: Rename and change types of parameters
+ private var param1: String? = null
+ private var param2: String? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ arguments?.let {
+ param1 = it.getString(ARG_PARAM1)
+ param2 = it.getString(ARG_PARAM2)
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_log, container, false)
+ }
+
+ companion object {
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @param param1 Parameter 1.
+ * @param param2 Parameter 2.
+ * @return A new instance of fragment LogFragment.
+ */
+ // TODO: Rename and change types and number of parameters
+ @JvmStatic
+ fun newInstance(param1: String, param2: String) =
+ LogFragment().apply {
+ arguments = Bundle().apply {
+ putString(ARG_PARAM1, param1)
+ putString(ARG_PARAM2, param2)
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/net/rctt/netmon/MainActivity.kt b/app/src/main/java/net/rctt/netmon/MainActivity.kt
index 3aac48d..0d90f08 100644
--- a/app/src/main/java/net/rctt/netmon/MainActivity.kt
+++ b/app/src/main/java/net/rctt/netmon/MainActivity.kt
@@ -1,199 +1,35 @@
package net.rctt.netmon
-import android.Manifest
-import android.annotation.SuppressLint
import android.os.Bundle
-import android.os.Handler
-import android.os.Looper
-import android.telephony.CellIdentityNr
-import android.telephony.CellInfo
-import android.telephony.CellInfoGsm
-import android.telephony.CellInfoLte
-import android.telephony.CellInfoNr
-import android.telephony.CellInfoTdscdma
-import android.telephony.CellInfoWcdma
-import android.telephony.TelephonyManager
-import android.telephony.TelephonyManager.CellInfoCallback
-import android.widget.LinearLayout
-import androidx.activity.enableEdgeToEdge
-import androidx.annotation.RequiresPermission
import androidx.appcompat.app.AppCompatActivity
-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 org.osmdroid.config.Configuration
-import org.osmdroid.tileprovider.tilesource.TileSourceFactory
-import org.osmdroid.util.GeoPoint
-import org.osmdroid.views.MapView
-import org.osmdroid.views.overlay.Marker
-import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
-import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
-import java.io.File
+import androidx.fragment.app.Fragment
+import com.google.android.material.bottomnavigation.BottomNavigationView
class MainActivity : AppCompatActivity() {
- lateinit var cellsListView: LinearLayout
- lateinit var tel: TelephonyManager
- lateinit var cellsList: HashMap<Number, CellView>
- val cellDb = HashMap<Int, HashMap<Long, CellDbItem>>()
- lateinit var map: MapView
+
+ lateinit var bottomNav : BottomNavigationView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- enableEdgeToEdge()
setContentView(R.layout.activity_main)
- ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
- val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
- v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
- insets
- }
-
- Configuration.getInstance().userAgentValue =
- "Netmon/0.1 (+https://rctt.net; contact: bt@rctt.net)"
-
- map = findViewById(R.id.map)
- map.setTileSource(TileSourceFactory.MAPNIK)
- map.setMultiTouchControls(true)
- map.controller.setZoom(15)
- map.controller.setCenter(GeoPoint(51.10, 17.04));
-
- val locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), map)
- locationOverlay.enableMyLocation()
- this.map.overlays.add(locationOverlay)
-
- loadDb()
-
- cellsList = HashMap()
- cellsListView = findViewById(R.id.cellsList)
-
- tel = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
-
- val mainHandler = Handler(Looper.getMainLooper())
-
- mainHandler.post(object : Runnable {
- @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
- override fun run() {
- refresh()
- mainHandler.postDelayed(this, 1000)
- }
- })
- }
-
- 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]
+ loadFragment(LogFragment())
+ bottomNav = findViewById(R.id.bottomNav)!!
+ bottomNav.setOnItemSelectedListener {
+ when (it.itemId) {
+ R.id.log -> {
+ loadFragment(LogFragment())
}
-
- 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
- }
- addCellView(cell)
+ R.id.map -> {
+ loadFragment(MapFragment())
}
}
- })
- }
-
- @SuppressLint("SetTextI18n")
- fun addCellView(cell: CellInfo) {
- val id = getCellId(cell)
- if (id == 65535 || id == 2147483647) {
- return
+ true
}
-
- val lac = getCellLac(cell)
- val dbItem = findInDb(lac.toInt(), id.toLong())
- val desc = dbItem?.Description ?: ""
-
- var cellView = cellsList[id]
- if (cellView == null) {
- cellView = CellView(this, id)
- cellsList[id] = cellView
- cellView.setMarker(Marker(map))
- } else {
- cellsListView.removeView(cellView)
- map.overlays.remove(cellView.mapMarker)
- }
-
- 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)
- }
-
- cellView.refresh()
- cellView.setDesc(desc)
- cellView.setLocation(dbItem?.Latitude ?: 0.0, dbItem?.Longitude ?: 0.0)
- cellsListView.addView(cellView)
- map.overlays.add(cellView.mapMarker)
}
-}
-
-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 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
+ private fun loadFragment(fragment: Fragment){
+ val transaction = supportFragmentManager.beginTransaction()
+ transaction.replace(R.id.container,fragment)
+ transaction.commit()
}
- return 0
} \ No newline at end of file
diff --git a/app/src/main/java/net/rctt/netmon/MapFragment.kt b/app/src/main/java/net/rctt/netmon/MapFragment.kt
new file mode 100644
index 0000000..0ec3737
--- /dev/null
+++ b/app/src/main/java/net/rctt/netmon/MapFragment.kt
@@ -0,0 +1,59 @@
+package net.rctt.netmon
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+
+// TODO: Rename parameter arguments, choose names that match
+// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+private const val ARG_PARAM1 = "param1"
+private const val ARG_PARAM2 = "param2"
+
+/**
+ * A simple [Fragment] subclass.
+ * Use the [MapFragment.newInstance] factory method to
+ * create an instance of this fragment.
+ */
+class MapFragment : Fragment() {
+ // TODO: Rename and change types of parameters
+ private var param1: String? = null
+ private var param2: String? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ arguments?.let {
+ param1 = it.getString(ARG_PARAM1)
+ param2 = it.getString(ARG_PARAM2)
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_map, container, false)
+ }
+
+ companion object {
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @param param1 Parameter 1.
+ * @param param2 Parameter 2.
+ * @return A new instance of fragment MapFragment.
+ */
+ // TODO: Rename and change types and number of parameters
+ @JvmStatic
+ fun newInstance(param1: String, param2: String) =
+ MapFragment().apply {
+ arguments = Bundle().apply {
+ putString(ARG_PARAM1, param1)
+ putString(ARG_PARAM2, param2)
+ }
+ }
+ }
+} \ No newline at end of file