Ejemplos de Funciones Móviles Android Kotlin

Ejemplos de funciones móviles Android Kotlin incluyendo información del dispositivo, estado de la red y control de vibración

💻 Información del Dispositivo kotlin

🟢 simple ⭐⭐

Obtener detalles del dispositivo incluyendo modelo, fabricante, versión del SO, dimensiones de pantalla e identificadores únicos

⏱️ 25 min 🏷️ kotlin, android, device, hardware
Prerequisites: Basic Kotlin, Android SDK
// Android Kotlin Device Information Examples
// Using android.os.Build, android.util.DisplayMetrics, and Context

import android.content.Context
import android.os.Build
import android.util.DisplayMetrics
import android.view.WindowManager
import android.provider.Settings
import java.io.File

// 1. Basic Device Information
class DeviceInfo(private val context: Context) {

    // Get device manufacturer
    fun getManufacturer(): String {
        return Build.MANUFACTURER
    }

    // Get device model
    fun getModel(): String {
        return Build.MODEL
    }

    // Get device name (manufacturer + model)
    fun getDeviceName(): String {
        return "${Build.MANUFACTURER} ${Build.MODEL}"
    }

    // Get Android version
    fun getAndroidVersion(): String {
        return "Android ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})"
    }

    // Get build version information
    fun getBuildInfo(): String {
        return """
            Build ID: ${Build.DISPLAY}
            Build Date: ${Build.TIME}
            Build Type: ${Build.TYPE}
            Build Tags: ${Build.TAGS}
        """.trimIndent()
    }

    // Get device brand
    fun getBrand(): String {
        return Build.BRAND
    }

    // Get device product name
    fun getProduct(): String {
        return Build.PRODUCT
    }

    // Get device hardware name
    fun getHardware(): String {
        return Build.HARDWARE
    }

    // Get device serial number (requires permission)
    fun getSerialNumber(): String {
        return try {
            Build.getSerial()
        } catch (e: SecurityException) {
            "Permission denied"
        }
    }

    // Get bootloader version
    fun getBootloader(): String {
        return Build.BOOTLOADER
    }

    // Get device board
    fun getBoard(): String {
        return Build.BOARD
    }

    // Get device fingerprint
    fun getFingerprint(): String {
        return Build.FINGERPRINT
    }
}

// 2. Screen Information
class ScreenInfo(private val context: Context) {

    // Get screen dimensions in pixels
    fun getScreenSize(): Pair<Int, Int> {
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        return Pair(displayMetrics.widthPixels, displayMetrics.heightPixels)
    }

    // Get screen density
    fun getScreenDensity(): Float {
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        return displayMetrics.density
    }

    // Get screen density DPI
    fun getScreenDensityDpi(): Int {
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        return displayMetrics.densityDpi
    }

    // Get screen size category (small, normal, large, xlarge)
    fun getScreenSizeCategory(): String {
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        val screenSize = displayMetrics.widthPixels.toFloat() * displayMetrics.heightPixels.toFloat() / (displayMetrics.density * displayMetrics.density)

        return when {
            screenSize < 300_000 -> "small"
            screenSize < 500_000 -> "normal"
            screenSize < 700_000 -> "large"
            else -> "xlarge"
        }
    }

    // Get screen orientation
    fun getScreenOrientation(): String {
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val rotation = windowManager.defaultDisplay.rotation
        return when (rotation) {
            0 -> "portrait"
            1 -> "landscape"
            2 -> "reverse portrait"
            3 -> "reverse landscape"
            else -> "unknown"
        }
    }

    // Get real screen size (including decorations)
    fun getRealScreenSize(): Pair<Int, Int> {
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val displayMetrics = DisplayMetrics()
        windowManager.defaultDisplay.getRealMetrics(displayMetrics)
        return Pair(displayMetrics.widthPixels, displayMetrics.heightPixels)
    }
}

// 3. Device Identifiers
class DeviceIdentifiers(private val context: Context) {

    // Get Android ID
    fun getAndroidId(): String {
        return Settings.Secure.getString(
            context.contentResolver,
            Settings.Secure.ANDROID_ID
        )
    }

    // Get unique ID (custom implementation)
    fun getUniqueId(): String {
        val androidId = Settings.Secure.getString(
            context.contentResolver,
            Settings.Secure.ANDROID_ID
        )
        return if (androidId != null && androidId != "9774d56d682e549c") {
            androidId
        } else {
            Build.SERIAL
        }
    }

    // Get installation ID
    fun getInstallationId(): String {
        return try {
            val file = File(context.filesDir, "installation_id")
            if (!file.exists()) {
                file.writeText(${System.currentTimeMillis()}-${Build.SERIAL})
            }
            file.readText()
        } catch (e: Exception) {
            "unknown"
        }
    }
}

// 4. System Information
class SystemInfo(private val context: Context) {

