summaryrefslogtreecommitdiffstats
path: root/app
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
parent094a09ebfe142334f7b89ad2f03f17ed4dc1180e (diff)
downloadnetmon-new-ui.tar.gz
netmon-new-ui.zip
New uinew-ui
Diffstat (limited to 'app')
-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
-rw-r--r--app/src/main/res/drawable/baseline_map_24.xml5
-rw-r--r--app/src/main/res/drawable/rounded_bar_chart_24.xml5
-rw-r--r--app/src/main/res/layout/activity_main.xml49
-rw-r--r--app/src/main/res/layout/fragment_log.xml14
-rw-r--r--app/src/main/res/layout/fragment_map.xml14
-rw-r--r--app/src/main/res/menu/nav_menu.xml11
-rw-r--r--app/src/main/res/values/strings.xml2
10 files changed, 203 insertions, 213 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
diff --git a/app/src/main/res/drawable/baseline_map_24.xml b/app/src/main/res/drawable/baseline_map_24.xml
new file mode 100644
index 0000000..58f2947
--- /dev/null
+++ b/app/src/main/res/drawable/baseline_map_24.xml
@@ -0,0 +1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48V20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48V3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM15,19l-6,-2.11V5l6,2.11V19z"/>
+
+</vector>
diff --git a/app/src/main/res/drawable/rounded_bar_chart_24.xml b/app/src/main/res/drawable/rounded_bar_chart_24.xml
new file mode 100644
index 0000000..146a07d
--- /dev/null
+++ b/app/src/main/res/drawable/rounded_bar_chart_24.xml
@@ -0,0 +1,5 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M680,800Q663,800 651.5,788.5Q640,777 640,760L640,560Q640,543 651.5,531.5Q663,520 680,520L760,520Q777,520 788.5,531.5Q800,543 800,560L800,760Q800,777 788.5,788.5Q777,800 760,800L680,800ZM440,800Q423,800 411.5,788.5Q400,777 400,760L400,200Q400,183 411.5,171.5Q423,160 440,160L520,160Q537,160 548.5,171.5Q560,183 560,200L560,760Q560,777 548.5,788.5Q537,800 520,800L440,800ZM200,800Q183,800 171.5,788.5Q160,777 160,760L160,400Q160,383 171.5,371.5Q183,360 200,360L280,360Q297,360 308.5,371.5Q320,383 320,400L320,760Q320,777 308.5,788.5Q297,800 280,800L200,800Z"/>
+
+</vector>
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 76aa1e4..06e058e 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,42 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/main"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="#ffffff"
tools:context=".MainActivity">
- <LinearLayout
- android:layout_width="0dp"
+ <FrameLayout
+ android:id="@+id/container"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
+ android:layout_above="@+id/bottomNav" />
+
+
+ <com.google.android.material.bottomnavigation.BottomNavigationView
+ android:id="@+id/bottomNav"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:scrollIndicators="left"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent">
-
- <TextView
- android:id="@+id/haederCell"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="Cell Info"
- android:textSize="20sp" />
-
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:id="@+id/cellsList"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" />
- </ScrollView>
- <org.osmdroid.views.MapView android:id="@+id/map"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
- </LinearLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
+ app:menu="@menu/nav_menu" />
+</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_log.xml b/app/src/main/res/layout/fragment_log.xml
new file mode 100644
index 0000000..8df01f3
--- /dev/null
+++ b/app/src/main/res/layout/fragment_log.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".LogFragment">
+
+ <!-- TODO: Update blank fragment layout -->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="LOG" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_map.xml b/app/src/main/res/layout/fragment_map.xml
new file mode 100644
index 0000000..3ebc6c4
--- /dev/null
+++ b/app/src/main/res/layout/fragment_map.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".MapFragment">
+
+ <!-- TODO: Update blank fragment layout -->
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="MAP" />
+
+</FrameLayout> \ No newline at end of file
diff --git a/app/src/main/res/menu/nav_menu.xml b/app/src/main/res/menu/nav_menu.xml
new file mode 100644
index 0000000..7c766a1
--- /dev/null
+++ b/app/src/main/res/menu/nav_menu.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/log"
+ android:icon="@drawable/rounded_bar_chart_24"
+ android:title="Logs" />
+ <item
+ android:id="@+id/map"
+ android:icon="@drawable/baseline_map_24"
+ android:title="Map" />
+</menu> \ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2c29dfa..723086d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -3,4 +3,6 @@
<string name="title_activity_main2">MainActivity2</string>
<string name="tab_text_1">Tab 1</string>
<string name="tab_text_2">Tab 2</string>
+ <!-- TODO: Remove or change this placeholder text -->
+ <string name="hello_blank_fragment">Hello blank fragment</string>
</resources> \ No newline at end of file