Приложение Flutter navigator работает с эмулятором, но не работает на реальном устройстве

#android #flutter #dart #geolocation #flutter-dependencies

#Android #flutter #dart #геолокация #flutter-зависимости

Вопрос:

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

 Android 9
API level 28
compileSdkVersion 30
minSdkVersion 16
targetSdkVersion 29
 

Код

 import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/great_places.dart';
import 'package:yandex_mapkit/yandex_mapkit.dart';
import 'package:geolocator/geolocator.dart';
import '../helpers/db_helper.dart';

class PlacesListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return _Map();
  }
}

class _Map extends StatefulWidget {
  @override
  _MapState createState() => _MapState();
}

class _MapState extends State<_Map> {
  YandexMapController controller;
  Placemark _lastMarkedPoint;
  Placemark _lastMarkedUserPoint;
  double _zoom;
  StreamSubscription _locationSubscription;
  Position _currentLocation;
  Timer zoomDeleteTimer;
  Timer zoomTimer;
  Timer cameraTimer;

  Future<Position> _determineLocation() async {
    bool serviceEnabled;
    LocationPermission permission;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.deniedForever) {
      return Future.error(
          'Location permissions are permantly denied, we cannot request permissions.');
    }

    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission != LocationPermission.whileInUse amp;amp;
          permission != LocationPermission.always) {
        return Future.error(
            'Location permissions are denied (actual value: $permission).');
      }
    }

    return await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high,
    );
  }

  _listenLocation() {
    _locationSubscription = Geolocator.getPositionStream(
      desiredAccuracy: LocationAccuracy.high,
      distanceFilter: 1,
    ).listen((Position position) async {
      if (position != null) {
        if (controller != null) {
          print("SET USER POSITION");
          controller.enableCameraTracking(
            null,
            cameraPositionChanged,
          );
        }
        _setUserLocation(
          Point(
            latitude: position.latitude,
            longitude: position.longitude,
          ),
        );
        print("Updated Position: "   position.toString());
      }
    });
  }

  Future<void> fetchZoomHistory() async {
    print("ZOOM HISTORY DATABASE");
    final zoomList = await DBHelper.getData('zoom_history');
    print(zoomList);
    if (zoomList != null amp;amp; zoomList.length > 0) {
      setState(() {
        _zoom = double.parse(zoomList[0]['zoom']);
      });
    } else {
      setState(() {
        _zoom = 12.4;
      });
    }
  }

  Future<void> clearZoomHistory() async {
    await DBHelper.delete('zoom_history');
    print("ZOOM HISTORY DELETED");
  }

  @override
  void initState() {
    super.initState();

    _determineLocation().then((value) {
      setState(() {
        _currentLocation = value;
      });
    });
    _listenLocation();

    fetchZoomHistory();
  }

  Future<void> _setUserLocation(Point point, [setMark = true]) async {
    await controller.enableCameraTracking(
      null,
      cameraPositionChanged,
    );
    await controller.removePlacemark(_lastMarkedUserPoint);

    if (setMark == true) {
      var placemark = Placemark(
        point: point,
        opacity: 0.8,
        iconName: 'lib/assets/arrow_blue.png',
      );

      _lastMarkedUserPoint = placemark;
      await controller.addPlacemark(placemark);
    }

    await controller.move(
      point: point,
      zoom: _zoom,
      animation: const MapAnimation(smooth: true),
    );
  }

  Future<void> cameraPositionChanged(dynamic arguments) async {
    if (zoomTimer != null) zoomTimer.cancel();
    var zoom = arguments['zoom'];
    if (_zoom != zoom) {
      _zoom = zoom;
      zoomTimer =
          Timer.periodic(const Duration(milliseconds: 2000), (zoomTimer) async {
        await clearZoomHistory();
        print(zoom);
        DBHelper.insert('zoom_history', {
          'zoom': zoom,
        });
        zoomTimer.cancel();
      });
    }
  }

  void _setPlacesMark(YandexMapController controller, places) async {
    for (var i = 0; i < places.items.length; i  ) {
      var point = Point(
        latitude: places.items[i].latitude,
        longitude: places.items[i].longitude,
      );
      var placemark = Placemark(
        point: point,
        opacity: 0.8,
        iconName: 'lib/assets/tire4.png',
      );
      await controller.addPlacemark(placemark);
    }
  }

  Future<void> addPlaceMark(Point point, YandexMapController controller) async {
    if (_lastMarkedPoint != null) {
      await controller.removePlacemark(_lastMarkedPoint);
    }

    var placemark = Placemark(
      point: point,
      opacity: 0.7,
      iconName: 'lib/assets/place_red2.png',
    );

    _lastMarkedPoint = placemark;

    await controller.addPlacemark(placemark);
  }

  static const Point _point = Point(latitude: 59.939095, longitude: 30.315868);

  @override
  void dispose() {
    if (_locationSubscription != null) {
      _locationSubscription.cancel();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Navigator'),
      ),
      body: FutureBuilder(
        future: Provider.of<GreatPlaces>(context, listen: false)
            .fetchAndSetPlaces(),
        builder: (ctx, snapshot) => snapshot.connectionState ==
                ConnectionState.waiting
            ? Center(
                child: CircularProgressIndicator(),
              )
            : Consumer<GreatPlaces>(
                child: Center(
                  child: const Text('Places got not yet'),
                ),
                builder: (ctx, greatPlaces, ch) => greatPlaces.items.length <= 0
                    ? YandexMap(
                        onMapCreated:
                            (YandexMapController yandexMapController) async {
                          controller = yandexMapController;
                          Point setPoint;
                          if (_currentLocation != null) {
                            setPoint = Point(
                              latitude: _currentLocation.latitude,
                              longitude: _currentLocation.longitude,
                            );

                            await _setUserLocation(setPoint);
                          } else {
                            await _setUserLocation(setPoint, false);
                          }
                        },
                        onMapTap: (Point point) async {
                          await addPlaceMark(point, controller);
                        },
                      )
                    : YandexMap(
                        onMapCreated:
                            (YandexMapController yandexMapController) async {
                          controller = yandexMapController;
                          Point setPoint;
                          if (_currentLocation != null) {
                            setPoint = Point(
                              latitude: _currentLocation.latitude,
                              longitude: _currentLocation.longitude,
                            );

                            await _setUserLocation(setPoint);
                          } else {
                            await _setUserLocation(setPoint, false);
                          }
                          _setPlacesMark(controller, greatPlaces);
                        },
                        onMapTap: (Point point) async {
                          await addPlaceMark(point, controller);
                        },
                      ),
              ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          FloatingActionButton(
            onPressed: () async {
              await controller.zoomIn();
            },
            child: Icon(Icons.add, color: Colors.white),
            backgroundColor: Colors.green,
            heroTag: 'mapZoomIn',
          ),
          FloatingActionButton(
            onPressed: () async {
              await controller.zoomOut();
            },
            child: Icon(Icons.remove, color: Colors.white),
            backgroundColor: Colors.green,
            heroTag: 'mapZoomOut',
          ),
          FloatingActionButton(
            onPressed: () {
              _determineLocation().then((value) {
                _currentLocation = value;
                _setUserLocation(Point(
                  latitude: value.latitude,
                  longitude: value.longitude,
                ));
              });
            },
            child: Icon(Icons.place, color: Colors.white),
            backgroundColor: Colors.green,
            heroTag: 'showUserLocation',
          ),
          FloatingActionButton(
            onPressed: () async {
              await controller.move(
                point: _point,
                zoom: _zoom,
              );
            },
            child: Icon(Icons.home, color: Colors.white),
            backgroundColor: Colors.green,
            heroTag: 'mapGoToHome',
          ),
        ],
      ),
    );
  }
}
 

Результат

 <blockquote class="imgur-embed-pub" lang="en" data-id="lUY0L7h"  ><a href="//imgur.com/lUY0L7h">Navigator App</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script> 

Почему оно не работает на реальном устройстве правильно?

Загрузите APK здесь для тестирования

Комментарии:

1. Что происходит на реальном устройстве?

2. Местоположение и GPS включены на реальном устройстве??

3. На реальном устройстве не обнаружено местоположение, также кнопки местоположение пользователя и кнопка home. История масштабирования также не сохраняется в моем случае. @SergeyGlotov

4. Местоположение и GPS включены @MRazaImtiaz