Initial commit: Android Tether API app
Exposes phone connection status via HTTP API for tethered devices. Features: - Auto-start/stop server when tethering is enabled/disabled - REST API with /status and /health endpoints - Connection type, signal strength, carrier, battery info - Foreground service with persistent notification Stack: Kotlin 2.3, AGP 8.13, Gradle 8.13, compileSdk 36
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package dev.itsh.tetherapi.receiver
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.ConnectivityManager
|
||||
import android.os.Build
|
||||
import androidx.preference.PreferenceManager
|
||||
import dev.itsh.tetherapi.service.TetherApiService
|
||||
|
||||
class TetherStateReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action != ACTION_TETHER_STATE_CHANGED) return
|
||||
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val autoStartEnabled = prefs.getBoolean(PREF_AUTO_START, true)
|
||||
|
||||
if (!autoStartEnabled) return
|
||||
|
||||
val isTethering = isTetherActive(context, intent)
|
||||
val port = prefs.getInt(PREF_PORT, TetherApiService.DEFAULT_PORT)
|
||||
|
||||
if (isTethering && !TetherApiService.isRunning) {
|
||||
TetherApiService.start(context, port)
|
||||
} else if (!isTethering && TetherApiService.isRunning) {
|
||||
TetherApiService.stop(context)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun isTetherActive(context: Context, intent: Intent): Boolean {
|
||||
val extras = intent.extras ?: return false
|
||||
|
||||
val activeList = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
extras.getStringArrayList("activeArray")
|
||||
} else {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
extras.get("activeArray") as? ArrayList<String>
|
||||
}
|
||||
|
||||
if (!activeList.isNullOrEmpty()) {
|
||||
return true
|
||||
}
|
||||
|
||||
return try {
|
||||
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val method = cm.javaClass.getDeclaredMethod("getTetheredIfaces")
|
||||
val tetheredIfaces = method.invoke(cm) as? Array<*>
|
||||
tetheredIfaces != null && tetheredIfaces.isNotEmpty()
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED"
|
||||
const val PREF_AUTO_START = "auto_start_on_tether"
|
||||
const val PREF_PORT = "api_port"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user