Flutter地理围栏功能插件geofence_flutter的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter Geofence

A Flutter geofencing plugin for Flutter applications (Android & iOS) which provides geofencing functionalities.

Features

  • Geofence event triggered on location changes
  • Get continuous geofence event updates

Usage

To add the geofence_flutter to your Flutter application, follow the installation instructions. Below are some Android and iOS specifics that are required for the geofence_flutter to work correctly.

For Android

AndroidX

The geofence_flutter plugin requires the AndroidX version of the Android Support Libraries. This means you need to make sure your Android project supports AndroidX. Detailed instructions can be found here.

The TL;DR version is:

  1. Add the following to your gradle.properties file:

    android.useAndroidX=true
    android.enableJetifier=true
    
  2. Make sure you set the compileSdkVersion in your android/app/build.gradle file to 33:

    android {
      compileSdkVersion 33
    
      ...
    }
    
  3. Make sure you replace all the android. dependencies to their AndroidX counterparts (a full list can be found here: https://developer.android.com/jetpack/androidx/migrate).

Permissions

On Android, you’ll need to add either the ACCESS_COARSE_LOCATION or the ACCESS_FINE_LOCATION permission to your Android Manifest. To do so, open the AndroidManifest.xml file (located under android/app/src/main) and add one of the following two lines as direct children of the <manifest> tag (when you configure both permissions, the ACCESS_FINE_LOCATION will be used):

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Starting from Android 10, you need to add the ACCESS_BACKGROUND_LOCATION permission (next to the ACCESS_COARSE_LOCATION or the ACCESS_FINE_LOCATION permission) if you want to continue receiving updates even when your App is running in the background (note that the geofence_flutter plugin doesn’t support receiving and processing geofence event updates while running in the background):

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

For iOS

On iOS, you’ll need to add the following entries to your Info.plist file (located under ios/Runner) in order to access the device’s location. Simply open your Info.plist file and add the following:

<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>

If you would like to receive updates when your App is in the background, you’ll also need to add the Background Modes capability to your XCode project (Project > Signing and Capabilities > “+ Capability” button) and select Location Updates. Be careful with this, you will need to explain in detail to Apple why your App needs this when submitting your App to the AppStore. If Apple isn’t satisfied with the explanation, your App will be rejected.

API

Start Geofence Service

At first, you need to start the geofence service and for that, you need to pass the following parameters:

  • pointedLatitude: the latitude of the geofence area center
  • pointedLongitude: the longitude of the geofence area center
  • radiusMeter: the radius of the geofence area in meters
  • eventPeriodInSeconds: geofence event stream period in seconds
import 'package:geofence_flutter/geofence_flutter.dart';

await Geofence.startGeofenceService(
    pointedLatitude: "52.2165157",
    pointedLongitude: "6.9437819",
    radiusMeter: "50.0",
    eventPeriodInSeconds: 10
);

Get Geofence Event Streams

To get the stream geofence event updates on location changes, you need to subscribe to getGeofenceStream to listen to geofence event streams on current location updates.

import 'package:geofence_flutter/geofence_flutter.dart';

StreamSubscription<GeofenceEvent> geofenceEventStream = Geofence.getGeofenceStream()?.listen(
  (GeofenceEvent event) {
    print(event.toString());
});

Stop Geofence Service

To stop the geofence service, you need to specify this:

import 'package:geofence_flutter/geofence_flutter.dart';

Geofence.stopGeofenceService();

Also, stop the GeofenceEvent stream subscription listener which is geofenceEventStream in our case:

geofenceEventStream?.cancel();

Issues

Please file any issues, bugs, or feature requests as an issue on our GitHub page.

Dependencies

This plugin is dependent on the geolocator plugin of baseflow.com.

Want to Contribute

If you would like to contribute to the plugin (e.g., by improving the documentation, solving a bug, or adding a cool new feature), feel free to send your pull request.

Author

This geofence_flutter plugin for Flutter is developed by Sarfaraz.

Example Code

Here is a complete example of how to use the geofence_flutter plugin in a Flutter application:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:geofence_flutter/geofence_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Geofence',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Geofence'),
      debugShowCheckedModeBanner: false,
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  StreamSubscription<GeofenceEvent>? geofenceEventStream;
  String geofenceEvent = '';

  TextEditingController latitudeController = TextEditingController();
  TextEditingController longitudeController = TextEditingController();
  TextEditingController radiusController = TextEditingController();

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(10.0),
        child: Column(
          children: [
            Text(
              "Geofence Event: $geofenceEvent",
            ),
            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 meter'),
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                TextButton(
                  child: Text("Start"),
                  onPressed: () async {
                    await Geofence.startGeofenceService(
                        pointedLatitude: latitudeController.text,
                        pointedLongitude: longitudeController.text,
                        radiusMeter: radiusController.text,
                        eventPeriodInSeconds: 10);
                    if (geofenceEventStream == null) {
                      geofenceEventStream = Geofence.getGeofenceStream()
                          ?.listen((GeofenceEvent event) {
                        setState(() {
                          geofenceEvent = event.toString();
                        });
                      });
                    }
                  },
                ),
                SizedBox(width: 10.0),
                TextButton(
                  child: Text("Stop"),
                  onPressed: () {
                    Geofence.stopGeofenceService();
                    geofenceEventStream?.cancel();
                  },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    latitudeController.dispose();
    longitudeController.dispose();
    radiusController.dispose();
    super.dispose();
  }
}

This example demonstrates how to start and stop the geofence service, as well as how to listen to geofence events and update the UI accordingly.


更多关于Flutter地理围栏功能插件geofence_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地理围栏功能插件geofence_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用 geofence_flutter 插件在 Flutter 中实现地理围栏功能的代码示例。这个示例将展示如何添加、移除和监听地理围栏事件。

首先,确保在你的 pubspec.yaml 文件中添加 geofence_flutter 依赖:

dependencies:
  flutter:
    sdk: flutter
  geofence_flutter: ^最新版本号  # 请替换为最新的版本号

然后,运行 flutter pub get 来获取依赖。

接下来,在你的 Flutter 应用中实现地理围栏功能。以下是一个简单的示例代码:

import 'package:flutter/material.dart';
import 'package:geofence_flutter/geofence_flutter.dart';

void main() {
  runApp(MyApp());
}

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

class _MyAppState extends State<MyApp> {
  GeofenceFlutter _geofenceFlutter = GeofenceFlutter();

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

  void initGeofence() async {
    // 注册地理围栏事件监听器
    _geofenceFlutter.onGeofenceStatusChanged.listen((GeofenceStatus status) {
      print('Geofence status changed: $status');
    });

    // 添加一个地理围栏
    Geofence geofence = Geofence(
      id: 'my_geofence',
      latitude: 37.7853889, // 旧金山的纬度
      longitude: -122.4056973, // 旧金山的经度
      radius: 1000.0, // 半径为1000米
      transitionType: GeofenceTransition.ENTER | GeofenceTransition.EXIT, // 监听进入和离开事件
      notification: GeofenceNotification(
        title: 'Geofence Alert',
        description: 'You have entered/exited the geofence area!',
      ),
    );

    await _geofenceFlutter.addGeofence(geofence);
  }

  void removeGeofence() async {
    // 移除地理围栏
    await _geofenceFlutter.removeGeofence('my_geofence');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Geofence Flutter Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Tap the button to remove the geofence'),
              ElevatedButton(
                onPressed: removeGeofence,
                child: Text('Remove Geofence'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中:

  1. 依赖导入:我们在 pubspec.yaml 中添加了 geofence_flutter 依赖。
  2. 初始化地理围栏:在 initState 方法中,我们注册了一个地理围栏状态改变的监听器,并添加了一个地理围栏。
  3. 移除地理围栏:提供了一个按钮来移除地理围栏。
  4. 地理围栏配置:我们创建了一个 Geofence 对象,设置了围栏的 ID、经纬度、半径、监听的事件类型以及通知信息。

请注意,实际使用中你可能需要处理更多的边缘情况和错误处理。此外,由于地理围栏功能依赖于设备的定位服务,确保你的应用有适当的权限来处理位置数据。

这个示例应该给你一个良好的起点,以在 Flutter 应用中实现地理围栏功能。如果你有更具体的需求或问题,欢迎进一步提问!

回到顶部