Hello! 🌙
How are you feeling right now?

Cycle Calendar

Track, predict, and understand your cycle

🔴 Period◯ Predicted● Fertile● Today

📅 Log Period Date

Mood Vault

Track 25 emotions — privately, daily

How are you feeling today?

Mood History

Daily Journal

Your safe space — 100% private

Past Entries

Relief Vault

Yoga & Desi Nuskhe — 60+ natural remedies

Diet & BMI

Nutrition, BMI tracking & cycle-based diet

BMI Calculator

🥗 Period Nutrition Guide

Hormone Guide

Understand your hormonal cycle

Sleep Care

Better sleep during your cycle

Music & Podcasts

60+ Warrior Songs · 60+ Empowerment Podcasts · 60+ Period Comfort Songs · 60+ Period Tips

Finance & Grants

Women's investing guide + Government grants & business schemes

🔴 SOS ACTIVE — Sending live location via SMS every ~60 sec  |  Tap to Deactivate
🆘 SOS ACTIVATING
3
Release button to cancel immediately
🔐 Deactivate SOS
Enter your 4-digit PIN to stop all alerts
❌ Wrong PIN. Try again.
🔐 Set Security PIN
Choose a 4-digit PIN to deactivate SOS.
Don't forget it — it protects you in emergencies.
⚠️ Please enter all 4 digits.

Guardian Shield

Emergency protection and trusted-contact location sharing

Your safety tools are ready

Hold the SOS button for three seconds to start sharing your live location with approved guardians. A PIN protects deactivation.

📍 Live location
Updates while SOS is active
🛡️ Guardian access
Approval required before sharing
🔐 PIN control
Stops accidental deactivation
Open Guardian Portal →

🛡️ Add and verify guardians

Generate a one-time code and send it only to someone you trust. You remain in control: requests stay pending until approved, and access can be revoked here.

The code expires after 24 hours and can be redeemed once. The recipient can redeem it in the Guardian Portal.

No guardians invited yet.

Android Immortal Engine

Foreground Service · WakeLock · Boot Receiver · Battery Bypass — Complete Implementation

⚠️ AndroidManifest.xml Permissions Required:
All 4 components below are required to work. Add these permissions and declarations to your AndroidManifest.xml file. Each tab contains complete, copy-ready Kotlin code.

🗂️ File Structure — Which files to create

1GuardianForegroundService.kt — Main service (Sticky + WakeLock)
2BootReceiver.kt — Auto-restart on reboot & app update
3BatteryOptimizationHelper.kt — Doze Mode bypass prompt
4AndroidManifest.xml — Saari permissions & component registrations

🔧 GuardianForegroundService — What does this do?

  • START_STICKY — If the system kills the service, Android automatically restarts it
  • PARTIAL_WAKE_LOCK — CPU stays active even after screen turns off — GPS/SMS continues running during SOS trigger
  • PRIORITY_MAX + FLAG_ONGOING_EVENT — User cannot dismiss the notification (non-dismissible)
  • WakeLock is acquired only when SOS is active, and released on deactivation — battery safe
GuardianForegroundService.kt Kotlin
package com.lunacare.app.service

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import androidx.core.app.NotificationCompat
import com.lunacare.app.MainActivity
import com.lunacare.app.R

class GuardianForegroundService : Service() {

    // ── WakeLock reference (keeps CPU awake)
    private var wakeLock: PowerManager.WakeLock? = null

    // ── Notification Channel ID
    private val CHANNEL_ID   = "lunacare_guardian_channel"
    private val NOTIFICATION_ID = 1001

