geofence_foreground_service
一個 Flutter 專案,建立一個前臺服務來處理地理圍欄。
Basel-525k/geofence_foreground_service open-source repository details.
{"sdk":"flutter"}^2.1.8^2.0.7{"sdk":"flutter"}^5.0.0以下為英文專案原文快照,最新內容請造訪 GitHub。
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 |
<service
android:name="com.f2fk.geofence_foreground_service.GeofenceForegroundService"
android:foregroundServiceType="location">
</service>
<!--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" />
minSdkVersion in the app/build.gradle file is 29+platform :ios, '12.0'
<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>
Location updates and Background fetch capabilities from XCode
iOS capabilitiesDefine 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',
)
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)
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.