cph-cachet / flutter-plugins

A collection of Flutter plugins developed by CACHET
540 stars 648 forks source link

[health]: MissingPluginException (MissingPluginException(No implementation found for method requestAuthorization on channel flutter_health)) #97

Closed Ahmedibrahim66 closed 4 years ago

Ahmedibrahim66 commented 4 years ago

Hello, trying to fetch the to data from the google fit app in the background using this dependency health: ^1.0.2+2

i am trying to run method this method in the background in a periodic time,

void _getHealthDataPoints() async {

    List<HealthDataType> types = [
        HealthDataType.WEIGHT,
        HealthDataType.HEIGHT,
        HealthDataType.STEPS,
    ];

    DateTime startDate = DateTime.utc(2001, 01, 01);
    DateTime endDate = DateTime.now();

    List<HealthDataPoint> healthDataList = List<HealthDataPoint>();

    Future.delayed(Duration(seconds: 2), () async {
        bool isAuthorized = await Health.requestAuthorization();
        if (isAuthorized) {
            for (HealthDataType type in types) {
                /// Calls to 'Health.getHealthDataFromType' must be wrapped in a try catch block.
                try {
                    List<HealthDataPoint> healthData = await Health.getHealthDataFromType(startDate, endDate, type);
                    healthDataList.addAll(healthData);
                } catch (exception) {
                    print(exception.toString());
                }
            }
        }
        /// Do something with the health data list
        for (var healthData in healthDataList) {
            print(healthData);
        }
    });
}

i am calling it using this function that is called after runApp using AndroidalarmManager

void sendData() async {

 final DateTime now = DateTime.now();

 // get the data from the fit app

  _getHealthDataPoints();
   final int isolateId = Isolate.current.hashCode;
   print("[$now] Hello, world! isolate=${isolateId} function='$sendData'");
}

in the isAuthorized call i get a
MissingPluginException (MissingPluginException(No implementation found for method requestAuthorization on channel flutter_health))

1321

when calling the function from a button inside the scafold it works as expected

Flutter doctor image

i am using xiaomi Mi 9T

thomasnilsson commented 4 years ago

I doubt this is an issue with the plugin, do you have your application code hosted somewhere?

thomasnilsson commented 4 years ago

And also, a new version is out, try that and see if it works

AmrMonzir commented 3 years ago

I am facing the same problem, I have a simple application to get health data points in the previous day and uploads it to Google Sheet, with Workmanager package to schedule a task to run it every day at a set time. The code to get data points and uploading works fine, but when it is run in the background, it fails to get authorization and leaves. Any help for that? Pasted exception below.

flutter doctor -v
[√] Flutter (Channel stable, 1.22.4, on Microsoft Windows [Version 10.0.18363.1198], locale en-US)
    • Flutter version 1.22.4 at F:\flutter
    • Framework revision 1aafb3a8b9 (3 weeks ago), 2020-11-13 09:59:28 -0800
    • Engine revision 2c956a31c0
    • Dart version 2.10.4

[√] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
    • Android SDK at C:\Users\amrmo\AppData\Local\Android\sdk
    • Platform android-30, build-tools 30.0.1
    • ANDROID_HOME = C:\Users\amrmo\AppData\Local\Android\sdk
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[!] Android Studio (version 4.1.0)
    • Android Studio at C:\Program Files\Android\Android Studio
    X Flutter plugin not installed; this adds Flutter specific functionality.
    X Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[√] VS Code, 64-bit edition (version 1.51.1)
    • VS Code at C:\Program Files\Microsoft VS Code
    • Flutter extension version 3.16.0

[√] Connected device (1 available)
    • SM G950F (mobile) • ce0517153912091d02 • android-arm64 • Android 8.0.0 (API 26)

! Doctor found issues in 1 category.

Never mind the plugin not installed error, it is an error with the new Android Studio version that does nothing.

E/flutter ( 8793): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: MissingPluginException(No implementation found for method requestAuthorization on channel flutter_health)
E/flutter ( 8793): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:157:7)
E/flutter ( 8793): <asynchronous suspension>
E/flutter ( 8793): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:332:12)
E/flutter ( 8793): #2      HealthFactory.requestAuthorization (package:health/src/health_factory.dart:29:24)
E/flutter ( 8793): #3      HealthFactory.getHealthDataFromTypes (package:health/src/health_factory.dart:73:26)
E/flutter ( 8793): #4      HealthDataHelper.getHealthData (package:health_tracker/helpers/health_data_helper.dart:26:22)
E/flutter ( 8793): #5      SheetsHelper.getHealthData (package:health_tracker/helpers/sheets_helper.dart:28:65)
E/flutter ( 8793): #6      BackgroundTask.runTask (package:health_tracker/helpers/background_task.dart:9:24)
E/flutter ( 8793): #7      callbackDispatcher.<anonymous closure> (package:health_tracker/main.dart:35:20)
E/flutter ( 8793): #8      callbackDispatcher.<anonymous closure> (package:health_tracker/main.dart:26:27)
E/flutter ( 8793): #9      Workmanager.executeTask.<anonymous closure> (package:workmanager/src/workmanager.dart:80:28)
E/flutter ( 8793): #10     Workmanager.executeTask.<anonymous closure> (package:workmanager/src/workmanager.dart:78:45)
E/flutter ( 8793): #11     MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:430:55)
E/flutter ( 8793): #12     MethodChannel.setMethodCallHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:383:34)
E/flutter ( 8793): #13     _DefaultBinaryMessenger.handlePlatformMessage (package:flutter/src/services/binding.dart:283:33)
E/flutter ( 8793): #14     _invoke3.<anonymous closure> (dart:ui/hooks.dart:280:15)
E/flutter ( 8793): #15     _rootRun (dart:async/zone.dart:1190:13)
E/flutter ( 8793): #16     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter ( 8793): #17     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter ( 8793): #18     _invoke3 (dart:ui/hooks.dart:279:10)
E/flutter ( 8793): #19     _dispatchPlatformMessage (dart:ui/hooks.dart:154:5)

I would really appreciate help to get this to get authorization and work in the background.

kwnly commented 3 years ago

@AmrMonzir Hi, have you found any solution for this issue? Thanks!

AmrMonzir commented 3 years ago

@kwnly I found out that some plugins don't get registered automatically when the app runs in the background, and you have to register them by hand. In my case, I had to edit the generated java file to register all the plugins. Here's the code I used:

package io.flutter.plugins;
import io.flutter.plugin.common.PluginRegistry;
import com.transistorsoft.flutter.backgroundfetch.BackgroundFetchPlugin;
import io.flutter.plugins.deviceinfo.DeviceInfoPlugin;
import cachet.plugins.health.HealthPlugin;
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin;

public final class GeneratedPluginRegistrant {
  public static void registerWith(PluginRegistry registry) {
    if (alreadyRegisteredWith(registry)) {
      return;
    }
    BackgroundFetchPlugin.registerWith(registry.registrarFor("com.transistorsoft.flutter.backgroundfetch.BackgroundFetchPlugin"));
    DeviceInfoPlugin.registerWith(registry.registrarFor("io.flutter.plugins.deviceinfo.DeviceInfoPlugin"));
    HealthPlugin.registerWith(registry.registrarFor("cachet.plugins.health.HealthPlugin"));
    SharedPreferencesPlugin.registerWith(registry.registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"));
  }

  private static boolean alreadyRegisteredWith(PluginRegistry registry) {
    final String key = GeneratedPluginRegistrant.class.getCanonicalName();
    if (registry.hasPlugin(key)) {
      return true;
    }
    registry.registrarFor(key);
    return false;
  }
}