    // ════════════════════════════════════════
    //  onCreate — Service pehli baar create
    // ════════════════════════════════════════
    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()   // Android 8+ requires channel
        startForeground(
            NOTIFICATION_ID,
            buildGuardianNotification()   // Non-dismissible high-priority notification
        )
        acquireWakeLock()   // CPU lock — stays active even when screen is off
    }

    // ════════════════════════════════════════
    //  onStartCommand — START_STICKY → system restart karega
    // ════════════════════════════════════════
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // Handle SOS trigger / deactivate actions via Intent extras
        when (intent?.action) {
            ACTION_SOS_ACTIVATE   -> handleSosActivate()
            ACTION_SOS_DEACTIVATE -> handleSosDeactivate()
        }
        // START_STICKY: restarts with Intent=null after service is killed
        return START_STICKY
    }

    // ════════════════════════════════════════
    //  onBind — Not a bound service
    // ════════════════════════════════════════
    override fun onBind(intent: Intent?): IBinder? = null

    // ════════════════════════════════════════
    //  onDestroy — Release WakeLock
    // ════════════════════════════════════════
    override fun onDestroy() {
        releaseWakeLock()
        super.onDestroy()
    }

    // ════════════════════════════════════════
    //  SOS Activate — WakeLock acquire
    // ════════════════════════════════════════
    private fun handleSosActivate() {
        acquireWakeLock()
        // TODO: Start your GPS tracking / SMS loop here
        updateNotification(
            title   = "🆘 SOS ACTIVE — LunaCare Guardian",
            message = "Emergency mode active. Location updating every 4.5 min."
        )
    }

    // ════════════════════════════════════════
    //  SOS Deactivate — WakeLock release
    // ════════════════════════════════════════
    private fun handleSosDeactivate() {
        releaseWakeLock()
        // TODO: Stop GPS loop / SMS here
        updateNotification(
            title   = "🛡️ LunaCare Guardian Active",
            message = "Monitoring in background. Tap to open."
        )
    }

    // ════════════════════════════════════════
    //  WAKELOCK — PARTIAL_WAKE_LOCK
    //  Keep CPU running even when screen turns off
    // ════════════════════════════════════════
    private fun acquireWakeLock() {
        if (wakeLock?.isHeld == true) return   // Already holding, skip
        val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            "LunaCare::GuardianWakeLock"
        ).apply {
            // Timeout: 30 minutes max to prevent indefinite drain
            // Must re-acquire when SOS becomes active
            acquire(30 * 60 * 1000L)
        }
    }

    private fun releaseWakeLock() {
        if (wakeLock?.isHeld == true) {
            wakeLock?.release()
        }
        wakeLock = null
    }

    // ════════════════════════════════════════
    //  NOTIFICATION — Non-dismissible, PRIORITY_MAX
    // ════════════════════════════════════════
    private fun buildGuardianNotification(
        title:   String = "🛡️ LunaCare Guardian Active",
        message: String = "Monitoring in background. Tap to open."
    ): Notification {
        // Tapping notification → open MainActivity
        val tapIntent = PendingIntent.getActivity(
            this,
            0,
            Intent(this, MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
            },
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(title)
            .setContentText(message)
            .setSmallIcon(R.drawable.ic_luna_shield)   // Apna icon rakho
            .setContentIntent(tapIntent)
            .setPriority(NotificationCompat.PRIORITY_MAX)   // Highest priority
            .setCategory(NotificationCompat.CATEGORY_SERVICE)
            .setOngoing(true)           // Non-dismissible (FLAG_ONGOING_EVENT)
            .setShowWhen(false)         // No timestamp clutter
            .setAutoCancel(false)       // User cannot dismiss this notification
            .build()
    }

    private fun updateNotification(title: String, message: String) {
        val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        nm.notify(NOTIFICATION_ID, buildGuardianNotification(title, message))
    }

    // ════════════════════════════════════════
    //  NOTIFICATION CHANNEL — Android 8+ required
    // ════════════════════════════════════════
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "LunaCare Guardian Service",
                NotificationManager.IMPORTANCE_HIGH   // Heads-up notification
            ).apply {
                description     = "Keeps LunaCare SOS running in background"
                setShowBadge(false)
                lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            }
            val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            nm.createNotificationChannel(channel)
        }
    }

    // ════════════════════════════════════════
    //  COMPANION OBJECT — Intent Actions &
    //  Helper to start/stop service safely
    // ════════════════════════════════════════
    companion object {
        const val ACTION_SOS_ACTIVATE   = "com.lunacare.SOS_ACTIVATE"
        const val ACTION_SOS_DEACTIVATE = "com.lunacare.SOS_DEACTIVATE"

        /** Call this from Activity/Fragment to start Guardian service */
        fun startGuardian(context: Context) {
            val intent = Intent(context, GuardianForegroundService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)   // Android 8+ requires this
            } else {
                context.startService(intent)
            }
        }

        /** Trigger SOS mode */
        fun triggerSOS(context: Context) {
            val intent = Intent(context, GuardianForegroundService::class.java)
                .apply { action = ACTION_SOS_ACTIVATE }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
        }

        /** Deactivate SOS mode */
        fun deactivateSOS(context: Context) {
            val intent = Intent(context, GuardianForegroundService::class.java)
                .apply { action = ACTION_SOS_DEACTIVATE }
            context.startService(intent)
        }
    }
}

