fork download
  1. # your code goes here
Success #stdin #stdout 0.01s 7136KB
stdin
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.net.wifi.WifiManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Menu
import android.view.MenuItem
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.room.*
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import java.util.*
import kotlinx.coroutines.*
import java.text.SimpleDateFormat

// Entidad para la base de datos
@Entity(tableName = "wifi_measurements")
data class WifiMeasurement(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val ssid: String,
    val bssid: String,
    val signalStrength: Int,
    val timestamp: Long = System.currentTimeMillis()
)

// DAO para acceder a la base de datos
@Dao
interface WifiMeasurementDao {
    @Query("SELECT * FROM wifi_measurements WHERE ssid = :ssid ORDER BY timestamp DESC")
    suspend fun getMeasurementsForNetwork(ssid: String): List<WifiMeasurement>

    @Insert
    suspend fun insert(measurement: WifiMeasurement)

    @Query("DELETE FROM wifi_measurements WHERE timestamp < :timestamp")
    suspend fun deleteOldMeasurements(timestamp: Long)
}

// Base de datos
@Database(entities = [WifiMeasurement::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun wifiMeasurementDao(): WifiMeasurementDao
}

class MainActivity : AppCompatActivity() {
    private lateinit var wifiManager: WifiManager
    private lateinit var scanResultsText: TextView
    private lateinit var scanButton: Button
    private lateinit var filterEdit: EditText
    private lateinit var signalChart: LineChart
    private lateinit var db: AppDatabase
    
    private val PERMISSIONS_REQUEST_CODE = 123
    private val requiredPermissions = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_WIFI_STATE,
        Manifest.permission.CHANGE_WIFI_STATE
    )
    
    private val handler = Handler(Looper.getMainLooper())
    private var isAutoUpdateEnabled = false
    private val updateInterval = 5000L // 5 segundos
    private val scope = CoroutineScope(Dispatchers.Main + Job())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Inicializar componentes
        wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        scanResultsText = findViewById(R.id.scanResultsText)
        scanButton = findViewById(R.id.scanButton)
        filterEdit = findViewById(R.id.filterEdit)
        signalChart = findViewById(R.id.signalChart)

        // Inicializar base de datos
        db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java,
            "wifi-database"
        ).build()

        // Configurar el gráfico
        setupChart()

        scanButton.setOnClickListener {
            if (checkAndRequestPermissions()) {
                scanWifiNetworks()
            }
        }

        // Limpiar datos antiguos (más de 24 horas)
        scope.launch {
            val oneDayAgo = System.currentTimeMillis() - (24 * 60 * 60 * 1000)
            db.wifiMeasurementDao().deleteOldMeasurements(oneDayAgo)
        }
    }

    private fun setupChart() {
        signalChart.apply {
            description.isEnabled = false
            setDrawGridBackground(false)
            xAxis.setDrawGridLines(false)
            axisRight.isEnabled = false
            legend.isEnabled = true
        }
    }

    private fun startAutoUpdate() {
        isAutoUpdateEnabled = true
        handler.postDelayed(object : Runnable {
            override fun run() {
                if (isAutoUpdateEnabled && checkAndRequestPermissions()) {
                    scanWifiNetworks()
                    handler.postDelayed(this, updateInterval)
                }
            }
        }, updateInterval)
    }

    private fun stopAutoUpdate() {
        isAutoUpdateEnabled = false
        handler.removeCallbacksAndMessages(null)
    }

    private fun scanWifiNetworks() {
        val results = wifiManager.scanResults
        val filterText = filterEdit.text.toString().lowercase()
        
        val filteredResults = results.filter { result ->
            filterText.isEmpty() || result.SSID.lowercase().contains(filterText)
        }

        val networksInfo = StringBuilder()
        
        scope.launch {
            filteredResults.forEach { result ->
                // Guardar medición en la base de datos
                db.wifiMeasurementDao().insert(
                    WifiMeasurement(
                        ssid = result.SSID,
                        bssid = result.BSSID,
                        signalStrength = result.level
                    )
                )

                networksInfo.append("""
                    SSID: ${result.SSID}
                    BSSID: ${result.BSSID}
                    Intensidad de señal: ${result.level} dBm
                    Frecuencia: ${result.frequency} MHz
                    Capacidades: ${result.capabilities}
                    
                """.trimIndent())
            }
            
            scanResultsText.text = networksInfo.toString()
            updateChart(filteredResults[0].SSID) // Actualizar gráfico para la primera red
        }
    }

    private fun updateChart(ssid: String) {
        scope.launch {
            val measurements = db.wifiMeasurementDao().getMeasurementsForNetwork(ssid)
            val entries = measurements.mapIndexed { index, measurement ->
                Entry(index.toFloat(), measurement.signalStrength.toFloat())
            }

            val dataSet = LineDataSet(entries, "Señal de $ssid").apply {
                color = ContextCompat.getColor(this@MainActivity, R.color.purple_500)
                setDrawCircles(false)
                lineWidth = 2f
            }

            signalChart.data = LineData(dataSet)
            signalChart.invalidate()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_auto_update -> {
                if (isAutoUpdateEnabled) {
                    stopAutoUpdate()
                    item.setTitle("Iniciar actualización automática")
                } else {
                    startAutoUpdate()
                    item.setTitle("Detener actualización automática")
                }
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        stopAutoUpdate()
        scope.cancel()
    }
}
stdout
Standard output is empty