    // Get available memory
    fun getAvailableMemory(): Long {
        val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
        val memoryInfo = android.app.ActivityManager.MemoryInfo()
        activityManager.getMemoryInfo(memoryInfo)
        return memoryInfo.availMem
    }

    // Get total memory
    fun getTotalMemory(): Long {
        val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
        val memoryInfo = android.app.ActivityManager.MemoryInfo()
        activityManager.getMemoryInfo(memoryInfo)
        return memoryInfo.totalMem
    }

    // Get low memory threshold
    fun getLowMemoryThreshold(): Long {
        val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
        val memoryInfo = android.app.ActivityManager.MemoryInfo()
        activityManager.getMemoryInfo(memoryInfo)
        return memoryInfo.threshold
    }

    // Check if device is low on memory
    fun isLowMemory(): Boolean {
        val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
        val memoryInfo = android.app.ActivityManager.MemoryInfo()
        activityManager.getMemoryInfo(memoryInfo)
        return memoryInfo.lowMemory
    }

    // Get number of CPU cores
    fun getCpuCores(): Int {
        return Runtime.getRuntime().availableProcessors()
    }

    // Get available internal storage
    fun getAvailableInternalStorage(): Long {
        val stat = android.os.StatFs(Environment.getDataDirectory().path)
        return stat.availableBlocksLong * stat.blockSizeLong
    }

    // Get total internal storage
    fun getTotalInternalStorage(): Long {
        val stat = android.os.StatFs(Environment.getDataDirectory().path)
        return stat.blockCountLong * stat.blockSizeLong
    }
}

// 5. Battery Information
class BatteryInfo(private val context: Context) {

    // Get battery level percentage
    fun getBatteryLevel(): Int {
        val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
            context.registerReceiver(null, ifilter)
        }

        val level: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1
        val scale: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1

        return if (level != -1 && scale != -1) {
            (level * 100) / scale
        } else {
            -1
        }
    }

    // Check if device is charging
    fun isCharging(): Boolean {
        val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
            context.registerReceiver(null, ifilter)
        }

        val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
        return status == BatteryManager.BATTERY_STATUS_CHARGING ||
               status == BatteryManager.BATTERY_STATUS_FULL
    }

    // Get charging status
    fun getChargingStatus(): String {
        val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
            context.registerReceiver(null, ifilter)
        }

        val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
        return when (status) {
            BatteryManager.BATTERY_STATUS_CHARGING -> "charging"
            BatteryManager.BATTERY_STATUS_DISCHARGING -> "discharging"
            BatteryManager.BATTERY_STATUS_FULL -> "full"
            BatteryManager.BATTERY_STATUS_NOT_CHARGING -> "not charging"
            BatteryManager.BATTERY_STATUS_UNKNOWN -> "unknown"
            else -> "unknown"
        }
    }

    // Get battery health
    fun getBatteryHealth(): String {
        val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { ifilter ->
            context.registerReceiver(null, ifilter)
        }

        val health: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_HEALTH, -1) ?: -1
        return when (health) {
            BatteryManager.BATTERY_HEALTH_GOOD -> "good"
            BatteryManager.BATTERY_HEALTH_OVERHEAT -> "overheat"
            BatteryManager.BATTERY_HEALTH_DEAD -> "dead"
            BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE -> "over voltage"
            BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE -> "failure"
            BatteryManager.BATTERY_HEALTH_COLD -> "cold"
            else -> "unknown"
        }
    }
}

// 6. Telephony Information
class TelephonyInfo(private val context: Context) {

    private val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as android.telephony.TelephonyManager

    // Get SIM operator name
    fun getSimOperatorName(): String {
        return try {
            telephonyManager.simOperatorName ?: "unknown"
        } catch (e: SecurityException) {
            "Permission denied"
        }
    }

    // Get network operator name
    fun getNetworkOperatorName(): String {
        return try {
            telephonyManager.networkOperatorName ?: "unknown"
        } catch (e: SecurityException) {
            "Permission denied"
        }
    }

    // Get network type
    fun getNetworkType(): String {
        return try {
            when (telephonyManager.networkType) {
                TelephonyManager.NETWORK_TYPE_GPRS -> "GPRS"
                TelephonyManager.NETWORK_TYPE_EDGE -> "EDGE"
                TelephonyManager.NETWORK_TYPE_UMTS -> "UMTS"
                TelephonyManager.NETWORK_TYPE_LTE -> "LTE"
                TelephonyManager.NETWORK_TYPE_5G_NR -> "5G"
                else -> "unknown"
            }
        } catch (e: SecurityException) {
            "Permission denied"
        }
    }

    // Get phone type
    fun getPhoneType(): String {
        return try {
            when (telephonyManager.phoneType) {
                TelephonyManager.PHONE_TYPE_NONE -> "none"
                TelephonyManager.PHONE_TYPE_GSM -> "GSM"
                TelephonyManager.PHONE_TYPE_CDMA -> "CDMA"
                TelephonyManager.PHONE_TYPE_SIP -> "SIP"
                else -> "unknown"
            }
        } catch (e: SecurityException) {
            "Permission denied"
        }
    }