🔄 BootReceiver — What does this do?

  • ACTION_BOOT_COMPLETED — Service automatically restarts after phone reboot
  • ACTION_MY_PACKAGE_REPLACED — Service restarts after app update installation — user does not need to open the app manually
  • Both broadcasts are handled by a single receiver — clean & minimal
  • Add android:directBootAware="true" to the Manifest so it works during encrypted boot as well kare (Android 7+)
BootReceiver.kt Kotlin
package com.lunacare.app.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import com.lunacare.app.service.GuardianForegroundService

class BootReceiver : BroadcastReceiver() {

    // ════════════════════════════════════════
    //  onReceive — Boot ya App-Replace broadcast
    // ════════════════════════════════════════
    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action ?: return
        Log.d("BootReceiver", "Received broadcast: $action")

        when (action) {
            // ── Phone reboot complete ──
            Intent.ACTION_BOOT_COMPLETED,
            // ── Encrypted boot complete (Android 7+) ──
            "android.intent.action.LOCKED_BOOT_COMPLETED",
            // ── App update installed ──
            Intent.ACTION_MY_PACKAGE_REPLACED -> {
                startGuardianService(context)
            }
        }
    }

    // ════════════════════════════════════════
    //  Start Guardian Foreground Service
    // ════════════════════════════════════════
    private fun startGuardianService(context: Context) {
        try {
            val serviceIntent = Intent(context, GuardianForegroundService::class.java)

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                // Android 8+ — startForegroundService() is REQUIRED
                // Warna Android "Context.startForegroundService() did not call
                // Service.startForeground()" ANR dega
                context.startForegroundService(serviceIntent)
            } else {
                context.startService(serviceIntent)
            }

            Log.d("BootReceiver", "GuardianForegroundService started successfully.")

        } catch (e: Exception) {
            // Background service restriction (Android 12+) ya permission missing
            Log.e("BootReceiver", "Failed to start service: ${e.message}")
        }
    }
}

🔋 BatteryOptimizationHelper — What does this do?

  • Android's Doze Mode can put background apps to sleep — GPS & SMS may stop jaata hai
  • This helper takes the user to system settings where they can exempt the app from battery optimization se exempt kar sakti hai
  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission se direct dialog bhi trigger ho sakta hai
  • Show this prompt during onboarding or SOS setup — once allowed, it will not ask again
BatteryOptimizationHelper.kt Kotlin
package com.lunacare.app.util

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.appcompat.app.AlertDialog

object BatteryOptimizationHelper {

    // ════════════════════════════════════════
    //  Check: Is the app already exempt?
    // ════════════════════════════════════════
    fun isIgnoringBatteryOptimizations(context: Context): Boolean {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true  // Pre-M: no Doze mode
        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        return pm.isIgnoringBatteryOptimizations(context.packageName)
    }

