如何让 Flutter Workmanager 插件和 Location 插件一起工作 [英] How to make Flutter Workmanager plugin and Location plugin work together

查看:42
本文介绍了如何让 Flutter Workmanager 插件和 Location 插件一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

1.问题描述

我的目标是构建一个 Flutter 应用程序,该应用程序使用 这个工作管理器插件 并使用 <一个 href="https://pub.dev/packages/location" rel="noreferrer">这个位置插件.但是当我的 Workmanager 回调触发时,我无法正确加载位置插件.我收到此错误:

My goal is to build a Flutter app that gets periodic location updates using this workmanager plugin and using this location plugin. But I can't get the Location plugin to be loaded properly when my Workmanager callback fires. I get this error:

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

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

So basically, the problem is that when the Workmanager plugin tries to run dart code, it doesn't load up the Location plugin.

2.我研究过的其他资源

我发现其他人也面临同样的问题,此处此处,和这里.

I found others facing the same issue, here, here, and here.

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

As far as I understand, the solution provided to these questions boils down to: create a file named CustomApplication.java, which extends FlutterApplication, and which registers your plugin(s). And then register the CustomApplication.java file inside you AndoidManifest.xml file.

3.到目前为止我的代码

我试图制作一个实现我需要的功能的最低限度的应用程序:

I have tried to make a bare-minimum app that implements the features I require:

  1. 我实现了 Workmanager 插件(工作正常)
  2. 我实现了位置插件(工作正常)
  3. 我试图结合这些功能(不起作用)

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

To see exactly what I have done at each step, please look here: https://gitlab.com/tomoerlemans/workmanager_with_location/-/commits/master. (This repository can also be used to quickly replicate the issue).

相关代码文件如下:

ma​​in.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:

Finally, I am running the following versions of 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 + geolocator 会起作用.你应该看到这个项目 ha_client 它正在使用 workmanager 和 geolocater 来获取坐标

I haven't tried what background location tracking but considering you only want location tracking from background then I think workmanager + geolocater would work. You should see this project ha_client it's using workmanager and geolocater together to get the coords

此外,您使用的位置包也有自己的背景位置跟踪,这是在实验中 背景位置更新.

Also the location package you're using has it's own background location tracking which is in experimental Background Location Updates.

这篇关于如何让 Flutter Workmanager 插件和 Location 插件一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