health_connector_hc_android 1.4.0 copy "health_connector_hc_android: ^1.4.0" to clipboard
health_connector_hc_android: ^1.4.0 copied to clipboard

PlatformAndroid

Android implementation of health_connector using Health Connect

health_connector_hc_android #


📖 Overview #

health_connector_hc_android is the Android platform implementation for the Health Connector plugin. It provides integration with Android's Health Connect SDK, enabling Flutter apps to read, write, and aggregate health data on Android devices.

✨ Features #

Feature Description
🔐 Permission Management Request/check/revoke permissions
📖 Reading Health Data Read a single health record by ID or multiple health records within a date/time range with pagination
✍️ Writing Health Data Write health records
🔄 Updating Health Records Native in-place record updates with preserved IDs
🗑️ Deleting Health Records Remove specific records by their IDs or within a date/time range
Aggregating Health Data Sum/Avg/Min/Max Aggregation

🎯 Requirements #

  • Flutter >=3.3.0
  • Dart >=3.9.2
  • Android SDK: API level 26+ (Android 8.0)
  • Kotlin: 1.9.0+
  • Java: 11+

🚀 Getting Started #

📦 Installation #

Add to your pubspec.yaml:

flutter pub add health_connector_hc_android

Or manually add:

dependencies:
  health_connector_hc_android: [latest_version]

⚙️ Android Setup #

AndroidManifest.xml Configuration

Update AndroidManifest.xml

Add Health Connect permissions and intent filter to android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <!-- Your existing configuration -->

        <!-- Health Connect intent filter -->
        <activity-alias
            android:name="ViewPermissionUsageActivity"
            android:exported="true"
            android:targetActivity=".MainActivity"
            android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
            <intent-filter>
                <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
            </intent-filter>
        </activity-alias>
    </application>

    <!-- Declare Health Connect permissions -->
    <!-- Read permissions -->
    <uses-permission android:name="android.permission.health.READ_STEPS" />
    <uses-permission android:name="android.permission.health.READ_WEIGHT" />

    <!-- Write permissions -->
    <uses-permission android:name="android.permission.health.WRITE_STEPS" />
    <uses-permission android:name="android.permission.health.WRITE_WEIGHT" />
</manifest>

Important: Add permissions for each health data type you plan to use.

Health Connect Availability

📚 Usage #

Import Package

import 'package:health_connector/health_connector.dart';

Create HealthConnectorHCClient Instance

final client = HealthConnectorHCClient();

Check Health Connect Availability

final status = await client.getHealthPlatformStatus();

switch (status) {
  case HealthPlatformStatus.available:
    print('Health Connect ready');
    break;
  case HealthPlatformStatus.installationOrUpdateRequired:
    print('Please install or update Health Connect');
    break;
  case HealthPlatformStatus.unavailable:
    print('Health Connect not supported on this device');
    break;
}

Check Health Platform Feature Status

final featureStatus = await client.getFeatureStatus(
  HealthPlatformFeature.readHealthDataInBackground,
);

if (featureStatus == HealthPlatformFeatureStatus.available) {
  // Request feature permission if needed
}

Permissions

Request Permissions
final permissions = [
  // Health data permissions
  HealthDataType.steps.readPermission,
  HealthDataType.steps.writePermission,
  HealthDataType.weight.readPermission,
  HealthDataType.weight.writePermission,
  // ...
  
  // Feature permissions
  HealthPlatformFeature.readHealthDataInBackground,
  HealthPlatformFeature.readHealthDataHistory,
  // ...
];

final results = await client.requestPermissions(permissions);

for (final result in results) {
  print('${result.permission}: ${result.status}');
}
Check All Granted Permissions
final grantedPermissions = await client.getGrantedPermissions();
print('Granted permissions: ${grantedPermissions.length}');
Revoke All Granted Permissions
await client.revokeAllPermissions();

Read Health Records

Read Health Record by ID
final recordId = HealthRecordId('existing-record-id');
final readRequest = HealthDataType.steps.readRecord(recordId);
final record = await client.readRecord(readRequest);

if (record != null) {
  print('Steps: ${record.count.value} from ${record.startTime} to ${record.endTime}');
} else {
  print('Record not found');
}
Read Multiple Health Records
final request = HealthDataType.steps.readRecords(
  startTime: DateTime.now().subtract(Duration(days: 7)),
  endTime: DateTime.now(),
  pageSize: 100,
);

final response = await client.readRecords(request);

for (final record in response.records) {
  print('Steps: ${record.count.value} from ${record.startTime} to ${record.endTime}');
}
Read Multiple Health Records with Pagination
var request = HealthDataType.steps.readRecords(
  startTime: DateTime.now().subtract(Duration(days: 30)),
  endTime: DateTime.now(),
  pageSize: 100,
);

var allRecords = <StepRecord>[];
var pageNumber = 1;

while (true) {
  final response = await client.readRecords(request);
  
  allRecords.addAll(response.records.cast<StepRecord>());
  
  if (response.nextPageRequest == null) {
    break;
  }
  
  request = response.nextPageRequest!;
  pageNumber++;
}

print('Total records fetched: ${allRecords.length}');

Write Health Records

Write Single Health Record
final stepRecord = StepRecord(
  id: HealthRecordId.none,
  startTime: DateTime.now().subtract(Duration(hours: 1)),
  endTime: DateTime.now(),
  count: Numeric(5000),
  metadata: Metadata.automaticallyRecorded(
    device: Device.fromType(DeviceType.phone),
  ),
);

