summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.idea/.gitignore3
-rw-r--r--.idea/AndroidProjectSystem.xml6
-rw-r--r--.idea/compiler.xml6
-rw-r--r--.idea/deploymentTargetSelector.xml18
-rw-r--r--.idea/deviceManager.xml13
-rw-r--r--.idea/dictionaries/project.xml8
-rw-r--r--.idea/gradle.xml17
-rw-r--r--.idea/misc.xml10
-rw-r--r--.idea/runConfigurations.xml17
-rw-r--r--.idea/vcs.xml6
-rw-r--r--app/build.gradle.kts8
-rw-r--r--app/src/main/AndroidManifest.xml11
-rw-r--r--app/src/main/java/net/rctt/netmon/MainActivity.kt104
-rw-r--r--app/src/main/res/layout/activity_main.xml63
-rw-r--r--app/src/main/res/values-land/dimens.xml3
-rw-r--r--app/src/main/res/values-w1240dp/dimens.xml3
-rw-r--r--app/src/main/res/values-w600dp/dimens.xml3
-rw-r--r--app/src/main/res/values-w820dp/dimens.xml6
-rw-r--r--app/src/main/res/values/dimens.xml8
-rw-r--r--app/src/main/res/values/strings.xml3
-rw-r--r--app/src/main/res/values/themes.xml9
-rw-r--r--gradle/libs.versions.toml6
22 files changed, 315 insertions, 16 deletions
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml
new file mode 100644
index 0000000..4a53bee
--- /dev/null
+++ b/.idea/AndroidProjectSystem.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="AndroidProjectSystem">
+ <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="CompilerConfiguration">
+ <bytecodeTargetLevel target="21" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..df74897
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="deploymentTargetSelector">
+ <selectionStates>
+ <SelectionState runConfigName="app">
+ <option name="selectionMode" value="DROPDOWN" />
+ <DropdownSelection timestamp="2026-05-03T01:02:55.812002Z">
+ <Target type="DEFAULT_BOOT">
+ <handle>
+ <DeviceId pluginId="PhysicalDevice" identifier="serial=47111JEKB06200" />
+ </handle>
+ </Target>
+ </DropdownSelection>
+ <DialogSelection />
+ </SelectionState>
+ </selectionStates>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/deviceManager.xml b/.idea/deviceManager.xml
new file mode 100644
index 0000000..91f9558
--- /dev/null
+++ b/.idea/deviceManager.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="DeviceTable">
+ <option name="columnSorters">
+ <list>
+ <ColumnSorterState>
+ <option name="column" value="Name" />
+ <option name="order" value="ASCENDING" />
+ </ColumnSorterState>
+ </list>
+ </option>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml
new file mode 100644
index 0000000..ffb84f9
--- /dev/null
+++ b/.idea/dictionaries/project.xml
@@ -0,0 +1,8 @@
+<component name="ProjectDictionaryState">
+ <dictionary name="project">
+ <words>
+ <w>tdscdma</w>
+ <w>wcdma</w>
+ </words>
+ </dictionary>
+</component> \ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..cdbc250
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="GradleSettings">
+ <option name="linkedExternalProjectsSettings">
+ <GradleProjectSettings>
+ <option name="testRunner" value="CHOOSE_PER_TEST" />
+ <option name="externalProjectPath" value="$PROJECT_DIR$" />
+ <option name="modules">
+ <set>
+ <option value="$PROJECT_DIR$" />
+ <option value="$PROJECT_DIR$/app" />
+ </set>
+ </option>
+ </GradleProjectSettings>
+ </option>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ExternalStorageConfigurationManager" enabled="true" />
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/build/classes" />
+ </component>
+ <component name="ProjectType">
+ <option name="id" value="Android" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="RunConfigurationProducerService">
+ <option name="ignoredProducers">
+ <set>
+ <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
+ <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
+ <option value="com.intellij.execution.junit.PatternConfigurationProducer" />
+ <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
+ <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
+ <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
+ <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
+ <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
+ </set>
+ </option>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
+ </component>
+</project> \ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 98e6f42..21281d3 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -12,7 +12,7 @@ android {
defaultConfig {
applicationId = "net.rctt.netmon"
- minSdk = 26
+ minSdk = 29
targetSdk = 36
versionCode = 1
versionName = "1.0"
@@ -33,6 +33,9 @@ android {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
+ buildFeatures {
+ viewBinding = true
+ }
}
dependencies {
@@ -41,6 +44,9 @@ dependencies {
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.lifecycle.livedata.ktx)
+ implementation(libs.androidx.lifecycle.viewmodel.ktx)
+ implementation(libs.androidx.cardview)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 87305ab..d036883 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools" >
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
@@ -10,13 +12,12 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
- android:theme="@style/Theme.Netmon" >
+ android:theme="@style/Theme.Netmon">
<activity
android:name=".MainActivity"
- android:exported="true" >
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
-
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
diff --git a/app/src/main/java/net/rctt/netmon/MainActivity.kt b/app/src/main/java/net/rctt/netmon/MainActivity.kt
index 53c6f05..7111922 100644
--- a/app/src/main/java/net/rctt/netmon/MainActivity.kt
+++ b/app/src/main/java/net/rctt/netmon/MainActivity.kt
@@ -1,12 +1,34 @@
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.CellInfoGsm
+import android.telephony.CellInfoLte
+import android.telephony.CellInfoNr
+import android.telephony.CellInfoTdscdma
+import android.telephony.CellInfoWcdma
+import android.telephony.TelephonyManager
+import android.util.Log
+import android.widget.LinearLayout
+import android.widget.TextView
import androidx.activity.enableEdgeToEdge
+import androidx.annotation.RequiresPermission
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
+import java.text.SimpleDateFormat
+import java.util.Date
class MainActivity : AppCompatActivity() {
+ lateinit var statusView: LinearLayout
+ lateinit var cellView: LinearLayout
+
+ lateinit var tel: TelephonyManager
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
@@ -16,5 +38,87 @@ class MainActivity : AppCompatActivity() {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
+
+ statusView = findViewById(R.id.statusView)
+ cellView = findViewById(R.id.cellView)
+
+ val pLoc = ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.ACCESS_FINE_LOCATION)
+ if (pLoc == -1) {
+ log("Location permission required")
+ } else {
+ log("Ready")
+ 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)
+ }
+ })
+ }
+ }
+
+ @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
+ fun refresh() {
+ log("refreshing")
+
+ val cellList = tel.allCellInfo
+ cellView.removeAllViews()
+ for (cell in cellList) {
+ when (cell) {
+ is CellInfoGsm -> {
+ logDetected("GSM")
+ }
+ is CellInfoLte -> {
+ val id = cell.cellIdentity
+ if (id.ci == 2147483647) {
+ continue
+ }
+
+ logDetected("LTE")
+ logCell("CID: ${id.ci}")
+ logCell("PCI: ${id.pci}")
+ logCell("TAC: ${id.tac}")
+ logCell("EARFCN ${id.earfcn}")
+ logCell("BANDWIDTH: ${id.bandwidth}")
+ logCell("RSRP: ${cell.cellSignalStrength.rsrp}")
+ logCell("DBM: ${cell.cellSignalStrength.dbm}")
+ logCell("STATUS: ${cell.cellConnectionStatus}")
+ logCell("")
+ }
+ is CellInfoNr -> {
+ logDetected("NR")
+ }
+ is CellInfoTdscdma -> {
+ logDetected("TDSCDMA")
+ }
+ is CellInfoWcdma -> {
+ logDetected("WCDMA")
+ }
+ }
+ }
+ }
+
+ @SuppressLint("SimpleDateFormat", "SetTextI18n")
+ fun log(text: String) {
+ val sdf = SimpleDateFormat("hh:mm:ss")
+ val date = sdf.format(Date())
+ val msg = TextView(this)
+ msg.text = "$date $text"
+ statusView.addView(msg)
+ }
+
+ fun logDetected(text: String) {
+ log("detected $text cell")
+ }
+
+ fun logCell(text: String) {
+ val msg = TextView(this)
+ msg.text = text
+ cellView.addView(msg)
+ Log.d("NETMON", text)
}
} \ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 25a2ae6..e7c0e2c 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -7,13 +7,56 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Hello World!"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- </androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ 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="400dp">
+
+ <LinearLayout
+ android:id="@+id/cellView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+ </ScrollView>
+
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="?android:attr/listDivider" />
+
+ <TextView
+ android:id="@+id/headerStatus"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Status"
+ android:textSize="20sp" />
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:id="@+id/statusView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"/>
+ </ScrollView>
+ </LinearLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml
new file mode 100644
index 0000000..22d7f00
--- /dev/null
+++ b/app/src/main/res/values-land/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+ <dimen name="fab_margin">48dp</dimen>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values-w1240dp/dimens.xml b/app/src/main/res/values-w1240dp/dimens.xml
new file mode 100644
index 0000000..d73f4a3
--- /dev/null
+++ b/app/src/main/res/values-w1240dp/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+ <dimen name="fab_margin">200dp</dimen>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 0000000..22d7f00
--- /dev/null
+++ b/app/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+ <dimen name="fab_margin">48dp</dimen>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..9309de9
--- /dev/null
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,6 @@
+<resources>
+ <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+ (such as screen margins) for screens with more than 820dp of available width. This
+ would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+ <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..0a87b6e
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,8 @@
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+ <dimen name="appbar_padding">16dp</dimen>
+ <dimen name="fab_margin">16dp</dimen>
+ <dimen name="appbar_padding_top">8dp</dimen>
+</resources> \ 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 1d0121e..2c29dfa 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,6 @@
<resources>
<string name="app_name">netmon</string>
+ <string name="title_activity_main2">MainActivity2</string>
+ <string name="tab_text_1">Tab 1</string>
+ <string name="tab_text_2">Tab 2</string>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 9b8da79..8c1e2ef 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -6,4 +6,13 @@
</style>
<style name="Theme.Netmon" parent="Base.Theme.Netmon" />
+
+ <style name="Theme.Netmon.NoActionBar">
+ <item name="windowActionBar">false</item>
+ <item name="windowNoTitle">true</item>
+ </style>
+
+ <style name="Theme.Netmon.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+ <style name="Theme.Netmon.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources> \ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 486d16b..20de420 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -8,6 +8,9 @@ appcompat = "1.7.1"
material = "1.13.0"
activity = "1.13.0"
constraintlayout = "2.2.1"
+lifecycleLivedataKtx = "2.10.0"
+lifecycleViewmodelKtx = "2.10.0"
+cardview = "1.0.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -18,6 +21,9 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
+androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
+androidx-cardview = { group = "androidx.cardview", name = "cardview", version.ref = "cardview" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }