即使位置是静态的(颤振),位置 onChange 函数也会不断被调用
Posted
技术标签:
【中文标题】即使位置是静态的(颤振),位置 onChange 函数也会不断被调用【英文标题】:location onChange function keeps getting called even when location is static (Flutter) 【发布时间】:2020-03-29 20:07:09 【问题描述】:我正在使用 Flutter 中的 Location 3.0.1 包。我想听位置变化。我的代码(几乎完全取自这个包的 github 示例)如下:
class _HomePageState extends State<HomePage>
StreamSubscription<LocationData> locationSubscription;
final Location location = new Location();
LocationData _locationData;
String _error;
var popupData;
PermissionStatus _permissionGranted;
_checkPermissions() async
PermissionStatus permissionGrantedResult = await location.hasPermission();
setState(()
_permissionGranted = permissionGrantedResult;
);
_requestPermission() async
if (_permissionGranted != PermissionStatus.GRANTED)
PermissionStatus permissionRequestedResult =
await location.requestPermission();
print(permissionRequestedResult);
setState(()
_permissionGranted = permissionRequestedResult;
);
if (permissionRequestedResult != PermissionStatus.GRANTED)
return;
else
_loadLocation();
else
_loadLocation();
Future<void> _listenLocation() async
locationSubscription =
location.onLocationChanged().handleError((dynamic err)
setState(()
_error = err.code;
);
locationSubscription.cancel();
).listen((LocationData currentLocation)
setState(()
_error = null;
_locationData = currentLocation;
);
);
void _loadLocation() async
_locationData = await location.getLocation();
_listenLocation();
void initState()
super.initState();
@override
Widget build(BuildContext context)
if(_locationData == null)
_checkPermissions();
_requestPermission();
. . .
但是,即使位置没有改变(我是在我的模拟器上运行此代码,因此位置应该是静态的)。有谁知道为什么会发生这种情况以及如何解决?
颤振医生的输出:
[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.2 19C57, locale en-US)
• Flutter version 1.12.13+hotfix.5 at /Users/foo/development/flutter
• Framework revision 27321ebbad (4 months ago), 2019-12-10 18:15:01 -0800
• Engine revision 2994f7e1e6
• Dart version 2.7.0
[✓] android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at /Users/foo/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.
[✓] Xcode - develop for ios and macOS (Xcode 11.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 11.3, Build version 11C29
• CocoaPods version 1.8.4
[✓] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 39.0.3
• Dart plugin version 191.8423
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] IntelliJ IDEA Ultimate Edition (version 2019.1.4)
• IntelliJ at /Applications/IntelliJ IDEA.app
• Flutter plugin version 38.1.3
• Dart plugin version 191.8593
[✓] Connected device (2 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)
• iPhone 11 Pro Max • B3536B50-C435-4442-9CF4-69D470B979CA • ios •
com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)
• No issues found!
如果有人可以给我一段代码,展示如何正确侦听更新,那也会很有帮助(即我的代码看起来并不像这样)。
【问题讨论】:
【参考方案1】:您可以在下面复制粘贴运行完整代码
因为您将代码放在 Widget build
中导致此问题
您可以参考此https://medium.com/flutter-community/build-a-location-service-in-flutter-367a1b212f7a 来构建位置服务
我做了一些改动,你可以直接看到完整的代码
您可以在Widget build
中使用StreamProvider
而不是await location.getLocation
你可以直接用location.requestPermission
代替Permission Handler
代码片段
return StreamProvider<UserLocation>(
create: (context) => LocationService().locationStream,
...
LocationService()
// Request permission to use location
location.requestPermission().then((permissionStatus)
if (permissionStatus == PermissionStatus.granted)
// If granted listen to the onLocationChanged stream and emit over our controller
location.onLocationChanged.listen((locationData)
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:location/location.dart';
import 'dart:async';
class LocationService
UserLocation _currentLocation;
var location = Location();
StreamController<UserLocation> _locationController =
StreamController<UserLocation>();
Stream<UserLocation> get locationStream => _locationController.stream;
LocationService()
// Request permission to use location
location.requestPermission().then((permissionStatus)
if (permissionStatus == PermissionStatus.granted)
// If granted listen to the onLocationChanged stream and emit over our controller
location.onLocationChanged.listen((locationData)
if (locationData != null)
_locationController.add(UserLocation(
latitude: locationData.latitude,
longitude: locationData.longitude,
));
);
);
Future<UserLocation> getLocation() async
try
var userLocation = await location.getLocation();
_currentLocation = UserLocation(
latitude: userLocation.latitude,
longitude: userLocation.longitude,
);
on Exception catch (e)
print('Could not get location: $e.toString()');
return _currentLocation;
void main()
runApp(MyApp());
class UserLocation
final double latitude;
final double longitude;
UserLocation(this.latitude, this.longitude);
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return StreamProvider<UserLocation>(
create: (context) => LocationService().locationStream,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: HomeView(),
)),
);
class HomeView extends StatelessWidget
const HomeView(Key key) : super(key: key);
@override
Widget build(BuildContext context)
var userLocation = Provider.of<UserLocation>(context);
return Center(
child: Text(
'Location: Lat$userLocation?.latitude, Long: $userLocation?.longitude'),
);
【讨论】:
以上是关于即使位置是静态的(颤振),位置 onChange 函数也会不断被调用的主要内容,如果未能解决你的问题,请参考以下文章