diff --git a/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/MainActivity.kt b/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/MainActivity.kt index 9e7d8c4c5..23b645978 100644 --- a/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/MainActivity.kt +++ b/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/MainActivity.kt @@ -20,11 +20,17 @@ class MainActivity : FlutterActivity() { override fun onReceive(context: Context?, intent: Intent?) { val latitude = intent?.getDoubleExtra("latitude", 0.0) val longitude = intent?.getDoubleExtra("longitude", 0.0) + val accuracy = intent?.getFloatExtra("accuracy", 0.0f) // Retrieve accuracy here + // Handle the location data here - Toast.makeText(context, "Latitude: $latitude, Longitude: $longitude", Toast.LENGTH_LONG).show() + Toast.makeText(context, "Latitude: $latitude, Longitude: $longitude, Accuracy: $accuracy", 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)) + MethodChannel(it, CHANNEL).invokeMethod("locationUpdate", mapOf( + "latitude" to latitude, + "longitude" to longitude, + "accuracy" to accuracy + )) } } } diff --git a/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/location_service.kt b/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/location_service.kt index 930d4a408..23756ee0e 100644 --- a/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/location_service.kt +++ b/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/location_service.kt @@ -92,10 +92,11 @@ class LocationService : Service() { val intent = Intent("LocationUpdate") intent.putExtra("latitude", location.latitude) intent.putExtra("longitude", location.longitude) + intent.putExtra("accuracy", location.accuracy) sendBroadcast(intent) - Log.d("LocationSharing", "Location sent to MainActivity: Latitude ${location.latitude}, Longitude ${location.longitude}") + Log.d("LocationSharing", "Location sent to MainActivity: Latitude ${location.latitude}, Longitude ${location.longitude}, Accuracy ${location.accuracy}") } override fun onDestroy() { @@ -129,8 +130,10 @@ class LocationService : Service() { 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 notificationContent = "Latitude: ${location.latitude}, Longitude: ${location.longitude}, Accuracy: ${location.accuracy}" // Include accuracy + + // Write location and accuracy to file + writeToFile("Latitude: ${location.latitude}, Longitude: ${location.longitude}, Accuracy: ${location.accuracy}, isSync: false, timestamp: $timestamp") val notification = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Location Service") diff --git a/apps/health_campaign_field_worker_app/lib/data/repositories/local/localization.dart b/apps/health_campaign_field_worker_app/lib/data/repositories/local/localization.dart index bd9fc1e08..0d8244287 100644 --- a/apps/health_campaign_field_worker_app/lib/data/repositories/local/localization.dart +++ b/apps/health_campaign_field_worker_app/lib/data/repositories/local/localization.dart @@ -10,98 +10,104 @@ import '../../local_store/no_sql/schema/localization.dart'; class LocalizationLocalRepository { FutureOr> returnLocalizationFromSQL( LocalSqlDataStore sql) async { - final selectQuery = sql.select(sql.localization).join([]); - - // List to hold the AND conditions - final andConditions = >[]; - - // Add condition for locale if provided - if (LocalizationParams().locale != null) { - final localeString = '${LocalizationParams().locale!}'; - andConditions.add(sql.localization.locale.equals(localeString)); - } - - // Add conditions for modules and codes - if (LocalizationParams().module != null && - LocalizationParams().module!.isNotEmpty) { - final moduleToExclude = LocalizationParams().module!; - - if (LocalizationParams().exclude == true) { - // Exclude modules but include records where the code matches - final moduleCondition = - sql.localization.module.contains(moduleToExclude).not(); - final codeCondition = LocalizationParams().code != null && - LocalizationParams().code!.isNotEmpty - ? sql.localization.code.isIn(LocalizationParams().code!.toList()) - : const Constant(false); // True if no code filter - - // Combine conditions: exclude module unless code matches - andConditions.add(buildAnd([moduleCondition | codeCondition])); - } else { - // Include specified modules and optionally filter by code - final moduleCondition = - sql.localization.module.contains(moduleToExclude); - final codeCondition = LocalizationParams().code != null && - LocalizationParams().code!.isNotEmpty - ? sql.localization.code.isIn(LocalizationParams().code!.toList()) - : const Constant(false); - - // Combine conditions: module matches and optionally code filter - andConditions.add(buildAnd([moduleCondition | codeCondition])); + return retryLocalCallOperation(() async { + final selectQuery = sql.select(sql.localization).join([]); + + // List to hold the AND conditions + final andConditions = >[]; + + // Add condition for locale if provided + if (LocalizationParams().locale != null) { + final localeString = '${LocalizationParams().locale!}'; + andConditions.add(sql.localization.locale.equals(localeString)); + } + + // Add conditions for modules and codes + if (LocalizationParams().module != null && + LocalizationParams().module!.isNotEmpty) { + final moduleToExclude = LocalizationParams().module!; + + if (LocalizationParams().exclude == true) { + // Exclude modules but include records where the code matches + final moduleCondition = + sql.localization.module.contains(moduleToExclude).not(); + final codeCondition = LocalizationParams().code != null && + LocalizationParams().code!.isNotEmpty + ? sql.localization.code.isIn(LocalizationParams().code!.toList()) + : const Constant(false); // True if no code filter + + // Combine conditions: exclude module unless code matches + andConditions.add(buildAnd([moduleCondition | codeCondition])); + } else { + // Include specified modules and optionally filter by code + final moduleCondition = + sql.localization.module.contains(moduleToExclude); + final codeCondition = LocalizationParams().code != null && + LocalizationParams().code!.isNotEmpty + ? sql.localization.code.isIn(LocalizationParams().code!.toList()) + : const Constant(false); + + // Combine conditions: module matches and optionally code filter + andConditions.add(buildAnd([moduleCondition | codeCondition])); + } + } else if (LocalizationParams().code != null && + LocalizationParams().code!.isNotEmpty) { + // If no module filter, just apply code filter + andConditions.add( + sql.localization.code.isIn(LocalizationParams().code!.toList())); + } + + // Apply the combined conditions to the query + if (andConditions.isNotEmpty) { + selectQuery.where(buildAnd(andConditions)); } - } else if (LocalizationParams().code != null && - LocalizationParams().code!.isNotEmpty) { - // If no module filter, just apply code filter - andConditions - .add(sql.localization.code.isIn(LocalizationParams().code!.toList())); - } - - // Apply the combined conditions to the query - if (andConditions.isNotEmpty) { - selectQuery.where(buildAnd(andConditions)); - } - - final result = await selectQuery.get(); - - return result.map((row) { - final data = row.readTableOrNull(sql.localization); - - return Localization() - ..code = data!.code - ..locale = data.locale - ..module = data.module - ..message = data.message; - }).toList(); + + final result = await selectQuery.get(); + + return result.map((row) { + final data = row.readTableOrNull(sql.localization); + + return Localization() + ..code = data!.code + ..locale = data.locale + ..module = data.module + ..message = data.message; + }).toList(); + }); } FutureOr> fetchLocalization( {required LocalSqlDataStore sql, required String locale, required String module}) async { - final query = sql.select(sql.localization).join([]) - ..where( - buildOr([ - sql.localization.locale.equals(locale), - sql.localization.module.contains(module), - ]), - ); - - final results = await query.get(); - - return results.map((e) { - final data = e.readTableOrNull(sql.localization); - return Localization() - ..code = data!.code - ..locale = data.locale - ..module = data.module - ..message = data.message; - }).toList(); + return retryLocalCallOperation(() async { + final query = sql.select(sql.localization).join([]) + ..where( + buildOr([ + sql.localization.locale.equals(locale), + sql.localization.module.contains(module), + ]), + ); + + final results = await query.get(); + + return results.map((e) { + final data = e.readTableOrNull(sql.localization); + return Localization() + ..code = data!.code + ..locale = data.locale + ..module = data.module + ..message = data.message; + }).toList(); + }); } FutureOr create( List result, LocalSqlDataStore sql) async { - return sql.batch((batch) { - batch.insertAll(sql.localization, result); + return retryLocalCallOperation(() async { + return sql.batch((batch) { + batch.insertAll(sql.localization, result); + }); }); } } diff --git a/apps/health_campaign_field_worker_app/pubspec.lock b/apps/health_campaign_field_worker_app/pubspec.lock index c47910a9c..a4d1893aa 100644 --- a/apps/health_campaign_field_worker_app/pubspec.lock +++ b/apps/health_campaign_field_worker_app/pubspec.lock @@ -69,10 +69,10 @@ packages: dependency: "direct main" description: name: attendance_management - sha256: f1b4373e8d0d9f8227ede0d25d4141f0d16d18ac2525c0347b844098cdab080f + sha256: "8a09814ca11cca736d771be70fb6174303ea0cb3525aa72e7239cbc14b915303" url: "https://pub.dev" source: hosted - version: "1.0.2+1" + version: "1.0.2+4" audioplayers: dependency: "direct main" description: @@ -517,18 +517,19 @@ packages: digit_firebase_services: dependency: "direct main" description: - path: "../../packages/digit_firebase_services" - relative: true - source: path + name: digit_firebase_services + sha256: ce76521d797e123b6fc95c9dfad7d4a918a93b97f57aecd0e1d517b46190909d + url: "https://pub.dev" + source: hosted version: "0.0.1" digit_location_tracker: dependency: "direct main" description: name: digit_location_tracker - sha256: "1ea40a1373cac2c90659432a5531cd96489d2bd4d9a719f2ae3978ea60662ab6" + sha256: ee5531b9b9442820d48d1ddd86177602eb425f742b0d9c29b57325ef157fa886 url: "https://pub.dev" source: hosted - version: "0.0.1-dev.1" + version: "0.0.1-dev.2" digit_scanner: dependency: "direct main" description: diff --git a/apps/health_campaign_field_worker_app/pubspec.yaml b/apps/health_campaign_field_worker_app/pubspec.yaml index 06d188a41..f86b903a0 100644 --- a/apps/health_campaign_field_worker_app/pubspec.yaml +++ b/apps/health_campaign_field_worker_app/pubspec.yaml @@ -74,7 +74,7 @@ dependencies: disable_battery_optimization: ^1.1.1 digit_dss: ^1.0.1 closed_household: ^1.0.1+1 - digit_location_tracker: ^0.0.1-dev.1 + digit_location_tracker: ^0.0.1-dev.2 permission_handler: ^11.3.1 dev_dependencies: diff --git a/packages/digit_location_tracker/CHANGELOG.md b/packages/digit_location_tracker/CHANGELOG.md index e0452a61f..0493f2b49 100644 --- a/packages/digit_location_tracker/CHANGELOG.md +++ b/packages/digit_location_tracker/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.0.1-dev.2 + +* Modified Regex for handling negative latitude, longitude and added new accuracy field +* Added new accuracy field to fetch precise location + ## 0.0.1-dev.1 * Init release of digit_location_tracker diff --git a/packages/digit_location_tracker/README.md b/packages/digit_location_tracker/README.md index be133cdd4..0b6fb25b3 100644 --- a/packages/digit_location_tracker/README.md +++ b/packages/digit_location_tracker/README.md @@ -34,6 +34,8 @@ triggerLocationTracker( now.add(const Duration(hours: 8)).millisecondsSinceEpoch, ); -## Additional information +## Additional Required information -Create location service file in your android folder and replace main activity similar to this https://github.com/egovernments/health-campaign-field-worker-app/blob/location_tracker/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/MainActivity.kt and https://github.com/egovernments/health-campaign-field-worker-app/blob/location_tracker/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/location_service.kt +Create location service file in your android folder and replace main activity similar to this +1. https://github.com/egovernments/health-campaign-field-worker-app/blob/location_tracker/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/MainActivity.kt +2. https://github.com/egovernments/health-campaign-field-worker-app/blob/location_tracker/apps/health_campaign_field_worker_app/android/app/src/main/kotlin/com/digit/hcm/location_service.kt diff --git a/packages/digit_location_tracker/lib/utils/utils.dart b/packages/digit_location_tracker/lib/utils/utils.dart index 8fc217297..dcc22740e 100644 --- a/packages/digit_location_tracker/lib/utils/utils.dart +++ b/packages/digit_location_tracker/lib/utils/utils.dart @@ -30,19 +30,20 @@ Future> parseLocationData(List logs) async { for (var log in logs) { final pattern = RegExp( - r'Latitude:\s*(\d+\.\d+),\s*Longitude:\s*(\d+\.\d+),\s*isSync:\s*(\w+),\s*timestamp:\s*(\d+)'); + r'Latitude:\s*(-?\d+\.\d+),\s*Longitude:\s*(-?\d+\.\d+),\s*Accuracy:\s*(\d+\.\d+),\s*isSync:\s*(\w+),\s*timestamp:\s*(\d+)'); final match = pattern.firstMatch(log); if (match != null) { final latitude = double.parse(match.group(1)!); final longitude = double.parse(match.group(2)!); - final isSync = match.group(3)!.toLowerCase() == 'true'; - final timestamp = int.parse(match.group(4)!); + final accuracy = double.parse(match.group(3)!); + final isSync = match.group(4)!.toLowerCase() == 'true'; + final timestamp = int.parse(match.group(5)!); locationDataList.add(UserActionModel( latitude: latitude, longitude: longitude, - locationAccuracy: 1.3, + locationAccuracy: accuracy, tenantId: LocationTrackerSingleton().tenantId, clientReferenceId: IdGen.instance.identifier, isSync: isSync, diff --git a/packages/digit_location_tracker/pubspec.yaml b/packages/digit_location_tracker/pubspec.yaml index 8b8c120c7..e1a343baa 100644 --- a/packages/digit_location_tracker/pubspec.yaml +++ b/packages/digit_location_tracker/pubspec.yaml @@ -1,6 +1,6 @@ name: digit_location_tracker description: "A comprehensive package to enable location_tracking in the application" -version: 0.0.1-dev.1 +version: 0.0.1-dev.2 homepage: https://github.com/egovernments/health-campaign-field-worker-app/tree/master/packages/digit_location_tracker repository: https://github.com/egovernments/health-campaign-field-worker-app