    // Get SIM serial number
    fun getSimSerialNumber(): String {
        return try {
            telephonyManager.simSerialNumber ?: "unknown"
        } catch (e: SecurityException) {
            "Permission denied"
        }
    }

    // Check if SIM is ready
    fun isSimReady(): Boolean {
        return try {
            telephonyManager.simState == TelephonyManager.SIM_STATE_READY
        } catch (e: SecurityException) {
            false
        }
    }
}

// Main demonstration
fun demonstrateDeviceInformation(context: Context) {
    println("=== Android Kotlin Device Information Examples ===\n")

    // 1. Basic device info
    println("--- 1. Basic Device Information ---")
    val deviceInfo = DeviceInfo(context)
    println("Manufacturer: ${deviceInfo.getManufacturer()}")
    println("Model: ${deviceInfo.getModel()}")
    println("Device Name: ${deviceInfo.getDeviceName()}")
    println("Android Version: ${deviceInfo.getAndroidVersion()}")
    println("Brand: ${deviceInfo.getBrand()}")
    println("Product: ${deviceInfo.getProduct()}")
    println("Hardware: ${deviceInfo.getHardware()}")

    // 2. Screen information
    println("\n--- 2. Screen Information ---")
    val screenInfo = ScreenInfo(context)
    val (width, height) = screenInfo.getScreenSize()
    println("Screen Size: ${width}x${height}")
    println("Screen Density: ${screenInfo.getScreenDensity()}")
    println("Screen DPI: ${screenInfo.getScreenDensityDpi()}")
    println("Screen Size Category: ${screenInfo.getScreenSizeCategory()}")
    println("Screen Orientation: ${screenInfo.getScreenOrientation()}")

    // 3. Device identifiers
    println("\n--- 3. Device Identifiers ---")
    val deviceIds = DeviceIdentifiers(context)
    println("Android ID: ${deviceIds.getAndroidId()}")
    println("Unique ID: ${deviceIds.getUniqueId()}")
    println("Installation ID: ${deviceIds.getInstallationId()}")

    // 4. System information
    println("\n--- 4. System Information ---")
    val systemInfo = SystemInfo(context)
    println("Available Memory: ${systemInfo.getAvailableMemory() / (1024 * 1024)} MB")
    println("Total Memory: ${systemInfo.getTotalMemory() / (1024 * 1024)} MB")
    println("CPU Cores: ${systemInfo.getCpuCores()}")
    println("Low Memory: ${systemInfo.isLowMemory()}")
    println("Available Storage: ${systemInfo.getAvailableInternalStorage() / (1024 * 1024 * 1024)} GB")
    println("Total Storage: ${systemInfo.getTotalInternalStorage() / (1024 * 1024 * 1024)} GB")

    // 5. Battery information
    println("\n--- 5. Battery Information ---")
    val batteryInfo = BatteryInfo(context)
    println("Battery Level: ${batteryInfo.getBatteryLevel()}%")
    println("Is Charging: ${batteryInfo.isCharging()}")
    println("Charging Status: ${batteryInfo.getChargingStatus()}")
    println("Battery Health: ${batteryInfo.getBatteryHealth()}")

    // 6. Telephony information
    println("\n--- 6. Telephony Information ---")
    val telephonyInfo = TelephonyInfo(context)
    println("SIM Operator: ${telephonyInfo.getSimOperatorName()}")
    println("Network Operator: ${telephonyInfo.getNetworkOperatorName()}")
    println("Network Type: ${telephonyInfo.getNetworkType()}")
    println("Phone Type: ${telephonyInfo.getPhoneType()}")
    println("SIM Ready: ${telephonyInfo.isSimReady()}")

    println("\n=== All Device Information Examples Completed ===")
}

💻 Control de Vibración kotlin

🟢 simple ⭐⭐

Controlar la vibración del dispositivo con patrones, amplitudes y efectos personalizados

⏱️ 20 min 🏷️ kotlin, android, vibration, hardware
Prerequisites: Basic Kotlin, VIBRATE permission
// Android Kotlin Vibration Control Examples
// Using android.os.Vibrator and android.os.VibrationEffect

import android.content.Context
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager
import android.annotation.SuppressLint

// 1. Basic Vibration
class BasicVibration(private val context: Context) {

    private val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        @Suppress("DEPRECATION")
        context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    }

    // Check if device has vibrator
    fun hasVibrator(): Boolean {
        return vibrator.hasVibrator()
    }

    // Vibrate for specified duration
    @SuppressLint("MissingPermission")
    fun vibrate(milliseconds: Long) {
        if (hasVibrator()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                vibrator.vibrate(VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE))
            } else {
                @Suppress("DEPRECATION")
                vibrator.vibrate(milliseconds)
            }
        }
    }

    // Vibrate with custom amplitude
    @SuppressLint("MissingPermission")
    fun vibrateWithAmplitude(milliseconds: Long, amplitude: Int) {
        if (hasVibrator() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            vibrator.vibrate(VibrationEffect.createOneShot(milliseconds, amplitude))
        }
    }

    // Stop vibration
    fun stopVibration() {
        vibrator.cancel()
    }
}