final recordId = await client.writeRecord(stepRecord);
print('Record written with ID: $recordId');
Write Multiple Health Records
final records = [
  StepRecord(
    id: HealthRecordId.none,
    startTime: DateTime.now().subtract(Duration(hours: 2)),
    endTime: DateTime.now().subtract(Duration(hours: 1)),
    count: Numeric(3000),
    metadata: Metadata.automaticallyRecorded(
      device: Device.fromType(DeviceType.phone),
    ),
  ),
  DistanceRecord(
    id: HealthRecordId.none,
    startTime: DateTime.now().subtract(Duration(hours: 1)),
    endTime: DateTime.now(),
    distance: Length(5000),
    metadata: Metadata.automaticallyRecorded(
      device: Device.fromType(DeviceType.phone),
    ),
  ),
  // ...
];

final recordIds = await client.writeRecords(records);
print('Wrote ${recordIds.length} records');

Update Health Records

final recordId = HealthRecordId('existing-record-id');
final readRequest = HealthDataType.steps.readRecord(recordId);
final existingRecord = await client.readRecord(readRequest);

if (existingRecord != null) {
  final updatedRecord = existingRecord.copyWith(
    startTime: existingRecord.startTime,
    endTime: existingRecord.endTime,
    count: Numeric(existingRecord.count.value + 100),
    metadata: existingRecord.metadata,
  );

  final updatedId = await client.updateRecord(updatedRecord);
  
  print('Original ID: $recordId');
  print('Updated ID: $updatedId');
  // originalId == updatedId on Android
}

Delete Health Records

Delete Health Records by IDs
await client.deleteRecordsByIds(
  dataType: HealthDataType.steps,
  recordIds: [
    HealthRecordId('id-1'),
    HealthRecordId('id-2'),
  ],
);

print('Records deleted');
Delete Health Records by Date Range
await client.deleteRecords(
  dataType: HealthDataType.steps,
  startTime: DateTime.now().subtract(Duration(days: 7)),
  endTime: DateTime.now(),
);

print('Records deleted');

Aggregate Health Data

final sumRequest = HealthDataType.steps.aggregateSum(
  startTime: DateTime.now().startOfDay,
  endTime: DateTime.now(),
);

final sumResponse = await client.aggregate(sumRequest);
print('Total steps today: ${sumResponse.value.value}');

final avgRequest = HealthDataType.weight.aggregateAvg(
  startTime: DateTime.now().subtract(Duration(days: 30)),
  endTime: DateTime.now(),
);

final avgResponse = await client.aggregate(avgRequest);
print('Average weight: ${avgResponse.value.inKilograms} kg');

final minRequest = HealthDataType.weight.aggregateMin(
  startTime: DateTime.now().subtract(Duration(days: 30)),
  endTime: DateTime.now(),
);
final minResponse = await client.aggregate(minRequest);
print('Min weight: ${minResponse.value.inKilograms} kg');

final maxRequest = HealthDataType.weight.aggregateMax(
  startTime: DateTime.now().subtract(Duration(days: 30)),
  endTime: DateTime.now(),
);
final maxResponse = await client.aggregate(maxRequest);
print('Max weight: ${maxResponse.value.inKilograms} kg');

📋 Supported Health Data Types #

Note: For a complete list of all Health Connect data types, see the official Health Connect documentation.

🏃 Activity #

Data Type Supported Documentation
Steps StepsRecord
Distance DistanceRecord
Active Calories Burned ActiveCaloriesBurnedRecord
Floors Climbed FloorsClimbedRecord
Wheelchair Pushes WheelchairPushesRecord
Exercise Session ExerciseSessionRecord
Total Calories Burned TotalCaloriesBurnedRecord
Cycling Pedaling Cadence CyclingPedalingCadenceRecord
Power PowerRecord
Speed SpeedRecord

📏 Body Measurements #

Data Type Supported Documentation
Weight WeightRecord
Height HeightRecord
Body Fat Percentage BodyFatRecord
Lean Body Mass LeanBodyMassRecord
Bone Mass BoneMassRecord
Basal Metabolic Rate BasalMetabolicRateRecord

🩸 Cycle Tracking / Reproductive Health #

Data Type Supported Documentation
Menstruation Flow MenstruationFlowRecord
Cervical Mucus CervicalMucusRecord
Ovulation Test OvulationTestRecord
Basal Body Temperature BasalBodyTemperatureRecord
Sexual Activity SexualActivityRecord

🍎 Nutrition #

Data Type Supported Documentation
Hydration / Water HydrationRecord
Nutrition / Dietary Energy NutritionRecord

😴 Sleep #

Data Type Supported Documentation
Sleep Session SleepSessionRecord
Sleep Stage SleepStageRecord

❤️ Vitals #

Data Type Supported Documentation
Heart Rate (Series) HeartRateSeriesRecord
Resting Heart Rate RestingHeartRateRecord
Blood Pressure BloodPressureRecord
Body Temperature BodyTemperatureRecord
Oxygen Saturation OxygenSaturationRecord
Respiratory Rate RespiratoryRateRecord
Vo2 Max Vo2MaxRecord
Blood Glucose BloodGlucoseRecord

🧘 Wellness / Mental Health #

Data Type Supported Documentation
Mindfulness Session MindfulnessSessionRecord

🤝 Contributing #

Contributions are welcome!

To report issues or request features, please visit our GitHub Issues.

4
likes
160
points
528
downloads

Publisher

unverified uploader

Weekly Downloads

Android implementation of health_connector using Health Connect

Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter, health_connector_core, health_connector_logger, meta

More

Packages that depend on health_connector_hc_android

Packages that implement health_connector_hc_android