    // ════════════════════════════════════════
    //  Method 1: Direct System Dialog
    //  (ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
    //  Note: REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission
    //  is REQUIRED in Manifest
    // ════════════════════════════════════════
    @SuppressLint("BatteryLife")
    fun requestDirectExemption(activity: Activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return
        if (isIgnoringBatteryOptimizations(activity)) return  // Already exempt

        val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
            data = Uri.parse("package:${activity.packageName}")
        }
        try {
            activity.startActivity(intent)
        } catch (e: Exception) {
            // Some devices crash here — fallback to settings page
            openBatterySettings(activity)
        }
    }

    // ════════════════════════════════════════
    //  Method 2: App-specific battery settings
    //  (Most reliable — user manually toggles)
    // ════════════════════════════════════════
    fun openBatterySettings(activity: Activity) {
        val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)
        } else {
            Intent(Settings.ACTION_SETTINGS)
        }
        try {
            activity.startActivity(intent)
        } catch (e: Exception) {
            // Absolute fallback
            activity.startActivity(Intent(Settings.ACTION_SETTINGS))
        }
    }

    // ════════════════════════════════════════
    //  Show Explanation Dialog
    //  (Explain to user why it is needed — then ask)
    // ════════════════════════════════════════
    fun showBatteryOptimizationDialog(activity: Activity) {
        if (isIgnoringBatteryOptimizations(activity)) return  // Already done, skip

        AlertDialog.Builder(activity)
            .setTitle("🛡️ Battery Optimization — Disable This")
            .setMessage(
                "LunaCare SOS will only work when the app is running in the background. " +
                "\n\n" +
                "Android's Doze Mode can put the app to sleep, which may " +
                "interrupt GPS and SMS during emergencies.\n\n" +
                "Please set LunaCare to 'Unrestricted' or 'Don't optimize' " +
                "set it to High Accuracy."
            )
            .setPositiveButton("Allow ✅") { _, _ ->
                requestDirectExemption(activity)
            }
            .setNegativeButton("Baad mein") { dialog, _ ->
                dialog.dismiss()
                // Warn user SOS may not work reliably
            }
            .setCancelable(false)  // Non-dismissible dialog
            .show()
    }

    // ════════════════════════════════════════
    //  Call this on SOS Setup or Onboarding
    //  Usage in Activity/Fragment:
    //
    //  BatteryOptimizationHelper.checkAndPrompt(this)
    // ════════════════════════════════════════
    fun checkAndPrompt(activity: Activity) {
        if (!isIgnoringBatteryOptimizations(activity)) {
            showBatteryOptimizationDialog(activity)
        }
    }
}

📋 AndroidManifest.xml — All required entries in one place

  • Add all the <uses-permission> and <service>/<receiver> blocks to your existing Manifest file
  • android:foregroundServiceType="location" — Android 10+ par location wale foreground service ke liye mandatory hai
  • android:exported="false" — BootReceiver ke liye true hona chahiye (system broadcast receive karne ke liye)
  • Replace com.lunacare.app apne actual package name se
AndroidManifest.xml — Required additions XML
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lunacare.app">

    <!-- ══════════════════════════════════════════
         PERMISSIONS — Immortal Engine ke liye required
    ══════════════════════════════════════════ -->

    <!-- Foreground Service permission (Android 9+) -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <!-- Foreground Service type: location (mandatory for Android 10+) -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

    <!-- WakeLock — Keeps CPU active even after screen turns off -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <!-- Boot Receiver — Phone reboot ke baad service restart -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <!-- Battery Optimization bypass prompt -->
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

    <!-- Location permissions (SOS GPS tracking ke liye) -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!-- Background location — GPS continues even when screen is off during active SOS -->
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

    <!-- SMS sending (emergency alert) -->
    <uses-permission android:name="android.permission.SEND_SMS" />

    <!-- Internet (for any online features) -->
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <!-- Main Activity -->
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- ══════════════════════════════════════════
             GUARDIAN FOREGROUND SERVICE
             - android:foregroundServiceType="location" → Required for Android 10+
             - android:stopWithTask="false" → Service won't stop when task is swiped away
        ══════════════════════════════════════════ -->
        <service
            android:name=".service.GuardianForegroundService"
            android:enabled="true"
            android:exported="false"
            android:foregroundServiceType="location"
            android:stopWithTask="false" />

        <!-- ══════════════════════════════════════════
             BOOT RECEIVER
             - Listens to both RECEIVE_BOOT_COMPLETED and MY_PACKAGE_REPLACED
             - android:directBootAware="true" → Works during encrypted boot (Android 7+)
             - android:exported="true" → REQUIRED to receive system broadcasts
        ══════════════════════════════════════════ -->
        <receiver
            android:name=".receiver.BootReceiver"
            android:enabled="true"
            android:exported="true"
            android:directBootAware="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
                <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
            </intent-filter>
        </receiver>

    </application>

</manifest>

🚀 Usage — How to use in Activity

// ── App launch hone par Guardian start karo (e.g. MainActivity.onCreate)
GuardianForegroundService.startGuardian(this)

// ── SOS trigger hone par (3-sec hold ke baad)
GuardianForegroundService.triggerSOS(this)

// ── SOS deactivate hone par (PIN verify ke baad)
GuardianForegroundService.deactivateSOS(this)

