Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Location Tracker Patch #604

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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")
naveenr-egov marked this conversation as resolved.
Show resolved Hide resolved

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Location Service")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,98 +10,104 @@ import '../../local_store/no_sql/schema/localization.dart';
class LocalizationLocalRepository {
FutureOr<List<Localization>> returnLocalizationFromSQL(
LocalSqlDataStore sql) async {
final selectQuery = sql.select(sql.localization).join([]);

// List to hold the AND conditions
final andConditions = <Expression<bool>>[];

// 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 = <Expression<bool>>[];

// 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<List<Localization>> 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<LocalizationCompanion> 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);
});
Comment on lines +107 to +110
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add batch size limit and duplicate handling

The batch insert operation should include:

  1. A maximum batch size to prevent memory issues
  2. A strategy for handling duplicate entries (e.g., IGNORE or REPLACE)
  return retryLocalCallOperation(() async {
+   const int maxBatchSize = 1000;
+   for (var i = 0; i < result.length; i += maxBatchSize) {
+     final end = (i + maxBatchSize < result.length) ? i + maxBatchSize : result.length;
      return sql.batch((batch) {
-       batch.insertAll(sql.localization, result);
+       batch.insertAll(
+         sql.localization,
+         result.sublist(i, end),
+         mode: InsertMode.insertOrReplace,
+       );
      });
+   }
  });

Committable suggestion skipped: line range outside the PR's diff.

});
}
}
15 changes: 8 additions & 7 deletions apps/health_campaign_field_worker_app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion apps/health_campaign_field_worker_app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 5 additions & 0 deletions packages/digit_location_tracker/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
6 changes: 4 additions & 2 deletions packages/digit_location_tracker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 5 additions & 4 deletions packages/digit_location_tracker/lib/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,20 @@ Future<List<UserActionModel>> parseLocationData(List<String> 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,
naveenr-egov marked this conversation as resolved.
Show resolved Hide resolved
tenantId: LocationTrackerSingleton().tenantId,
clientReferenceId: IdGen.instance.identifier,
isSync: isSync,
Expand Down
2 changes: 1 addition & 1 deletion packages/digit_location_tracker/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Loading