Flutter地理围栏功能插件easy_geofencing的使用
Flutter地理围栏功能插件easy_geofencing的使用
easy_geofencing
是一个用于Flutter应用程序(Android和iOS)的地理围栏插件,它提供了地理围栏的功能。这个插件完全用纯Dart语言编写。
特性
- 根据位置变化触发地理围栏状态[初始化、进入、退出]。
- 获取连续的地理围栏状态更新。
- 优化的Dart代码。
- 对电池友好的Dart包。
使用方法
要将easy_geofencing
添加到你的Flutter应用中,请阅读安装说明。以下是确保easy_geofencing
在Android和iOS上正常工作的具体配置。
对于Android
AndroidX
easy_geofencing
插件需要AndroidX版本的Android支持库。这意味着你需要确保你的Android项目支持AndroidX。详细的指令可以在这里找到:AndroidX兼容性。
简短版是:
-
在你的
gradle.properties
文件中添加以下内容:android.useAndroidX=true android.enableJetifier=true
-
确保你在
android/app/build.gradle
文件中设置compileSdkVersion
为30:android { compileSdkVersion 30 ... }
-
确保你将所有的
android.
依赖替换为其AndroidX对应物(完整的列表可以在这里找到)。
权限
在Android上,你需要在你的AndroidManifest.xml
文件中添加ACCESS_COARSE_LOCATION
或ACCESS_FINE_LOCATION
权限。打开AndroidManifest.xml
文件(位于android/app/src/main
),并添加以下一行作为<manifest>
标签的直接子元素(如果你同时配置了这两个权限,则会使用ACCESS_FINE_LOCATION
):
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
从Android 10开始,如果你想在应用运行在后台时继续接收更新,还需要添加ACCESS_BACKGROUND_LOCATION
权限(除了ACCESS_COARSE_LOCATION
或ACCESS_FINE_LOCATION
权限之外):
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
对于iOS
在iOS上,你需要向你的Info.plist
文件(位于ios/Runner
)中添加以下条目以访问设备的位置。只需打开你的Info.plist
文件并添加以下内容:
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>
如果你想在应用处于后台时接收更新,还需要在XCode项目中添加Background Modes能力(Project > Signing and Capabilities > "+ Capability"按钮),并选择Location Updates。请注意,当提交应用到AppStore时,你需要详细解释为什么你的应用需要此功能。如果Apple不满意你的解释,你的应用可能会被拒绝。
API
启动Easy Geofencing服务
首先,你需要启动地理围栏服务,并传递以下参数:
pointedLatitude
: 地理围栏区域中心的纬度pointedLongitude
: 地理围栏区域中心的经度radiusMeter
: 地理围栏区域的半径(米)eventPeriodInSeconds
: 地理围栏状态流周期(秒)
import 'package:easy_geofencing/easy_geofencing.dart';
EasyGeofencing.startGeofenceService(
pointedLatitude: "34.2165157",
pointedLongitude: "71.9437819",
radiusMeter: "250.0",
eventPeriodInSeconds: 5
);
获取地理围栏状态流
为了获取位置变化时的地理围栏状态更新,你需要订阅getGeofenceStream
来监听当前位置更新的地理围栏状态流。
import 'package:easy_geofencing/easy_geofencing.dart';
StreamSubscription<GeofenceStatus> geofenceStatusStream = EasyGeofencing.getGeofenceStream().listen(
(GeofenceStatus status) {
print(status.toString());
});
停止地理围栏服务
要停止地理围栏服务,你需要指定:
import 'package:easy_geofencing/easy_geofencing.dart';
EasyGeofencing.stopGeofenceService();
同时,停止地理围栏状态流订阅监听器,例如geofenceStatusStream
:
geofenceStatusStream.cancel();
示例Demo
下面是一个完整的示例应用,演示如何使用easy_geofencing
插件。
import 'dart:async';
import 'package:easy_geofencing/easy_geofencing.dart';
import 'package:easy_geofencing/enums/geofence_status.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Easy Geofencing',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Easy Geofencing'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextEditingController latitudeController = TextEditingController();
TextEditingController longitudeController = TextEditingController();
TextEditingController radiusController = TextEditingController();
StreamSubscription<GeofenceStatus>? geofenceStatusStream;
String geofenceStatus = '';
bool isReady = false;
Position? position;
@override
void initState() {
super.initState();
getCurrentPosition();
}
Future<void> getCurrentPosition() async {
position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
print("LOCATION => ${position!.toJson()}");
isReady = (position != null) ? true : false;
}
setLocation() async {
await getCurrentPosition();
latitudeController.text = position!.latitude.toString();
longitudeController.text = position!.longitude.toString();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
actions: [
IconButton(
icon: Icon(Icons.my_location),
onPressed: () {
if (isReady) {
setState(() {
setLocation();
});
}
},
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
TextField(
controller: latitudeController,
decoration: InputDecoration(border: InputBorder.none, hintText: 'Enter pointed latitude'),
),
TextField(
controller: longitudeController,
decoration: InputDecoration(border: InputBorder.none, hintText: 'Enter pointed longitude'),
),
TextField(
controller: radiusController,
decoration: InputDecoration(border: InputBorder.none, hintText: 'Enter radius in meter'),
),
SizedBox(height: 60),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
child: Text("Start"),
onPressed: () {
print("starting geoFencing Service");
EasyGeofencing.startGeofenceService(
pointedLatitude: latitudeController.text,
pointedLongitude: longitudeController.text,
radiusMeter: radiusController.text,
eventPeriodInSeconds: 5);
if (geofenceStatusStream == null) {
geofenceStatusStream = EasyGeofencing.getGeofenceStream()?.listen((GeofenceStatus status) {
print(status.toString());
setState(() {
geofenceStatus = status.toString();
});
});
}
},
),
SizedBox(width: 10.0),
ElevatedButton(
child: Text("Stop"),
onPressed: () {
print("stop");
EasyGeofencing.stopGeofenceService();
geofenceStatusStream?.cancel();
},
),
],
),
SizedBox(height: 100),
Text(
"Geofence Status: \n\n\n" + geofenceStatus,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
],
),
),
);
}
@override
void dispose() {
latitudeController.dispose();
longitudeController.dispose();
radiusController.dispose();
super.dispose();
}
}
这个示例应用展示了如何启动和停止地理围栏服务,并监听地理围栏状态的变化。
更多关于Flutter地理围栏功能插件easy_geofencing的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地理围栏功能插件easy_geofencing的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用easy_geofencing
插件来实现地理围栏功能的代码示例。
首先,你需要在你的Flutter项目中添加easy_geofencing
依赖。在你的pubspec.yaml
文件中添加以下依赖项:
dependencies:
flutter:
sdk: flutter
easy_geofencing: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来获取依赖。
接下来,你需要在你的AndroidManifest.xml
中添加必要的权限,以便应用能够访问位置信息:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<application
... >
<!-- 你的其他配置 -->
</application>
</manifest>
然后,在你的Flutter代码中,你可以这样使用easy_geofencing
插件:
import 'package:flutter/material.dart';
import 'package:easy_geofencing/easy_geofencing.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late EasyGeofencing _easyGeofencing;
late StreamSubscription<GeofencingEvent> _geofencingEventSubscription;
@override
void initState() {
super.initState();
_easyGeofencing = EasyGeofencing();
// 请求权限
_easyGeofencing.requestPermissions().then((isGranted) {
if (isGranted) {
// 初始化地理围栏
_initializeGeofencing();
} else {
// 处理权限被拒绝的情况
print("Location permissions denied");
}
});
}
void _initializeGeofencing() async {
// 创建一个地理围栏
GeofencingRegion region = GeofencingRegion(
identifier: "my_geofence",
latitude: 37.7853889,
longitude: -122.4056973,
radius: 100.0, // 半径为100米
);
// 添加地理围栏
await _easyGeofencing.addGeofence(region);
// 监听地理围栏事件
_geofencingEventSubscription = _easyGeofencing.geofencingEvents.listen((event) {
if (event.geofenceIdentifier == "my_geofence") {
if (event.action == GeofenceAction.ENTER) {
print("Entered the geofence");
} else if (event.action == GeofenceAction.EXIT) {
print("Exited the geofence");
} else if (event.action == GeofenceAction.DWELL) {
print("Dwelled inside the geofence");
}
}
});
}
@override
void dispose() {
// 取消订阅
_geofencingEventSubscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Geofencing Example'),
),
body: Center(
child: Text('Check console for geofencing events'),
),
),
);
}
}
在这个示例中,我们完成了以下步骤:
- 在
pubspec.yaml
中添加easy_geofencing
依赖。 - 在
AndroidManifest.xml
中添加必要的权限。 - 在Flutter代码中请求位置权限。
- 初始化并添加一个地理围栏。
- 监听地理围栏事件,并在控制台打印事件信息。
确保你已经替换了GeofencingRegion
中的经纬度和半径为你实际需要的值。这个示例展示了如何设置和监听一个基本的地理围栏,你可以根据需要进行扩展和自定义。