// ── Battery optimization bypass (on SOS setup screen or during onboarding)
BatteryOptimizationHelper.checkAndPrompt(this)

📡 LocationTelemetryService — What does this do?

  • FusedLocationProviderClient — Google Play Services best-in-class GPS providerr, jo GPS + WiFi + Cell Tower sab combine karta hai maximum accuracy ke liye
  • PRIORITY_HIGH_ACCURACY — Most precise location, battery optimizedze hoti hai baaki time
  • 20-sec interval / 10-sec fastest interval — Regular updates ke saath urgent data bhi milta hai
  • Zero-Latency Injection — Fires an immediate high-priority request the moment SOS is triggered fix force hoti hai — standard interval wait nahi karna padta
  • Firebase Realtime Database — Every location update is written to /emergency_logs/{uid} node pe push hoti hai with lat, lng, speed, accuracy, serverTimestamp
  • Location Disabled Handling — Shows a dialog to the user to enable High Accuracy GPS if GPS is off
LocationTelemetryService.kt Kotlin
package com.lunacare.app.service

import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.location.LocationManager
import android.os.Looper
import android.provider.Settings
import android.util.Log
import com.google.android.gms.location.*
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ServerValue

/**
 * ══════════════════════════════════════════════════════════════════
 *  LocationTelemetryService — LunaCare High-Precision GPS Telemetry
 * ══════════════════════════════════════════════════════════════════
 *
 *  Use this class inside GuardianForegroundService or
 *  call it as a separate helper class.
 *
 *  Dependencies (add to app/build.gradle):
 *  implementation "com.google.android.gms:play-services-location:21.0.1"
 *  implementation "com.google.firebase:firebase-database-ktx:20.3.0"
 *  implementation "com.google.firebase:firebase-auth-ktx:22.3.0"
 * ══════════════════════════════════════════════════════════════════
 */
class LocationTelemetryService(private val context: Context) {

    companion object {
        private const val TAG = "LocationTelemetry"

        // ── Configuration ──────────────────────────────────────────
        private const val UPDATE_INTERVAL_MS      = 20_000L   // 20 seconds — normal interval
        private const val FASTEST_INTERVAL_MS     = 10_000L   // 10 seconds — fastest allowed
        private const val SOS_IMMEDIATE_TIMEOUT   = 5_000L    // 5 sec max wait for instant fix

        // ── Firebase DB Path ───────────────────────────────────────
        private const val DB_PATH = "emergency_logs"
    }

    // ── FusedLocationProviderClient — Google ka best GPS provider ──
    private val fusedClient: FusedLocationProviderClient =
        LocationServices.getFusedLocationProviderClient(context)

    // ── Firebase References ────────────────────────────────────────
    private val firebaseAuth = FirebaseAuth.getInstance()
    private val firebaseDb   = FirebaseDatabase.getInstance()

    // ── LocationRequest — PRIORITY_HIGH_ACCURACY ───────────────────
    // This config is for regular SOS tracking
    private val locationRequest: LocationRequest = LocationRequest.Builder(
        Priority.PRIORITY_HIGH_ACCURACY,
        UPDATE_INTERVAL_MS
    ).apply {
        setMinUpdateIntervalMillis(FASTEST_INTERVAL_MS)   // Fastest allowed interval: 10 sec
        setWaitForAccurateLocation(true)                  // Wait for first accurate reading
        setMaxUpdateDelayMillis(UPDATE_INTERVAL_MS * 2)   // Max batch delay
    }.build()