// 2. Pattern Vibration
class PatternVibration(private val context: Context) {

    private val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        @Suppress("DEPRECATION")
        context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    }

    // Vibrate with pattern
    // Pattern format: [wait, vibrate, wait, vibrate, ...]
    @SuppressLint("MissingPermission")
    fun vibratePattern(pattern: LongArray, repeat: Int = -1) {
        if (hasVibrator()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val effect = VibrationEffect.createWaveform(pattern, repeat)
                vibrator.vibrate(effect)
            } else {
                @Suppress("DEPRECATION")
                vibrator.vibrate(pattern, repeat)
            }
        }
    }

    // Single beep pattern
    @SuppressLint("MissingPermission")
    fun beep() {
        val pattern = longArrayOf(0, 100, 0, 0)
        vibratePattern(pattern)
    }

    // Double beep pattern
    @SuppressLint("MissingPermission")
    fun doubleBeep() {
        val pattern = longArrayOf(0, 100, 100, 100, 0, 0)
        vibratePattern(pattern)
    }

    // Triple beep pattern
    @SuppressLint("MissingPermission")
    fun tripleBeep() {
        val pattern = longArrayOf(0, 100, 100, 100, 100, 100, 0, 0)
        vibratePattern(pattern)
    }

    // SOS pattern (... --- ...)
    @SuppressLint("MissingPermission")
    fun sos() {
        val pattern = longArrayOf(
            0, 100, 100, 100, 100, 100, 200,  // ...
            200, 300, 100, 300, 100, 300, 200,  // ---
            200, 100, 100, 100, 100, 100, 0  // ...
        )
        vibratePattern(pattern)
    }

    // Heartbeat pattern
    @SuppressLint("MissingPermission")
    fun heartbeat() {
        val pattern = longArrayOf(0, 50, 150, 50, 500, 0, 0)
        vibratePattern(pattern, 0) // Repeat
    }

    // Tick-tock pattern
    @SuppressLint("MissingPermission")
    fun tickTock() {
        val pattern = longArrayOf(0, 50, 200, 100, 0, 0)
        vibratePattern(pattern, 0) // Repeat
    }

    // Ascending pattern
    @SuppressLint("MissingPermission")
    fun ascending() {
        val pattern = longArrayOf(0, 50, 50, 100, 50, 150, 50, 200, 0, 0)
        vibratePattern(pattern)
    }

    // Descending pattern
    @SuppressLint("MissingPermission")
    fun descending() {
        val pattern = longArrayOf(0, 200, 50, 150, 50, 100, 50, 50, 0, 0)
        vibratePattern(pattern)
    }

    // Check if device has vibrator
    private fun hasVibrator(): Boolean {
        return vibrator.hasVibrator()
    }

    // Stop vibration
    fun stopVibration() {
        vibrator.cancel()
    }
}

// 3. Predefined Vibration Effects (API 26+)
class PredefinedVibrationEffects(private val context: Context) {

    private val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        @Suppress("DEPRECATION")
        context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    }

    // Click effect
    @SuppressLint("MissingPermission")
    fun click() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
        }
    }

    // Double click effect
    @SuppressLint("MissingPermission")
    fun doubleClick() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK))
        }
    }

    // Tick effect
    @SuppressLint("MissingPermission")
    fun tick() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
        }

    // Heavy click effect
    @SuppressLint("MissingPermission")
    fun heavyClick() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK))
        }
    }

    // Pop effect
    @SuppressLint("MissingPermission")
    fun pop() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_POP))
        }
    }

    // Thud effect
    @SuppressLint("MissingPermission")
    fun thud() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_THUD))
        }
    }

    private fun hasVibrator(): Boolean {
        return vibrator.hasVibrator()
    }
}

// 4. Amplitude-Based Vibration (API 26+)
class AmplitudeVibration(private val context: Context) {

