Julian
Julian

Reputation: 41

Flutter HEALTH package get steps from user returns always null?

I am working on a personal project and I am using flutter to develop an app (cross platform) that reads in the user's health data from google fit (Android) or Apple Health. I am using this package and even the EXACT same code like in the documentation (I am currently only testing on Android):

Future fetchStepData() async {
    int? steps;

    // get steps for today (i.e., since midnight)
    final now = DateTime.now();
    final midnight = DateTime(now.year, now.month, now.day);

    bool requested = await health.requestAuthorization([HealthDataType.STEPS]);

    if (requested) {
      try {
        steps = await health.getTotalStepsInInterval(midnight, now);
      } catch (error) {
        print("Caught exception in getTotalStepsInInterval: $error");
      }

      print('Total number of steps: $steps');

      setState(() {
        _nofSteps = (steps == null) ? 0 : steps;
        _state = (steps == null) ? AppState.NO_DATA : AppState.STEPS_READY;
      });
    } else {
      print("Authorization not granted - error in authorization");
      setState(() => _state = AppState.DATA_NOT_FETCHED);
    }
  }

Then I am calling this function with await and I also have inserted the correct permission in all Android Manifest files:

Also I set up an OAuth2 Client ID for the project and added my google account as a test user.

BUT THE FUNCTION SETS THE VARIABLE STEPS ALWAYS TO NULL? The boolean variable "requested" is true, so it seems like the actual connection is working?

I am really disappointed by myself guys and I really need help - THANK YOU!

I tried adding the correct android permissions, asking for permissions explicitly, different time intervalls but nothing worked for me, I always got a null value back.

Upvotes: 0

Views: 1397

Answers (2)

Amit Sharma
Amit Sharma

Reputation: 1

Im using above mentioned but still not getting permission for Health Data.

is there any other way to get proper response.

  Future fetchData() async {
// Example: Check and request permissions
await _checkAndRequestPermissions();
await ref.read(googleLoginProvider.notifier).login();

// configure the health plugin before use.
// HealthFactory().configure();

/// Get everything from midnight until now
final DateTime startDate = DateTime(2020, 11, 07, 0, 0, 0);
final DateTime endDate = DateTime(2025, 11, 07, 23, 59, 59);

final HealthFactory health = HealthFactory();
// final HealthFactory health = HealthFactory(useHealthConnectIfAvailable: true);

/// Define the types to get.
final List<HealthDataType> types = [
  HealthDataType.STEPS,
  HealthDataType.HEIGHT,
  // HealthDataType.WEIGHT,
  // HealthDataType.BLOOD_GLUCOSE,
  // HealthDataType.DISTANCE_WALKING_RUNNING,
];

setState(() => _state = AppState.FETCHING_DATA);

/// You MUST request access to the data types before reading them
final bool accessWasGranted = await health.requestAuthorization(types);
log("Authorization result: $accessWasGranted");
int steps = 0;

if (accessWasGranted) {
  try {
    /// Fetch new data
    final List<HealthDataPoint> healthData =
        await health.getHealthDataFromTypes(startDate, endDate, types);

    /// Save all the new data points
    _healthDataList.addAll(healthData);
  } catch (e) {
    log("Caught exception in getHealthDataFromTypes: $e");
  }

  /// Filter out duplicates
  _healthDataList = HealthFactory.removeDuplicates(_healthDataList);

  /// log the results
  for (final x in _healthDataList) {
    log("Data point: $x");
    steps += x.value.round();
  }

  log("Steps: $steps");

  /// Update the UI to display the results
  setState(() {
    _state =
        _healthDataList.isEmpty ? AppState.NO_DATA : AppState.DATA_READY;
  });
} else if (!accessWasGranted) {
  log("Authorization not granted");
  log("User did not grant access to health data. Please enable permissions 
        in the settings.");
  setState(() => _state = AppState.DATA_NOT_FETCHED);
 }
}

& check request permission is

Future<void> _checkAndRequestPermissions() async {
if (Platform.isAndroid) {
  final PermissionStatus activityRecognitionStatus =
      await Permission.activityRecognition.status;
  final PermissionStatus bodySensorsStatus =
      await Permission.sensors.status;
  if (activityRecognitionStatus.isDenied || bodySensorsStatus.isDenied) {
    // If permissions are denied, request them
    await [
      Permission.activityRecognition,
      Permission.sensors,
    ].request();
  }
 }
}

Upvotes: 0

Zofi96
Zofi96

Reputation: 51

I had a similar problem. Adding a Google login with specified scope helped. I first log the user in with the code:

class LoginController extends GetxController {
  final _googleSignIn = GoogleSignIn(scopes: ["https://www.googleapis.com/auth/fitness.activity.read"]);
  var googleAccount = Rx<GoogleSignInAccount?>(null);

  login() async {
    googleAccount.value = await _googleSignIn.signIn();
  }
}

I then retrieve the data using code:

  getSteps() async {
    await Permission.activityRecognition.request();

    HealthFactory health = HealthFactory();

    // define the types to get
    var types = [
      HealthDataType.STEPS,
    ];

    // requesting access to the data types before reading them
    bool requested = await health.requestAuthorization(types);

    var now = DateTime.now();
    var steps = await health.getTotalStepsInInterval(now.subtract(Duration(days: 1)), now);
  }

Upvotes: 0

Related Questions