    // ── Location Callback — Har update par Firebase push ──────────
    private val locationCallback = object : LocationCallback() {

        override fun onLocationResult(result: LocationResult) {
            result.lastLocation?.let { location ->

                // ── Speed: convert m/s → km/h ─────────────────
                val speedKmh = if (location.hasSpeed()) {
                    (location.speed * 3.6f).toDouble()   // 1 m/s = 3.6 km/h
                } else {
                    0.0
                }

                // ── Telemetry data object ───────────────────────────
                val telemetryData = mapOf(
                    "latitude"        to location.latitude,
                    "longitude"       to location.longitude,
                    "speed_kmh"       to speedKmh,
                    "accuracy_meters" to location.accuracy.toDouble(),
                    "altitude"        to location.altitude,
                    "bearing"         to location.bearing.toDouble(),
                    "provider"        to (location.provider ?: "unknown"),
                    "serverTimestamp" to ServerValue.TIMESTAMP,    // Firebase server time — tamper-proof
                    "deviceTimestamp" to location.time             // Device ka local time (backup)
                )

                pushToFirebase(telemetryData)

                Log.d(TAG, "📍 Location pushed: ${location.latitude}, ${location.longitude} | " +
                    "Speed: ${"%.1f".format(speedKmh)} km/h | " +
                    "Accuracy: ${location.accuracy}m")
            }
        }

        override fun onLocationAvailability(availability: LocationAvailability) {
            if (!availability.isLocationAvailable) {
                Log.w(TAG, "⚠️ Location unavailable — GPS disabled or no signal")
                // Show GPS disabled dialog on UI thread
                android.os.Handler(Looper.getMainLooper()).post {
                    showLocationDisabledDialog()
                }
            }
        }
    }

    // ════════════════════════════════════════════════════════════════
    //  startTracking() — Start regular 20-sec SOS tracking
    // ════════════════════════════════════════════════════════════════
    fun startTracking() {
        // First check if GPS is enabled
        if (!isLocationEnabled()) {
            showLocationDisabledDialog()
            return
        }

        try {
            fusedClient.requestLocationUpdates(
                locationRequest,
                locationCallback,
                Looper.getMainLooper()   // Callback on main thread (UI safe)
            )
            Log.d(TAG, "✅ Location tracking started — 20sec interval, PRIORITY_HIGH_ACCURACY")
        } catch (e: SecurityException) {
            Log.e(TAG, "❌ Location permission missing: ${e.message}")
        }
    }

    // ════════════════════════════════════════════════════════════════
    //  stopTracking() — Stop tracking (on SOS deactivate)
    // ════════════════════════════════════════════════════════════════
    fun stopTracking() {
        fusedClient.removeLocationUpdates(locationCallback)
        Log.d(TAG, "🛑 Location tracking stopped")
    }

    // ════════════════════════════════════════════════════════════════
    //  forceImmediateFix() — ZERO-LATENCY INJECTION
    //  ─────────────────────────────────────────────────────────────
    //  SOS trigger hone ke TURANT baad ye call karo.
    //  Standard 20-sec interval ka wait bypass karta hai and
    //  ek immediate high-priority location fix force karta hai.
    //
    //  Usage:
    //      telemetryService.forceImmediateFix()   // SOS button press ke turant baad
    //      telemetryService.startTracking()        // Regular loop start karo
    // ════════════════════════════════════════════════════════════════
    fun forceImmediateFix() {
        // ── One-shot high-priority immediate request ────────────────
        val immediateRequest = LocationRequest.Builder(
            Priority.PRIORITY_HIGH_ACCURACY,
            1L   // Interval = 1ms → turant deliver karo
        ).apply {
            setMaxUpdates(1)                           // Sirf EK fix chahiye
            setWaitForAccurateLocation(false)          // Don't wait — speed priority hai
            setMinUpdateIntervalMillis(1L)
        }.build()

        try {
            fusedClient.requestLocationUpdates(
                immediateRequest,
                object : LocationCallback() {
                    override fun onLocationResult(result: LocationResult) {
                        result.lastLocation?.let { location ->

                            val speedKmh = if (location.hasSpeed()) {
                                (location.speed * 3.6f).toDouble()
                            } else { 0.0 }

                            // ── Immediate SOS telemetry with sosTriggered flag ──
                            val immediateData = mapOf(
                                "latitude"        to location.latitude,
                                "longitude"       to location.longitude,
                                "speed_kmh"       to speedKmh,
                                "accuracy_meters" to location.accuracy.toDouble(),
                                "altitude"        to location.altitude,
                                "serverTimestamp" to ServerValue.TIMESTAMP,
                                "deviceTimestamp" to location.time,
                                "sosTriggered"    to true,   // Ye SOS trigger fix hai — flag lagao
                                "provider"        to (location.provider ?: "unknown")
                            )
                            pushToFirebase(immediateData)
                            // Ek baar push after ye callback hata do
                            fusedClient.removeLocationUpdates(this)

                            Log.d(TAG, "🚨 ZERO-LATENCY SOS Fix: ${location.latitude}, " +
                                "${location.longitude} | Accuracy: ${location.accuracy}m")
                        }
                    }
                },
                Looper.getMainLooper()
            )
            Log.d(TAG, "⚡ Immediate high-priority location fix requested")
        } catch (e: SecurityException) {
            Log.e(TAG, "❌ Permission missing for immediate fix: ${e.message}")
        }
    }

