| Method | Use Case | Platform Support |
|---|---|---|
delete | Delete by type and time range | iOS, Android |
deleteByUUID | Delete specific data point by UUID | iOS only |
deleteByClientRecordId | Delete by custom record ID | Android only |
Delete by Type and Time Range
Remove all data of a specific type within a time period.Method Signature
Copy
Future<bool> delete({
required HealthDataType type,
required DateTime startTime,
required DateTime endTime,
})
Basic Usage
Copy
// Delete today's steps
final today = DateTime.now();
final startOfDay = DateTime(today.year, today.month, today.day);
await health.delete(
type: HealthDataType.STEPS,
startTime: startOfDay,
endTime: today,
);
// Delete weight measurements from last week
await health.delete(
type: HealthDataType.WEIGHT,
startTime: DateTime.now().subtract(Duration(days: 7)),
endTime: DateTime.now(),
);
Delete Specific Day
Copy
Future<bool> deleteDay(HealthDataType type, DateTime date) async {
final startOfDay = DateTime(date.year, date.month, date.day);
final endOfDay = startOfDay.add(Duration(days: 1));
return await health.delete(
type: type,
startTime: startOfDay,
endTime: endOfDay,
);
}
// Usage
await deleteDay(HealthDataType.HEART_RATE, DateTime.now());
Delete All Data of Type
Copy
Future<bool> deleteAllData(HealthDataType type) async {
// Delete from a very old date to now
return await health.delete(
type: type,
startTime: DateTime(2000, 1, 1),
endTime: DateTime.now(),
);
}
// Usage
await deleteAllData(HealthDataType.STEPS);
Delete by UUID (iOS Only)
Delete a specific data point using its unique identifier.Method Signature
Copy
Future<bool> deleteByUUID({
required String uuid,
})
Usage
Copy
// First, get the data with UUID
final dataPoints = await health.getHealthDataFromTypes(
types: [HealthDataType.WEIGHT],
startDate: DateTime.now().subtract(Duration(days: 7)),
endDate: DateTime.now(),
);
// Delete a specific point
if (dataPoints.isNotEmpty) {
final uuid = dataPoints.first.uuid;
final success = await health.deleteByUUID(uuid: uuid);
if (success) {
print('Data point deleted');
}
}
Delete Specific Reading
Copy
class DataPointManager {
final Health health;
DataPointManager(this.health);
Future<bool> deleteReading(HealthDataPoint point) async {
if (point.uuid.isEmpty) {
print('No UUID available');
return false;
}
return await health.deleteByUUID(uuid: point.uuid);
}
Future<int> deleteMultipleReadings(List<HealthDataPoint> points) async {
int deletedCount = 0;
for (var point in points) {
if (point.uuid.isNotEmpty) {
final success = await health.deleteByUUID(uuid: point.uuid);
if (success) deletedCount++;
}
}
return deletedCount;
}
}
// Usage
final manager = DataPointManager(health);
await manager.deleteReading(dataPoint);
Delete by Client Record ID (Android Only)
Delete data using a custom record identifier on Android Health Connect.Method Signature
Copy
Future<bool> deleteByClientRecordId({
required String clientRecordId,
})
Usage
Copy
// Delete by custom record ID
await health.deleteByClientRecordId(
clientRecordId: 'my-app-weight-2024-01-15',
);
Custom ID Strategy
Copy
class RecordIdGenerator {
static String generate(HealthDataType type, DateTime timestamp) {
final dateStr = timestamp.toIso8601String();
return 'myapp_${type.name}_$dateStr';
}
}
// When writing data, use custom ID
final recordId = RecordIdGenerator.generate(
HealthDataType.WEIGHT,
DateTime.now(),
);
// Later, delete by this ID
await health.deleteByClientRecordId(clientRecordId: recordId);
Bulk Delete Operations
Copy
class BulkDeleteManager {
final Health health;
BulkDeleteManager(this.health);
Future<Map<HealthDataType, bool>> deleteMultipleTypes({
required List<HealthDataType> types,
required DateTime startTime,
required DateTime endTime,
}) async {
final results = <HealthDataType, bool>{};
for (var type in types) {
final success = await health.delete(
type: type,
startTime: startTime,
endTime: endTime,
);
results[type] = success;
}
return results;
}
Future<void> clearAllActivityData(DateTime date) async {
final activityTypes = [
HealthDataType.STEPS,
HealthDataType.DISTANCE_WALKING_RUNNING,
HealthDataType.ACTIVE_ENERGY_BURNED,
HealthDataType.FLIGHTS_CLIMBED,
];
final startOfDay = DateTime(date.year, date.month, date.day);
final endOfDay = startOfDay.add(Duration(days: 1));
final results = await deleteMultipleTypes(
types: activityTypes,
startTime: startOfDay,
endTime: endOfDay,
);
results.forEach((type, success) {
print('${type.name}: ${success ? "✓" : "✗"}');
});
}
}
// Usage
final manager = BulkDeleteManager(health);
await manager.clearAllActivityData(DateTime.now());
Selective Deletion
Copy
class SelectiveDeleter {
final Health health;
SelectiveDeleter(this.health);
// Delete outliers (e.g., unrealistic values)
Future<int> deleteOutliers({
required HealthDataType type,
required DateTime startDate,
required DateTime endDate,
required bool Function(HealthDataPoint) isOutlier,
}) async {
// Read data
final dataPoints = await health.getHealthDataFromTypes(
types: [type],
startDate: startDate,
endDate: endDate,
);
int deletedCount = 0;
// Delete outliers
for (var point in dataPoints) {
if (isOutlier(point) && point.uuid.isNotEmpty) {
final success = await health.deleteByUUID(uuid: point.uuid);
if (success) deletedCount++;
}
}
return deletedCount;
}
}
// Usage
final deleter = SelectiveDeleter(health);
final deletedCount = await deleter.deleteOutliers(
type: HealthDataType.WEIGHT,
startDate: DateTime.now().subtract(Duration(days: 30)),
endDate: DateTime.now(),
isOutlier: (point) {
final value = (point.value as NumericHealthValue).numericValue;
// Delete weights outside reasonable range
return value < 30 || value > 300;
},
);
print('Deleted $deletedCount outlier readings');
Safe Deletion with Confirmation
Copy
Future<bool> safeDelete({
required Health health,
required HealthDataType type,
required DateTime startTime,
required DateTime endTime,
required Future<bool> Function(int count) confirmDeletion,
}) async {
// First, count how many data points will be deleted
final dataPoints = await health.getHealthDataFromTypes(
types: [type],
startDate: startTime,
endDate: endTime,
);
if (dataPoints.isEmpty) {
print('No data to delete');
return false;
}
// Ask for confirmation
final confirmed = await confirmDeletion(dataPoints.length);
if (!confirmed) {
print('Deletion cancelled');
return false;
}
// Proceed with deletion
return await health.delete(
type: type,
startTime: startTime,
endTime: endTime,
);
}
// Usage
await safeDelete(
health: health,
type: HealthDataType.STEPS,
startTime: startDate,
endTime: endDate,
confirmDeletion: (count) async {
print('About to delete $count data points');
// In real app, show a dialog
return true; // User confirmed
},
);
Platform Differences
- iOS (HealthKit)
- Android (Health Connect)
- Supports
deleteanddeleteByUUID - UUID-based deletion is precise
- Deletion is immediate
- Cannot undo deletions
- May affect data in other apps
Error Handling
Copy
Future<void> deleteWithErrorHandling(
HealthDataType type,
DateTime start,
DateTime end,
) async {
try {
final success = await health.delete(
type: type,
startTime: start,
endTime: end,
);
if (success) {
print('✓ Data deleted successfully');
} else {
print('✗ Deletion failed');
print(' Check permissions or data existence');
}
} catch (e) {
print('✗ Error during deletion: $e');
}
}
Permission Requirements
Deletion requires WRITE permission:Copy
final types = [HealthDataType.STEPS, HealthDataType.WEIGHT];
final granted = await health.requestAuthorization(
types,
permissions: List.filled(types.length, HealthDataAccess.WRITE),
);
if (granted) {
// Can now delete data
await health.delete(
type: HealthDataType.STEPS,
startTime: startTime,
endTime: endTime,
);
}
See Also
- Permissions - Managing write permissions
- Basic Reading - Getting data points with UUIDs
- Basic Writing - Writing health data