    private val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        @Suppress("DEPRECATION")
        context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    }

    // Vibrate with amplitude pattern
    // Timings: duration of each vibration/pause
    // Amplitudes: intensity for each timing (0-255)
    @SuppressLint("MissingPermission")
    fun vibrateWithAmplitudes(timings: LongArray, amplitudes: IntArray, repeat: Int = -1) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            val effect = VibrationEffect.createWaveform(timings, amplitudes, repeat)
            vibrator.vibrate(effect)
        }
    }

    // Gentle vibration
    @SuppressLint("MissingPermission")
    fun gentleVibration() {
        val timings = longArrayOf(0, 200, 0, 0)
        val amplitudes = intArrayOf(0, 64, 0, 0)
        vibrateWithAmplitudes(timings, amplitudes)
    }

    // Medium vibration
    @SuppressLint("MissingPermission")
    fun mediumVibration() {
        val timings = longArrayOf(0, 200, 0, 0)
        val amplitudes = intArrayOf(0, 128, 0, 0)
        vibrateWithAmplitudes(timings, amplitudes)
    }

    // Strong vibration
    @SuppressLint("MissingPermission")
    fun strongVibration() {
        val timings = longArrayOf(0, 200, 0, 0)
        val amplitudes = intArrayOf(0, 255, 0, 0)
        vibrateWithAmplitudes(timings, amplitudes)
    }

    // Fade in vibration
    @SuppressLint("MissingPermission")
    fun fadeInVibration() {
        val timings = longArrayOf(0, 50, 50, 50, 50, 50, 50, 50, 0, 0)
        val amplitudes = intArrayOf(0, 50, 100, 150, 200, 255, 0, 0)
        vibrateWithAmplitudes(timings, amplitudes)
    }

    // Fade out vibration
    @SuppressLint("MissingPermission")
    fun fadeOutVibration() {
        val timings = longArrayOf(0, 50, 50, 50, 50, 50, 50, 50, 0, 0)
        val amplitudes = intArrayOf(0, 255, 200, 150, 100, 50, 0, 0)
        vibrateWithAmplitudes(timings, amplitudes)
    }

    // Ramp pattern (gentle to strong to gentle)
    @SuppressLint("MissingPermission")
    fun rampPattern() {
        val timings = longArrayOf(0, 100, 50, 100, 50, 100, 50, 100, 0, 0)
        val amplitudes = intArrayOf(0, 80, 120, 160, 200, 160, 120, 80, 0, 0)
        vibrateWithAmplitudes(timings, amplitudes)
    }

    private fun hasVibrator(): Boolean {
        return vibrator.hasVibrator()
    }
}

// 5. Notification Vibration Patterns
class NotificationVibrations(private val context: Context) {

    private val patternVibration = PatternVibration(context)

    // Success vibration
    @SuppressLint("MissingPermission")
    fun success() {
        patternVibration.vibratePattern(longArrayOf(0, 50, 100, 50, 0, 0))
    }

    // Error vibration
    @SuppressLint("MissingPermission")
    fun error() {
        patternVibration.vibratePattern(longArrayOf(0, 100, 50, 100, 50, 200, 0, 0))
    }

    // Warning vibration
    @SuppressLint("MissingPermission")
    fun warning() {
        patternVibration.vibratePattern(longArrayOf(0, 150, 100, 0, 0))
    }

    // Message received vibration
    @SuppressLint("MissingPermission")
    fun messageReceived() {
        patternVibration.vibratePattern(longArrayOf(0, 50, 150, 50, 0, 0))
    }

    // Call vibration
    @SuppressLint("MissingPermission")
    fun call() {
        val pattern = longArrayOf(0, 600, 400, 600, 0, 0)
        patternVibration.vibratePattern(pattern, 1) // Repeat
    }

    // Alarm vibration
    @SuppressLint("MissingPermission")
    fun alarm() {
        val pattern = longArrayOf(0, 500, 200, 500, 200, 500, 0, 0)
        patternVibration.vibratePattern(pattern, 1) // Repeat
    }
}

// 6. Haptic Feedback (API 26+)
class HapticFeedback(private val context: Context) {

    private val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
        vibratorManager.defaultVibrator
    } else {
        @Suppress("DEPRECATION")
        context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
    }

    // Virtual key press
    @SuppressLint("MissingPermission")
    fun virtualKeyPress() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
        }
    }

    // Long press
    @SuppressLint("MissingPermission")
    fun longPress() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
        }
    }

    // Text entry
    @SuppressLint("MissingPermission")
    fun textEntry() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasVibrator()) {
            vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
        }
    }

    private fun hasVibrator(): Boolean {
        return vibrator.hasVibrator()
    }
}

// 7. Vibration Controller
class VibrationController(private val context: Context) {

    private val basicVibration = BasicVibration(context)
    private val patternVibration = PatternVibration(context)
    private val predefinedEffects = PredefinedVibrationEffects(context)
    private val amplitudeVibration = AmplitudeVibration(context)
    private val notificationVibrations = NotificationVibrations(context)

    // Stop all vibrations
    fun stopAll() {
        basicVibration.stopVibration()
    }

    // Test vibration intensity
    @SuppressLint("MissingPermission")
    fun testIntensity(level: Int) {
        val amplitude = when (level) {
            1 -> 64
            2 -> 128
            3 -> 192
            4 -> 255
            else -> 128
        }
        basicVibration.vibrateWithAmplitude(200, amplitude)
    }

