Flutter: Попытка получить доступ к данным о местоположении в фоновом режиме с помощью плагина location и workManager - PullRequest
0 голосов
/ 12 марта 2020

Краткое описание проблемы: при попытке доступа к данным о местоположении пользователя в фоновом режиме с помощью плагина location и workManager. В настоящее время с кодом, упомянутым ниже, я могу получить доступ к информации о местоположении, если приложение открыто, так как callbackDispatcher - это функция верхнего уровня, я не могу вызвать плагин местоположения. Плагин местоположения работает, когда вызов сделан внутри класса. Я пытаюсь получить доступ к _getlocation () из callbackDispatcher, я получаю PlatformException (NO_ACTIVITY).

То, что я пробовал: найдено несколько других парней, сталкивающихся с подобной проблемой здесь , здесь и здесь Устали от всех этих шагов и не повезло.

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"),
        ),
      ]),
    );
  }
}

Попытка доступа к _getlocation () из callbackDispatcher (); Любая помощь в этом очень ценится.

1 Ответ

0 голосов
/ 19 марта 2020

Недавно я столкнулся с той же проблемой. пакет местоположений не работает с плагином 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, когда приложение онлайн ..

I надеюсь, это поможет ..

...