Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into registration-deliv…
Browse files Browse the repository at this point in the history
…ery-component
  • Loading branch information
yashita-egov committed Nov 12, 2024
2 parents 23c5b37 + fafde86 commit 3e6c816
Show file tree
Hide file tree
Showing 423 changed files with 19,063 additions and 4,740 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ migrate_working_dir/
*.iws
.idea/


# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
Expand Down Expand Up @@ -57,3 +56,7 @@ pubspec_overrides.yaml
apps/health_campaign_field_worker_app/.env
apps/health_campaign_field_worker_app/libisar.dylib
*.properties

# FVM Version Cache
.fvm/
.fvmrc
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ class _ChecklistDataShowcaseData {
import '../../../utils/i18_key_constants.dart' as i18;
import '../showcase_wrappers.dart';
part 'checklist_data.dart';
part 'survey_form_data.dart';
final checklistDataShowcaseData = _ChecklistDataShowcaseData();
```
Expand Down
4 changes: 4 additions & 0 deletions apps/health_campaign_field_worker_app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release

# FVM Version Cache
.fvm/
.fvmrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="com.android.alarm.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Expand All @@ -30,6 +33,12 @@
android:allowBackup="false"
android:fullBackupOnly="false"
android:fullBackupContent="false"
<service
android:name=".LocationService"
android:enabled="true"
android:foregroundServiceType="location"
android:exported="false" />

<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,100 @@
package com.digit.hcm
import android.app.NotificationManager
import android.content.Context

import io.flutter.embedding.android.FlutterActivity
import android.os.Bundle
import java.io.File
import java.io.FileOutputStream
import io.flutter.plugin.common.MethodChannel
import android.content.Intent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.IntentFilter
import android.os.Environment
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import android.widget.Toast

class MainActivity : FlutterActivity() {
private val CHANNEL = "com.digit.location_tracker"
private val locationReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val latitude = intent?.getDoubleExtra("latitude", 0.0)
val longitude = intent?.getDoubleExtra("longitude", 0.0)
// Handle the location data here
Toast.makeText(context, "Latitude: $latitude, Longitude: $longitude", Toast.LENGTH_LONG).show()
// Optionally, you can send this data to Flutter via MethodChannel
flutterEngine?.dartExecutor?.binaryMessenger?.let {
MethodChannel(it, CHANNEL).invokeMethod("locationUpdate", mapOf("latitude" to latitude, "longitude" to longitude))
}
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

class MainActivity: FlutterActivity() {
override fun onResume() {
super.onResume()
closeAllNotifications();
MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"startLocationUpdates" -> {
val interval = (call.argument<Number>("interval")?.toLong()) ?: 60000L
val stopAfterTimestamp = (call.argument<Number>("stopAfterTimestamp")?.toLong()) ?: (System.currentTimeMillis() + 60000L)
if (!isMyServiceRunning(LocationService::class.java)) {
startService(interval, stopAfterTimestamp)
} else {
Toast.makeText(this, "Location service is already running", Toast.LENGTH_SHORT).show()
}
result.success(null)
}
"stopLocationUpdates" -> {
stopService()
result.success(null)
}
else -> result.notImplemented()
}
}

// Register the receiver for location updates
val filter = IntentFilter("LocationUpdate")
registerReceiver(locationReceiver, filter)
}

override fun onDestroy() {
super.onDestroy()
// Unregister the receiver
unregisterReceiver(locationReceiver)
}

private fun closeAllNotifications() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancelAll()
private fun startService(locationUpdateInterval: Long, stopAfterTimestamp: Long) {
try {
val serviceIntent = Intent(this, LocationService::class.java).apply {
putExtra("interval", locationUpdateInterval) // Pass the interval to the service
putExtra("stopAfterTimestamp", stopAfterTimestamp)
}
startService(serviceIntent)
} catch (e: Exception) {
e.printStackTrace()
}
}

}
private fun stopService() {
try {
val serviceIntent = Intent(this, LocationService::class.java)
Toast.makeText(this, "Stopping location service", Toast.LENGTH_SHORT).show()
stopService(serviceIntent)
} catch (e: Exception) {
e.printStackTrace()
}
}

// Check if service is running
private fun isMyServiceRunning(serviceClass: Class<*>): Boolean {
val manager = getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
for (service in manager.getRunningServices(Int.MAX_VALUE)) {
if (serviceClass.name == service.service.className) {
Toast.makeText(this, "Location service is already running", Toast.LENGTH_SHORT).show()
return true
}
}
Toast.makeText(this, "Location service starting", Toast.LENGTH_SHORT).show()
return false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package com.digit.hcm

import android.annotation.TargetApi
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.location.Location
import android.os.Build
import java.io.File
import java.io.FileOutputStream
import android.os.IBinder
import android.os.Environment
import android.os.Looper
import android.util.Log
import androidx.core.app.NotificationCompat
import com.google.android.gms.location.*
import java.io.IOException

class LocationService : Service() {

private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationCallback: LocationCallback
private var locationUpdateInterval: Long = 60000L
private var stopAfterTimestamp: Long = 0L

override fun onCreate() {
super.onCreate()
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
createNotificationChannel()
startForegroundService()
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
locationUpdateInterval = intent?.getLongExtra("interval", 60000L) ?: 60000L
stopAfterTimestamp = intent?.getLongExtra("stopAfterTimestamp", System.currentTimeMillis() + 60000L) ?: System.currentTimeMillis() + 60000L
startLocationUpdates()
return START_STICKY
}

@TargetApi(Build.VERSION_CODES.ECLAIR)
private fun startForegroundService() {
val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Location Service")
.setContentText("Tracking location in background")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(1, notification)
} else {
startForeground(1, notification)
}
}

private fun startLocationUpdates() {
val locationRequest = LocationRequest.create().apply {
interval = locationUpdateInterval
fastestInterval = locationUpdateInterval
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}

locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult ?: return
for (location in locationResult.locations) {
updateNotification(location)
sendLocationToMainActivity(location)

// Check if the stop time has been reached
if (System.currentTimeMillis() >= stopAfterTimestamp) {
Log.d("LocationService", "Stop after timestamp reached")
stopSelf()
}
}
}
}

fusedLocationClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}

private fun sendLocationToMainActivity(location: Location) {
val intent = Intent("LocationUpdate")
intent.putExtra("latitude", location.latitude)
intent.putExtra("longitude", location.longitude)

sendBroadcast(intent)

Log.d("LocationSharing", "Location sent to MainActivity: Latitude ${location.latitude}, Longitude ${location.longitude}")
}

override fun onDestroy() {
super.onDestroy()
fusedLocationClient.removeLocationUpdates(locationCallback)
}

override fun onBind(intent: Intent?): IBinder? {
return null
}

private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(
CHANNEL_ID,
"Location Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(serviceChannel)
}
}

fun stopService() {
stopForeground(true)
stopSelf()
Log.d("LocationService", "Service stopped")
}

private fun updateNotification(location: Location) {
val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
val timestamp = System.currentTimeMillis()
val notificationContent = "Latitude: ${location.latitude}, Longitude: ${location.longitude},"
writeToFile("Latitude: ${location.latitude}, Longitude: ${location.longitude}, isSync: false, timestamp: $timestamp")

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Location Service")
.setContentText(notificationContent)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build()

val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.notify(1, notification)
}

private fun writeToFile(data: String) {
try {
val fileName = "location_data.txt"
val file: File

// Access Downloads folder
val downloadsFolder = File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "")
file = File(downloadsFolder, fileName)

val fileOutputStream = FileOutputStream(file, true) // Append mode
fileOutputStream.write((data + "\n").toByteArray())
fileOutputStream.close()

// Print the file path
println("File saved at: ${file.absolutePath}")
} catch (e: Exception) {
e.printStackTrace()
}
}

companion object {
private const val CHANNEL_ID = "LocationServiceChannel"
}
}
8 changes: 8 additions & 0 deletions apps/health_campaign_field_worker_app/lib/app.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:attendance_management/attendance_management.dart';
import 'package:survey_form/survey_form.dart';
import 'package:closed_household/blocs/closed_household.dart';
import 'package:closed_household/closed_household.dart';
import 'package:digit_components/digit_components.dart';
Expand All @@ -25,6 +26,8 @@ import 'blocs/localization/localization.dart';
import 'blocs/project/project.dart';
import 'data/local_store/app_shared_preferences.dart';
import 'data/network_manager.dart';
import 'data/remote_client.dart';
import 'data/repositories/remote/bandwidth_check.dart';
import 'data/repositories/remote/localization.dart';
import 'data/repositories/remote/mdms.dart';
import 'router/app_navigator_observer.dart';
Expand Down Expand Up @@ -201,6 +204,11 @@ class MainApplicationState extends State<MainApplication>
),
BlocProvider(
create: (ctx) => ProjectBloc(
bandwidthCheckRepository: BandwidthCheckRepository(
DioClient().dio,
bandwidthPath:
envConfig.variables.checkBandwidthApiPath,
),
mdmsRepository: MdmsRepository(widget.client),
dashboardRemoteRepository:
DashboardRemoteRepository(widget.client),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ class MdmsConfig {
final List<ServiceRegistry> serviceRegistryList;
final DashboardConfigSchema? dashboardConfigSchema;


const MdmsConfig(
{required this.appConfigs,
required this.serviceRegistryList,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:collection/collection.dart';
import 'package:digit_data_model/data/local_store/sql_store/sql_store.dart';
import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import '../../data/local_store/no_sql/schema/app_configuration.dart';
import 'app_localization.dart';

Expand Down
Loading

0 comments on commit 3e6c816

Please sign in to comment.