    // Vibrate for notification type
    @SuppressLint("MissingPermission")
    fun notify(type: String) {
        when (type) {
            "success" -> notificationVibrations.success()
            "error" -> notificationVibrations.error()
            "warning" -> notificationVibrations.warning()
            "message" -> notificationVibrations.messageReceived()
            "call" -> notificationVibrations.call()
            "alarm" -> notificationVibrations.alarm()
        }
    }
}

// Main demonstration
fun demonstrateVibrationControl(context: Context) {
    println("=== Android Kotlin Vibration Control Examples ===\n")

    // 1. Basic vibration
    println("--- 1. Basic Vibration ---")
    val basicVibration = BasicVibration(context)
    println("Has Vibrator: ${basicVibration.hasVibrator()}")
    println("Vibrate for 200ms:")
    // basicVibration.vibrate(200) // Uncomment to test

    println("\nVibrate with amplitude:")
    // basicVibration.vibrateWithAmplitude(200, 128) // Uncomment to test

    // 2. Pattern vibration
    println("\n--- 2. Pattern Vibration ---")
    val patternVibration = PatternVibration(context)
    println("Available patterns:")
    println("  - beep()")
    println("  - doubleBeep()")
    println("  - tripleBeep()")
    println("  - sos()")
    println("  - heartbeat()")
    println("  - tickTock()")
    println("  - ascending()")
    println("  - descending()")

    // 3. Predefined effects
    println("\n--- 3. Predefined Effects ---")
    val predefinedEffects = PredefinedVibrationEffects(context)
    println("Available predefined effects:")
    println("  - click()")
    println("  - doubleClick()")
    println("  - tick()")
    println("  - heavyClick()")
    println("  - pop()")
    println("  - thud()")

    // 4. Amplitude-based vibration
    println("\n--- 4. Amplitude-Based Vibration ---")
    val amplitudeVibration = AmplitudeVibration(context)
    println("Available amplitude patterns:")
    println("  - gentleVibration()")
    println("  - mediumVibration()")
    println("  - strongVibration()")
    println("  - fadeInVibration()")
    println("  - fadeOutVibration()")
    println("  - rampPattern()")

    // 5. Notification vibrations
    println("\n--- 5. Notification Vibrations ---")
    val notificationVibrations = NotificationVibrations(context)
    println("Available notification patterns:")
    println("  - success()")
    println("  - error()")
    println("  - warning()")
    println("  - messageReceived()")
    println("  - call()")
    println("  - alarm()")

    // 6. Haptic feedback
    println("\n--- 6. Haptic Feedback ---")
    val hapticFeedback = HapticFeedback(context)
    println("Available haptic feedback:")
    println("  - virtualKeyPress()")
    println("  - longPress()")
    println("  - textEntry()")

    // 7. Controller
    println("\n--- 7. Vibration Controller ---")
    val controller = VibrationController(context)
    println("Controller methods:")
    println("  - stopAll(): Stop all vibrations")
    println("  - testIntensity(level): Test vibration (1-4)")
    println("  - notify(type): Vibrate for notification type")

    println("\n=== All Vibration Control Examples Completed ===")
}

💻 Estado de la Red kotlin

🟡 intermediate ⭐⭐⭐⭐

Verificar conectividad de red, tipo de conexión y monitorear cambios de red

⏱️ 30 min 🏷️ kotlin, android, network, connectivity
Prerequisites: Intermediate Kotlin, Android permissions
// Android Kotlin Network Status Examples
// Using android.net.ConnectivityManager, NetworkInfo, and NetworkRequest

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkInfo
import android.net.NetworkRequest
import android.os.Build
import android.telephony.TelephonyManager

// 1. Basic Network Connectivity
class NetworkConnectivity(private val context: Context) {

    private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    // Check if network is available
    fun isNetworkAvailable(): Boolean {
        val networkInfo = connectivityManager.activeNetworkInfo
        return networkInfo != null && networkInfo.isConnected
    }

    // Check if WiFi is connected
    fun isWifiConnected(): Boolean {
        val networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
        return networkInfo?.isConnected == true
    }

    // Check if mobile network is connected
    fun isMobileConnected(): Boolean {
        val networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
        return networkInfo?.isConnected == true
    }

    // Check if device is roaming
    fun isRoaming(): Boolean {
        val networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
        return networkInfo?.isRoaming == true
    }
}

// 2. Network Type Detection (API 21+)
class NetworkTypeDetector(private val context: Context) {

