【问题标题】:Flutter: Trying to access location data in background using location and workManager pluginFlutter:尝试使用 location 和 workManager 插件在后台访问位置数据
【发布时间】:2020-06-24 12:02:55
【问题描述】:

问题简介: 尝试使用 location 和 workManager 插件在后台访问用户的位置数据。 目前使用下面提到的代码,如果应用程序打开,我可以访问位置信息,因为 callbackDispatcher 是顶级函数,我无法调用位置插件。 位置插件在类内完成调用时起作用。我正在尝试一种从 callbackDispatcher 访问 _getlocation() 的方法,我得到 PlatformException(NO_ACTIVITY)。

我尝试过的事情: 发现很少有其他人面临类似问题hereherehere 累了所有这些步骤,没有运气。

import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:workmanager/workmanager.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

Location location = new Location();

void callbackDispatcher() {
  Workmanager.executeTask((task, inputData) {
    if (task == "simplePeriodicTask") {
      print("task working");
      _getLocation();
    }
    return Future.value(true);
  });
}

LocationData _location;
String _error;
double lat;
double long;
_getLocation() async {
  _error = null;

  try {
    var _locationResult = await location.getLocation();

    _location = _locationResult;
    lat = _location.latitude;
    long = _location.longitude;
  } on PlatformException catch (err) {
    _error = err.code;
  }

  if (_error == null) {
    // _check();
    print(lat);
  } else {
    //dialog
    print(_error);
  }
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    Workmanager.initialize(
        callbackDispatcher, // The top level function, aka callbackDispatcher
        isInDebugMode:
            true // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
        );
    _checkPermissions();
  }

  // Permission for location
  PermissionStatus _permissionGranted;
  // final Location location = new Location();

  _checkPermissions() async {
    PermissionStatus permissionGrantedResult = await location.hasPermission();
    setState(() {
      _permissionGranted = permissionGrantedResult;
    });
    if (_permissionGranted == PermissionStatus.DENIED) {
      _requestPermission();
    } else if (_permissionGranted == PermissionStatus.GRANTED) {
      _checkService();
    }
  }

  _requestPermission() async {
    if (_permissionGranted != PermissionStatus.GRANTED) {
      PermissionStatus permissionRequestedResult =
          await location.requestPermission();
      setState(() {
        _permissionGranted = permissionRequestedResult;
      });
      if (permissionRequestedResult != PermissionStatus.GRANTED) {
        return;
      } else if (permissionRequestedResult == PermissionStatus.GRANTED) {
        _checkService();
      }
    }
  }
  //Permission ends

//services enabled function
  bool _serviceEnabled;
  _checkService() async {
    bool serviceEnabledResult = await location.serviceEnabled();
    setState(() {
      _serviceEnabled = serviceEnabledResult;
    });
    if (_serviceEnabled == false) {
      _requestService();
    } else {
      // _getLocation();
    }
  }

  _requestService() async {
    if (_serviceEnabled == null || !_serviceEnabled) {
      bool serviceRequestedResult = await location.requestService();
      setState(() {
        _serviceEnabled = serviceRequestedResult;
      });
      if (!serviceRequestedResult) {
        return;
      } else {
        // _getLocation();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dart'),
      ),
      body: Column(children: <Widget>[
        RaisedButton(
            child: Text('get Location'),
            onPressed: () {
              Workmanager.registerPeriodicTask(
                "2",
                "simplePeriodicTask",
                // When no frequency is provided the default 15 minutes is set.
                // Minimum frequency is 15 min. Android will automatically change your frequency to 15 min if you have configured a lower frequency.
              );
              print('task registered');
              _getLocation();
            }),
        RaisedButton(
          onPressed: () async {
            await Workmanager.cancelAll();
            print('task Destroyd');
          },
          child: Text("cancel"),
        ),
      ]),
    );
  }
}

试图从 callbackDispatcher() 访问 _getlocation(); 非常感谢您对此提供任何帮助。

【问题讨论】:

    标签: function flutter methods location workmanagers


    【解决方案1】:

    我最近遇到了同样的问题。位置包不适用于 WorkManager 插件,我不知道原因,但这是我的解决方案;

      /// This Function calls only from WorkManager 
      /// Used GeoLocator instead of Location package due to PlatformException(NO_ACTIVITY) error throwing
    
              Future<String> getPlaceMarkLocationWhileAppOff() async {
                Geolocator geoLocator = Geolocator()..forceAndroidLocationManager = true;
                var _position = await geoLocator.getCurrentPosition(
                    // desiredAccuracy: LocationAccuracy.high,
                    );
                var value = await geoLocator.placemarkFromCoordinates(_position.latitude, _position.longitude);
                return _placeMark = "${value.first.subLocality}\n${value.first.subAdministrativeArea}";
              }
    

    应用离线时使用Geolocator包,应用上线时使用Location包..

    我希望它会有所帮助..

    【讨论】:

      猜你喜欢
      • 2020-06-01
      • 2021-12-25
      • 2021-01-16
      • 1970-01-01
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多