    // ════════════════════════════════════════════════════════════════
    //  pushToFirebase() — /emergency_logs/{uid} pe data push karo
    // ════════════════════════════════════════════════════════════════
    private fun pushToFirebase(data: Map<String, Any>) {
        val uid = firebaseAuth.currentUser?.uid ?: run {
            // Auth nahi hai — anonymous UID use karo ya local device ID
            Log.w(TAG, "⚠️ No Firebase user — using anonymous node")
            "anonymous_${android.os.Build.SERIAL}"
        }

        // push() → automatic unique key generate karta hai (timestamp-based)
        // Isse entries kabhi overwrite nahi hoti — har fix alag node mein jaati hai
        firebaseDb.reference
            .child(DB_PATH)           // /emergency_logs
            .child(uid)               // /emergency_logs/{uid}
            .push()                   // /emergency_logs/{uid}/{auto-key}
            .setValue(data)
            .addOnSuccessListener {
                Log.d(TAG, "✅ Firebase push successful")
            }
            .addOnFailureListener { err ->
                Log.e(TAG, "❌ Firebase push failed: ${err.message}")
                // TODO: Offline queue mein store karo and baad mein retry karo
            }
    }

    // ════════════════════════════════════════════════════════════════
    //  isLocationEnabled() — checks if GPS/High Accuracy is enabled or not
    // ════════════════════════════════════════════════════════════════
    fun isLocationEnabled(): Boolean {
        val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        return lm.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
               lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
    }

    // ════════════════════════════════════════════════════════════════
    //  showLocationDisabledDialog() — User ko GPS enable karne bolo
    //  High-Accuracy mode ka prompt dikhao
    // ════════════════════════════════════════════════════════════════
    private fun showLocationDisabledDialog() {
        // Ye sirf Activity context mein kaam karta hai
        // Service mein use kar rahe ho to Application context pe AlertDialog nahi banta
        // Recommended: LocalBroadcastManager se Activity ko message bhejo
        try {
            AlertDialog.Builder(context)
                .setTitle("📍 GPS Band Hai — Location Enable Karo")
                .setMessage(
                    "SOS emergency mein accurate location send karne ke liye\n\n" +
                    "Settings → Location → Mode → Enable 'High Accuracy'.\n\n" +
                    "GPS disabled hone par contacts ko sirf approximate area milega — " +
                    "exact location ke liye High Accuracy GPS zaroori hai. 🛡️"
                )
                .setPositiveButton("Settings Kholo ✅") { _, _ ->
                    // High Accuracy Location Settings direct open karo
                    val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS).apply {
                        flags = Intent.FLAG_ACTIVITY_NEW_TASK
                    }
                    try {
                        context.startActivity(intent)
                    } catch (e: Exception) {
                        // Fallback: General settings
                        context.startActivity(
                            Intent(Settings.ACTION_SETTINGS).apply {
                                flags = Intent.FLAG_ACTIVITY_NEW_TASK
                            }
                        )
                    }
                }
                .setNegativeButton("Baad Mein") { dialog, _ ->
                    dialog.dismiss()
                    Log.w(TAG, "User ne GPS enable karna skip kiya — SOS accuracy reduced")
                }
                .setCancelable(false)   // Dismiss cannot — safety critical
                .show()
        } catch (e: Exception) {
            // Window token error (service context) — broadcast se handle karo
            Log.e(TAG, "Dialog show failed (use Activity context): ${e.message}")
            // Send local broadcast to Activity to show dialog
            val broadcastIntent = Intent("com.lunacare.SHOW_GPS_DIALOG")
            context.sendBroadcast(broadcastIntent)
        }
    }
}