    private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    // Get network type (WiFi, Mobile, Ethernet, etc.)
    fun getNetworkType(): String {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork ?: return "none"
            val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return "unknown"

            return when {
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> "wifi"
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> "cellular"
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> "ethernet"
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> "bluetooth"
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> "vpn"
                else -> "unknown"
            }
        } else {
            @Suppress("DEPRECATION")
            val networkInfo = connectivityManager.activeNetworkInfo
            return when (networkInfo?.type) {
                ConnectivityManager.TYPE_WIFI -> "wifi"
                ConnectivityManager.TYPE_MOBILE -> "cellular"
                ConnectivityManager.TYPE_ETHERNET -> "ethernet"
                ConnectivityManager.TYPE_BLUETOOTH -> "bluetooth"
                ConnectivityManager.TYPE_VPN -> "vpn"
                else -> "unknown"
            }
        }
    }

    // Check if network is metered
    fun isMeteredNetwork(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork ?: return false
            connectivityManager.isActiveNetworkMetered(network)
        } else {
            connectivityManager.isActiveNetworkMetered
        }
    }

    // Check if network is high bandwidth
    fun isHighBandwidth(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork ?: return false
            val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
            return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) ||
                   capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
        }
        return false
    }

    // Get connection speed
    fun getConnectionSpeed(): String {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork ?: return "unknown"
            val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return "unknown"
            val downBandwidth = capabilities.linkDownstreamBandwidthKbps
            val upBandwidth = capabilities.linkUpstreamBandwidthKbps
            return "Down: ${downBandwidth}Kbps, Up: ${upBandwidth}Kbps"
        }
        return "unknown"
    }
}

// 3. Mobile Network Details
class MobileNetworkDetails(private val context: Context) {

    private val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager

    // Get mobile network type (2G, 3G, 4G, 5G)
    fun getMobileNetworkType(): String {
        return try {
            when (telephonyManager.networkType) {
                TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE,
                TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT,
                TelephonyManager.NETWORK_TYPE_IDEN -> "2G"
                TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_EVDO_0,
                TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_HSDPA,
                TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_HSPA,
                TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyManager.NETWORK_TYPE_EHRPD,
                TelephonyManager.NETWORK_TYPE_HSPAP -> "3G"
                TelephonyManager.NETWORK_TYPE_LTE -> "4G"
                TelephonyManager.NETWORK_TYPE_NR -> "5G"
                TelephonyManager.NETWORK_TYPE_UNKNOWN -> "unknown"
                else -> "unknown"
            }
        } catch (e: SecurityException) {
            "permission denied"
        }
    }

    // Get data state
    fun getDataState(): String {
        return try {
            when (telephonyManager.dataState) {
                TelephonyManager.DATA_DISCONNECTED -> "disconnected"
                TelephonyManager.DATA_CONNECTING -> "connecting"
                TelephonyManager.DATA_CONNECTED -> "connected"
                TelephonyManager.DATA_SUSPENDED -> "suspended"
                else -> "unknown"
            }
        } catch (e: SecurityException) {
            "permission denied"
        }
    }

    // Get SIM state
    fun getSimState(): String {
        return try {
            when (telephonyManager.simState) {
                TelephonyManager.SIM_STATE_ABSENT -> "absent"
                TelephonyManager.SIM_STATE_NETWORK_LOCKED -> "network locked"
                TelephonyManager.SIM_STATE_PIN_REQUIRED -> "pin required"
                TelephonyManager.SIM_STATE_PUK_REQUIRED -> "puk required"
                TelephonyManager.SIM_STATE_READY -> "ready"
                TelephonyManager.SIM_STATE_UNKNOWN -> "unknown"
                else -> "unknown"
            }
        } catch (e: SecurityException) {
            "permission denied"
        }
    }
}

// 4. Network Capabilities Checker (API 21+)
class NetworkCapabilitiesChecker(private val context: Context) {

    private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

    // Check if network is validated (has internet access)
    fun hasInternetAccess(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork ?: return false
            val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
            return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                   capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
        }
        return connectivityManager.activeNetworkInfo?.isConnected == true
    }

    // Check if network supports VPN
    fun supportsVPN(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork ?: return false
            val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
            return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)
        }
        return false
    }

    // Check if network is congested
    fun isNetworkCongested(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork ?: return false
            val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
            return !capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED)
        }
        return false
    }
}

// 5. Network State Listener
class NetworkStateListener(private val context: Context) {

    private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    private var networkCallback: ConnectivityManager.NetworkCallback? = null

    // Start monitoring network changes
    fun startNetworkMonitoring(onNetworkChanged: (Boolean, String) -> Unit) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            val request = NetworkRequest.Builder()
                .build()

            networkCallback = object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    val capabilities = connectivityManager.getNetworkCapabilities(network)
                    val type = when {
                        capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true -> "wifi"
                        capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> "cellular"
                        capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) == true -> "ethernet"
                        else -> "unknown"
                    }
                    onNetworkChanged(true, type)
                }

                override fun onLost(network: Network) {
                    onNetworkChanged(false, "none")
                }
            }

            connectivityManager.registerDefaultNetworkCallback(networkCallback as ConnectivityManager.NetworkCallback)
        }
    }

    // Stop monitoring network changes
    fun stopNetworkMonitoring() {
        networkCallback?.let {
            connectivityManager.unregisterNetworkCallback(it)
        }
        networkCallback = null
    }
}

// 6. Network Quality Estimator
class NetworkQualityEstimator(private val context: Context) {

