android - 如何让 Flutter Workmanager 插件和 Location 插件一起工作

标签 android flutter dart flutter-dependencies android-workmanager

1.问题描述

我的目标是构建一个使用 this workmanager plugin 获取定期位置更新的 Flutter 应用程序。并使用 this location plugin .但是当我的 Workmanager 回调触发时,我无法正确加载 Location 插件。我收到此错误:

MissingPluginException(No implementation found for method getLocation on channel lyokone/location)

所以基本上,问题是当 Workmanager 插件尝试运行 dart 代码时,它不会加载 Location 插件。

2.我研究过的其他资源

我发现其他人面临同样的问题,here , here , 和 here .

据我了解,为这些问题提供的解决方案归结为:创建一个名为 CustomApplication.java 的文件,该文件扩展了 FlutterApplication,并注册了您的插件。然后在 AndoidManifest.xml 文件中注册 CustomApplication.java 文件。

3. 到目前为止我的代码

我试图制作一个实现我需要的功能的最低限度的应用程序:
  • 我实现了 Workmanager 插件(工作正常)
  • 我实现了位置插件(工作正常)
  • 我试图结合这些功能(不起作用)

  • 要准确了解我在每个步骤中所做的工作,请查看此处:https://gitlab.com/tomoerlemans/workmanager_with_location/-/commits/master . (此存储库也可用于快速复制问题)。

    相关代码文件如下:

    main.dart
    import 'package:flutter/material.dart';
    import 'package:workmanager/workmanager.dart';
    import 'package:location/location.dart';
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      Workmanager.initialize(callbackDispatcher, isInDebugMode: true);
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                  onPressed: () {
                    Workmanager.registerPeriodicTask(
                        "1", "simpleTask");
                  },
                  child: Text("Start workmanager"),
                ),
                RaisedButton(
                  onPressed: () {
                    getLocation();
                  },
                  child: Text("Get current location"),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    void callbackDispatcher() {
      Workmanager.executeTask((task, inputData) {
        print("Native called background task at ${DateTime.now().toString()}");
        getLocation();
        return Future.value(true);
      });
    }
    
    void getLocation() async {
      LocationData currentLocation;
      var location = new Location();
      try {
        currentLocation = await location.getLocation();
      } on Exception catch (e) {
        print("Error obtaining location: $e");
        currentLocation = null;
      }
      print("Location altitude: ${currentLocation.altitude}");
      print("Location longitude: ${currentLocation.longitude}");
    }
    

    pubspec.yaml
    name: background_location
    description: A new Flutter project.
    
    version: 1.0.0+1
    
    environment:
      sdk: ">=2.1.0 <3.0.0"
    
    dependencies:
      flutter:
        sdk: flutter
    
      cupertino_icons: ^0.1.2
      workmanager: ^0.2.0
      location: ^2.3.5
    
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
    
    flutter:
      uses-material-design: true
    

    CustomApplication.java
    package io.flutter.plugins;
    
    import io.flutter.app.FlutterApplication;
    import io.flutter.plugin.common.PluginRegistry;
    import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
    import io.flutter.plugins.GeneratedPluginRegistrant;
    import be.tramckrijte.workmanager.WorkmanagerPlugin;
    import com.lyokone.location.LocationPlugin;
    
    public class CustomApplication extends FlutterApplication implements PluginRegistry.PluginRegistrantCallback {
        @Override
        public void onCreate() {
            super.onCreate();
            WorkmanagerPlugin.setPluginRegistrantCallback(this);
    
        }
        @Override
        public void registerWith(PluginRegistry registry) {
            WorkmanagerPlugin.registerWith(registry.registrarFor("be.tramckrijte.workmanager.WorkmanagerPlugin"));
            LocationPlugin.registerWith(registry.registrarFor("com.lyokone.location.LocationPlugin"));
        }
    }
    

    AndroidManifest.xml
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.background_location">        
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
        <application
            android:name="io.flutter.plugins.CustomApplication"
            android:label="background_location"
            android:icon="@mipmap/ic_launcher">
            <activity
                android:name=".MainActivity"
                android:launchMode="singleTop"
                android:theme="@style/LaunchTheme"
                android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
                android:hardwareAccelerated="true"
                android:windowSoftInputMode="adjustResize">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
            <meta-data
                android:name="flutterEmbedding"
                android:value="2" />
        </application>
    </manifest>
    

    最后,我正在运行以下版本的 Dart/Flutter/etc:
    Flutter 1.12.13+hotfix.5 • channel stable • https://github.com/flutter/flutter.git
    Framework • revision 27321ebbad (10 weeks ago) • 2019-12-10 18:15:01 -0800
    Engine • revision 2994f7e1e6
    Tools • Dart 2.7.0
    

    最佳答案

    我还没有尝试过什么后台位置跟踪,但考虑到你只想从后台进行位置跟踪,那么我认为 workmanager + geolocater会工作。
    你应该看到这个项目ha_client它同时使用 workmanager 和 geolocater 来获取坐标

    此外,您正在使用的位置包有它自己的后台位置跟踪,这是实验性的 Background Location Updates .

    关于android - 如何让 Flutter Workmanager 插件和 Location 插件一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60262425/

    相关文章:

    dart - AngularDart的角度组件的应用布局

    android - flutter :如果我想导航到详细信息页面,则会收到无效的论据错误

    java - 画廊 相机 Intent

    java - 安排事件在 2 小时后运行

    android - 如何使用观察者使用 ViewPager 中当前项目位置的值来验证 EditText 中的值?

    flutter - setState在futureBuilder中

    Dart http_server 服务 index.html 但不拉依赖

    java - Android 客户端-服务器应用程序和 Web 服务

    flutter - 函数返回 Future<String> 的实例而不是 String

    flutter - 合并列表中的信息