// ════════════════════════════════════════════════════════════════════
//  INTEGRATION — GuardianForegroundService mein kaise use karo
// ════════════════════════════════════════════════════════════════════
//
//  GuardianForegroundService.kt mein yeh add karo:
//
//  class GuardianForegroundService : Service() {
//
//      private lateinit var telemetry: LocationTelemetryService
//
//      override fun onCreate() {
//          super.onCreate()
//          telemetry = LocationTelemetryService(this)
//          // ...rest of onCreate...
//      }
//
//      private fun handleSosActivate() {
//          acquireWakeLock()
//          // ── Step 1: ZERO-LATENCY — Instant first fix (interval bypass)
//          telemetry.forceImmediateFix()
//          // ── Step 2: Regular 20-sec tracking loop start karo
//          telemetry.startTracking()
//          updateNotification(
//              title   = "🆘 SOS ACTIVE — LunaCare Guardian",
//              message = "Emergency mode — Live location Firebase pe sync ho rahi hai."
//          )
//      }
//
//      private fun handleSosDeactivate() {
//          releaseWakeLock()
//          telemetry.stopTracking()
//          updateNotification(
//              title   = "🛡️ LunaCare Guardian Active",
//              message = "Monitoring in background. Tap to open."
//          )
//      }
//
//      override fun onDestroy() {
//          telemetry.stopTracking()
//          super.onDestroy()
//      }
//  }
// ════════════════════════════════════════════════════════════════════

📋 AndroidManifest.xml — Telemetry ke liye extra permissions

AndroidManifest.xml — Telemetry additions XML
<!-- ══ LOCATION TELEMETRY PERMISSIONS ══ -->

<!-- Fine + Coarse location (runtime permission bhi maango) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- Background location — GPS continues even when screen is off during active SOS -->
<!-- Android 10+ pe alag rationale dikhana padega user ko -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<!-- Internet — Firebase Realtime Database sync ke liye -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- Network State — online/offline check ke liye -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- Foreground service location type — Android 10+ mandatory -->
<service
    android:name=".service.GuardianForegroundService"
    android:enabled="true"
    android:exported="false"
    android:foregroundServiceType="location"
    android:stopWithTask="false" />

🔧 app/build.gradle — Dependencies add karo

app/build.gradle (dependencies block) Groovy
dependencies {
    // ── Google Play Services — FusedLocationProviderClient ──
    implementation "com.google.android.gms:play-services-location:21.0.1"

    // ── Firebase (BOM se version manage hogi — recommended) ──
    implementation platform("com.google.firebase:firebase-bom:32.7.0")
    implementation "com.google.firebase:firebase-database-ktx"   // Realtime Database
    implementation "com.google.firebase:firebase-auth-ktx"        // Auth (UID ke liye)

    // ── Kotlin Coroutines (optional but recommended for async ops) ──
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
}

🔒 Firebase Realtime Database Rules — Security setup karo

Paste this in Firebase Console → Realtime Database → Rules tab. These rules ensure only authenticated users can write their own data, and admins (Emergency Responders) can read it.

Firebase Realtime Database Rules JSON
{
  "rules": {
    "emergency_logs": {
      "$uid": {
        // Sirf woh user likh sakta hai jiska uid match kare
        ".write": "auth != null && auth.uid === $uid",
        // Read: sirf authenticated users (emergency responders)
        ".read":  "auth != null"
      }
    }
  }
}

🗃️ Firebase mein data structure kaisi dikhegi

emergency_logs/
  └── {uid}/                          ← User ka Firebase Auth UID
        ├── {auto-key-1}/             ← SOS trigger ka INSTANT fix (sosTriggered: true)
        │     ├── latitude:     26.449923
        │     ├── longitude:    80.331872
        │     ├── speed_kmh:    4.2
        │     ├── accuracy_meters: 8.0
        │     ├── altitude:     127.5
        │     ├── provider:     "fused"
        │     ├── sosTriggered: true     ← Zero-latency injection flag
        │     ├── serverTimestamp: 1712500000000
        │     └── deviceTimestamp: 1712500000000
        │
        └── {auto-key-2}/             ← Regular 20-sec update
              ├── latitude:     26.450101
              ├── longitude:    80.332004
              ├── speed_kmh:    12.6
              ├── accuracy_meters: 5.0
              ├── sosTriggered: false    ← Normal update
              └── serverTimestamp: 1712500020000

My Profile

Your personal health settings