    // Estimate network quality based on type and bandwidth
    fun estimateNetworkQuality(): String {
        val detector = NetworkTypeDetector(context)
        val type = detector.getNetworkType()
        val bandwidth = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetwork
            val capabilities = network?.let {
                (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).getNetworkCapabilities(it)
            }
            capabilities?.linkDownstreamBandwidthKbps ?: 0
        } else {
            0
        }

        return when {
            type == "wifi" && bandwidth > 10_000 -> "excellent"
            type == "wifi" -> "good"
            type == "cellular" -> {
                val mobileType = MobileNetworkDetails(context).getMobileNetworkType()
                when (mobileType) {
                    "5G", "4G" -> "good"
                    "3G" -> "fair"
                    else -> "poor"
                }
            }
            type == "ethernet" -> "excellent"
            else -> "unknown"
        }
    }

    // Get recommended action based on quality
    fun getRecommendedAction(): String {
        val quality = estimateNetworkQuality()
        return when (quality) {
            "excellent" -> "Can stream HD video and download large files"
            "good" -> "Can stream video and download files"
            "fair" -> "Suitable for browsing and light streaming"
            "poor" -> "Only basic browsing recommended"
            else -> "Network not available"
        }
    }
}

// 7. Network Utils
class NetworkUtils(private val context: Context) {

    // Check if should use WiFi for large downloads
    fun shouldUseWifiForDownload(): Boolean {
        val detector = NetworkTypeDetector(context)
        return detector.isMeteredNetwork().not() && detector.getNetworkType() == "wifi"
    }

    // Check if can make network request
    fun canMakeRequest(): Boolean {
        val connectivity = NetworkConnectivity(context)
        return connectivity.isNetworkAvailable()
    }

    // Get network info summary
    fun getNetworkSummary(): Map<String, Any> {
        val connectivity = NetworkConnectivity(context)
        val detector = NetworkTypeDetector(context)
        val quality = NetworkQualityEstimator(context)

        return mapOf(
            "available" to connectivity.isNetworkAvailable(),
            "type" to detector.getNetworkType(),
            "metered" to detector.isMeteredNetwork(),
            "quality" to quality.estimateNetworkQuality(),
            "wifi" to connectivity.isWifiConnected(),
            "mobile" to connectivity.isMobileConnected()
        )
    }
}

// Main demonstration
fun demonstrateNetworkStatus(context: Context) {
    println("=== Android Kotlin Network Status Examples ===\n")

    // 1. Basic connectivity
    println("--- 1. Basic Network Connectivity ---")
    val connectivity = NetworkConnectivity(context)
    println("Network Available: ${connectivity.isNetworkAvailable()}")
    println("WiFi Connected: ${connectivity.isWifiConnected()}")
    println("Mobile Connected: ${connectivity.isMobileConnected()}")
    println("Is Roaming: ${connectivity.isRoaming()}")

    // 2. Network type
    println("\n--- 2. Network Type Detection ---")
    val typeDetector = NetworkTypeDetector(context)
    println("Network Type: ${typeDetector.getNetworkType()}")
    println("Is Metered: ${typeDetector.isMeteredNetwork()}")
    println("Is High Bandwidth: ${typeDetector.isHighBandwidth()}")
    println("Connection Speed: ${typeDetector.getConnectionSpeed()}")

    // 3. Mobile network details
    println("\n--- 3. Mobile Network Details ---")
    val mobileDetails = MobileNetworkDetails(context)
    println("Mobile Network Type: ${mobileDetails.getMobileNetworkType()}")
    println("Data State: ${mobileDetails.getDataState()}")
    println("SIM State: ${mobileDetails.getSimState()}")

    // 4. Network capabilities
    println("\n--- 4. Network Capabilities ---")
    val capabilitiesChecker = NetworkCapabilitiesChecker(context)
    println("Has Internet: ${capabilitiesChecker.hasInternetAccess()}")
    println("Supports VPN: ${capabilitiesChecker.supportsVPN()}")
    println("Is Congested: ${capabilitiesChecker.isNetworkCongested()}")

    // 5. Network quality
    println("\n--- 5. Network Quality ---")
    val qualityEstimator = NetworkQualityEstimator(context)
    println("Network Quality: ${qualityEstimator.estimateNetworkQuality()}")
    println("Recommendation: ${qualityEstimator.getRecommendedAction()}")

    // 6. Network summary
    println("\n--- 6. Network Summary ---")
    val utils = NetworkUtils(context)
    val summary = utils.getNetworkSummary()
    summary.forEach { (key, value) -> println("$key: $value") }

    // Note: Network listener requires lifecycle management
    println("\n--- 7. Network Monitoring ---")
    println("Network monitoring methods:")
    println("  - startNetworkMonitoring(): Monitor network changes")
    println("  - stopNetworkMonitoring(): Stop monitoring")

    println("\n=== All Network Status Examples Completed ===")
}