Cycle Calendar
Track, predict, and understand your cycle
📅 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
Don't forget it — it protects you in emergencies.
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.
Updates while SOS is active
Approval required before sharing
Stops accidental deactivation
🛡️ 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.
No guardians invited yet.
📞 Emergency Helplines — Available Now
Android Immortal Engine
Foreground Service · WakeLock · Boot Receiver · Battery Bypass — Complete Implementation
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
GuardianForegroundService.kt — Main service (Sticky + WakeLock)BootReceiver.kt — Auto-restart on reboot & app updateBatteryOptimizationHelper.kt — Doze Mode bypass promptAndroidManifest.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
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+)
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
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 haiandroid:exported="false"— BootReceiver ke liyetruehona chahiye (system broadcast receive karne ke liye)- Replace
com.lunacare.appapne actual package name se
<?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
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
<!-- ══ 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
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.
{
"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
Legal Shield
Women's Laws — Cyber, Workplace, Family, Property, Safety
Global Search
Find gynecologists, NGOs, therapists, police — anywhere in the world
🏥 AViro Expert Locator
AViro finds top-rated Gynecologists, Therapists & Physiotherapists near you — powered by AI.
📞 Emergency Helplines (India)
My Profile
Your personal health settings