diff options
Diffstat (limited to 'app/src')
| -rw-r--r-- | app/src/main/java/net/rctt/netmon/LogFragment.kt | 59 | ||||
| -rw-r--r-- | app/src/main/java/net/rctt/netmon/MainActivity.kt | 198 | ||||
| -rw-r--r-- | app/src/main/java/net/rctt/netmon/MapFragment.kt | 59 | ||||
| -rw-r--r-- | app/src/main/res/drawable/baseline_map_24.xml | 5 | ||||
| -rw-r--r-- | app/src/main/res/drawable/rounded_bar_chart_24.xml | 5 | ||||
| -rw-r--r-- | app/src/main/res/layout/activity_main.xml | 49 | ||||
| -rw-r--r-- | app/src/main/res/layout/fragment_log.xml | 14 | ||||
| -rw-r--r-- | app/src/main/res/layout/fragment_map.xml | 14 | ||||
| -rw-r--r-- | app/src/main/res/menu/nav_menu.xml | 11 | ||||
| -rw-r--r-- | app/src/main/res/values/strings.xml | 2 |
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 |
