搜尋套件、儲存庫與 APP 分類

GitHub 儲存庫Basel-525k/geofence_foreground_service

geofence_foreground_service

Basel-525k/geofence_foreground_service open-source repository details.

geofence_foreground_service 專案封面
星標
12
分支
28
最近推送(UTC)
2026年3月23日
專案狀態
未封存

原始 README

以下為英文專案原文快照,最新內容請造訪 GitHub。

geofence_foreground_service

Flutter Version License Platform Platform

A Flutter plugin that enables you to easily handle geofencing events in your Flutter app by utilizing native OS APIs on Android by creating a foreground service while being battery efficient since it uses the Geofence and WorkManager APIs. And on iOS by utilizing the CLLocationManager

It's important to note that the workmanager and flutter_foreground_task plugins were a great source of inspiration while creating this plugin.

Android iOS
Android Demo iOS Demo

Features

  • Supports geofencing in foreground as well as background 💪
  • Geofence a circular area 🗺️
  • Geofence a polygon 🤯 You can add a geofence using a list of coordinates, the system will calculate the center of them and register it, having full polygon support is a WIP 🚧
  • Notification customization 🔔: ⚠️Android⚠️ Displaying a notification when running a foreground service is mandatory, you can customize what is being displayed on it (title, content or the icon), the plugin displays your app icon by default.
  • Notification responsiveness ⏱️: ⚠️Android⚠️ You can set the responsiveness of the android notifications as per the docs here

Setup

🔧 Android Setup
  • Enable MultiDex, you can check how to do so here
  • Add the service to the AndroidManifest.xml inside the application tag
<service 
    android:name="com.f2fk.geofence_foreground_service.GeofenceForegroundService"
    android:foregroundServiceType="location">
</service>
  • Add the permissions
<!--required-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

<!--at least one of the follwoing-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  • Make sure the minSdkVersion in the app/build.gradle file is 29+
🔧 iOS Setup
  • Navigate to the Podfile and make sure to set the iOS version to 12+
platform :ios, '12.0'
  • Make sure to add the following permission to your Info.plist
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app need your location to provide best feature based on location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app need your location to provide best feature based on location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app need your location to provide best feature based on location</string>
  • Turn on the Location updates and Background fetch capabilities from XCode iOS capabilities

Example

Define the method that will handle the Geofence triggers

import 'package:geofence_foreground_service/exports.dart';
import 'package:geofence_foreground_service/geofence_foreground_service.dart';
import 'package:geofence_foreground_service/models/zone.dart';

// This method is a top level method
@pragma('vm:entry-point')
void callbackDispatcher() async {
  GeofenceForegroundService().handleTrigger(
    backgroundTriggerHandler: (zoneID, triggerType) {
      log(zoneID, name: 'zoneID');

      if (triggerType == GeofenceEventType.enter) {
        log('enter', name: 'triggerType');
      } else if (triggerType == GeofenceEventType.exit) {
        log('exit', name: 'triggerType');
      } else if (triggerType == GeofenceEventType.dwell) {
        log('dwell', name: 'triggerType');
      } else {
        log('unknown', name: 'triggerType');
      }

      return Future.value(true);
    },
  );
}

Then create an instance of the plugin to initiate it and assign GeoFences to it

final List<LatLng> timesSquarePolygon = [
  const LatLng(40.758078, -73.985640),
  const LatLng(40.757983, -73.985417),
  const LatLng(40.757881, -73.985493),
  const LatLng(40.757956, -73.985688),
];

Future<void> initPlatformState() async {
  // Remember to handle permissions before initiating the plugin

  bool hasServiceStarted = await GeofenceForegroundService().startGeofencingService(
    contentTitle: 'Test app is running in the background',
    contentText: 'Test app will be running to ensure seamless integration with ops team',
    notificationChannelId: 'com.app.geofencing_notifications_channel',
    serviceId: 525600,
    callbackDispatcher: callbackDispatcher,
  );

  if (hasServiceStarted) {
    await GeofenceForegroundService().addGeofenceZone(
      zone: Zone(
        id: 'zone#1_id',
        radius: 10000, // measured in meters
        coordinates: timesSquarePolygon,
        triggers: [
          GeofenceEventType.dwell,
          GeofenceEventType.enter,
          GeofenceEventType.exit
        ], // Currently, only available on Android
        expirationDuration: const Duration(days: 1), // Currently, only available on Android
        dwellLoiteringDelay: const Duration(hours: 1), // Currently, only available on Android
        initialTrigger: GeofenceEventType.enter, // Currently, only available on Android
      ),
    );
  }
}

Something important to point out is the callbackDispatcher method will run in an entirely different isolate than the actual app, so if you were to handle UI related code inside of it you'll need to use Ports, you can find more information here

You can pass a custom icon to the foreground service notification if you wish while initializing the service, this icon will be placed inside the android/app/src/main/res folder, you can check the example for more information, by default, it will take the app icon

const NotificationIconData(
  resType: ResourceType.mipmap,
  resPrefix: ResourcePrefix.ic,
  name: 'launcher',
)

Notes

Handling permissions is not a part of the package, so please refer to permission_handler plugin to grant the required permissions (it's used in the example too)

  • location
  • locationAlways
  • notification

Contributing

We welcome contributions. Please read CONTRIBUTING.md for pull request expectations (including small PRs and a maximum of 15 files per PR), testing, changelog updates, and review practices.

Basel-525k GitHub avatar
GitHub 作者

Basel-525k ↗

語言KotlinDartSwiftRubyJavaObjective-C

此儲存庫發佈的套件

使用的依賴

依賴清單 5 項

  • flutter{"sdk":"flutter"}
  • plugin_platform_interface^2.1.8
  • latlng^2.0.7
  • flutter_test開發依賴{"sdk":"flutter"}
  • flutter_lints開發依賴^5.0.0

如何選擇適合專案的儲存庫?

先依使用情境篩選,再比較專案活躍情況,最後到原始儲存庫確認使用要求。

  1. 透過儲存庫名稱、作者或描述搜尋,再依技術分類縮小範圍。
  2. 綜合星標、分支與最近推送比較專案;星標反映社群關注,不保證品質。
  3. 使用前在 GitHub 確認 README、授權條款與 Issues。

來源與維護

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