{"id":16401713,"url":"https://github.com/dev-hwang/geofencing_api","last_synced_at":"2025-04-21T11:33:12.409Z","repository":{"id":256010459,"uuid":"853219142","full_name":"Dev-hwang/geofencing_api","owner":"Dev-hwang","description":"This plugin is used to implement circular and polygon geofencing service.","archived":false,"fork":false,"pushed_at":"2024-11-04T10:08:28.000Z","size":128,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-04T11:18:08.394Z","etag":null,"topics":["android","flutter","geofencing","ios","web"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/geofencing_api","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dev-hwang.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-06T08:13:56.000Z","updated_at":"2024-11-04T10:08:32.000Z","dependencies_parsed_at":"2024-10-28T09:28:08.868Z","dependency_job_id":null,"html_url":"https://github.com/Dev-hwang/geofencing_api","commit_stats":null,"previous_names":["dev-hwang/geofencing_api"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-hwang%2Fgeofencing_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-hwang%2Fgeofencing_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-hwang%2Fgeofencing_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dev-hwang%2Fgeofencing_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dev-hwang","download_url":"https://codeload.github.com/Dev-hwang/geofencing_api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223861035,"owners_count":17215802,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","flutter","geofencing","ios","web"],"created_at":"2024-10-11T05:43:58.378Z","updated_at":"2025-04-21T11:33:12.374Z","avatar_url":"https://github.com/Dev-hwang.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"This plugin is used to implement circular and polygon geofencing service.\n\n\u003cimg src=\"https://github.com/user-attachments/assets/b11c5728-43bc-4792-bc55-a8cd237944a4\" width=\"700\" /\u003e\n\n\u003e [!CAUTION]\n\u003e It does not use the geofencing api implemented in the platform. \n\u003e Therefore, battery efficiency cannot be guaranteed. \n\u003e Instead, this plugin can provide more accurate and real-time geofencing by navigating your location while your app is alive.\n\n## Features\n\n* Can create a circular type geofence.\n* Can create a polygon type geofence.\n* Can listen to geofence status changes in real-time.\n* Can listen to location changes in real-time.\n* Can request or check location permission.\n\n## Getting started\n\nTo use this plugin, add `geofencing_api` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). For example:\n\n```yaml\ndependencies:\n  geofencing_api: ^2.0.0\n```\n\nAfter adding the plugin to your flutter project, we need to declare the platform-specific permissions to use for this plugin to work properly.\n\n### :baby_chick: Android\n\nSince the geofencing service works based on location, we need to declare location permission.\n\nOpen the `AndroidManifest.xml` file and declare permission between the `\u003cmanifest\u003e` and `\u003capplication\u003e` tags.\n\n```\n\u003cuses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" /\u003e\n\u003cuses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" /\u003e\n```\n\n### :baby_chick: iOS\n\nOpen the `ios/Runner/Info.plist` file and declare description within the `\u003cdict\u003e` tag.\n\n```\n\u003ckey\u003eNSLocationWhenInUseUsageDescription\u003c/key\u003e\n\u003cstring\u003eUsed to collect location data.\u003c/string\u003e\n```\n\n### :baby_chick: Background Mode\n\nTo perform geofencing in the background, declare permissions and descriptions.\n\n```\n\u003cuses-permission android:name=\"android.permission.ACCESS_BACKGROUND_LOCATION\" /\u003e\n```\n\n```\n\u003ckey\u003eNSLocationAlwaysAndWhenInUseUsageDescription\u003c/key\u003e\n\u003cstring\u003eUsed to collect location data in the background.\u003c/string\u003e\n\u003ckey\u003eNSLocationAlwaysUsageDescription\u003c/key\u003e\n\u003cstring\u003eUsed to collect location data in the background.\u003c/string\u003e\n\u003ckey\u003eUIBackgroundModes\u003c/key\u003e\n\u003carray\u003e\n    \u003cstring\u003efetch\u003c/string\u003e\n    \u003cstring\u003elocation\u003c/string\u003e\n\u003c/array\u003e\n```\n\nThen use [flutter_foreground_task](https://github.com/Dev-hwang/flutter_foreground_task) to implement a background geofencing service.\n\ndemo: https://github.com/Dev-hwang/flutter_foreground_task_example/tree/main/geofencing_service\n\n## How to use\n\n1. Request location permission. To start the geofencing service, the permission result must be `always` or `whileInUse`.\n\n```dart\nFuture\u003cbool\u003e requestLocationPermission({bool background = false}) async {\n  if (!await Geofencing.instance.isLocationServicesEnabled) {\n    // Location services is disabled.\n    return false;\n  }\n\n  LocationPermission permission =\n      await Geofencing.instance.getLocationPermission();\n  if (permission == LocationPermission.denied) {\n    // Android: ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION\n    // iOS 12-: NSLocationWhenInUseUsageDescription or NSLocationAlwaysAndWhenInUseUsageDescription\n    // iOS 13+: NSLocationWhenInUseUsageDescription\n    permission = await Geofencing.instance.requestLocationPermission();\n  }\n\n  if (permission == LocationPermission.denied ||\n      permission == LocationPermission.deniedForever) {\n    // Location permission has been ${permission.name}.\n    return false;\n  }\n\n  // Web: Only allow whileInUse permission.\n  if (kIsWeb || kIsWasm) {\n    return true;\n  }\n\n  // Android: You must request location permission one more time to access background location.\n  // iOS 12-: You can request always permission through the above request.\n  // iOS 13+: You can only request whileInUse permission through the above request.\n  // When the app enters the background, a prompt will appear asking for always permission.\n  if (Platform.isAndroid \u0026\u0026\n      background \u0026\u0026\n      permission == LocationPermission.whileInUse) {\n    // You need a clear explanation of why your app's feature needs access to background location.\n    // https://developer.android.com/develop/sensors-and-location/location/permissions#request-background-location\n\n    // Android: ACCESS_BACKGROUND_LOCATION\n    permission = await Geofencing.instance.requestLocationPermission();\n\n    if (permission != LocationPermission.always) {\n      // Location permission must always be granted to collect location in the background.\n      return false;\n    }\n  }\n\n  return true;\n}\n```\n\n2. Set up the geofencing service.\n* `interval`: The millisecond interval at which to update the geofence status. This value may be delayed by device platform limitations. The default is `5000`.\n* `accuracy`: The accuracy of the geofencing service in meters. The default is `100`.\n* `statusChangeDelay`: The status change delay in milliseconds. `GeofenceStatus.enter` and `GeofenceStatus.exit` events may be called frequently when the location is near the boundary of the geofence. If the option value is too large, real-time geofencing is not possible, so use it carefully. The default is `10000`.\n* `allowsMockLocation`: Whether to allow mock location. The default is `false`.\n* `printsDebugLog`: Whether to print debug logs in plugin. The default is `true`.\n\n```dart\nvoid setupGeofencing() {\n  Geofencing.instance.setup(\n    interval: 5000,\n    accuracy: 100,\n    statusChangeDelay: 10000,\n    allowsMockLocation: false,\n    printsDebugLog: true,\n  );\n}\n```\n\n3. Create geofence regions. Use the `.circular` or `.polygon` constructor.\n* `id`: The unique id of the geofence region.\n* `data`: The data of the geofence region.\n* `loiteringDelay`: The delay between `GeofenceStatus.enter` and `GeofenceStatus.dwell` in milliseconds. The default is `30000`.\n* `center`: The center coordinates of the geofence. (circular)\n* `radius`: The radius of the geofence. This value should be 10 meters or greater. (circular)\n* `polygon`: The polygon coordinates of the geofence. This value must have size 3 or greater. (polygon)\n\n```dart\nfinal Set\u003cGeofenceRegion\u003e _regions = {\n  GeofenceRegion.circular(\n    id: 'circular_region',\n    data: {\n      'name': 'National Museum of Korea',\n    },\n    center: const LatLng(37.523085, 126.979619),\n    radius: 250,\n    loiteringDelay: 60 * 1000,\n  ),\n  GeofenceRegion.polygon(\n    id: 'polygon_region',\n    data: {\n      'name': 'Gyeongbokgung Palace',\n    },\n    polygon: [\n      const LatLng(37.583696, 126.973739),\n      const LatLng(37.583441, 126.979361),\n      const LatLng(37.582506, 126.980198),\n      const LatLng(37.579054, 126.979490),\n      const LatLng(37.576112, 126.979061),\n      const LatLng(37.576503, 126.974126),\n      const LatLng(37.580959, 126.973568),\n    ],\n    loiteringDelay: 60 * 1000,\n  ),\n};\n```\n\n4. Start the geofencing service. You can add geofence regions before starting the service using the `regions` parameter.\n\n```dart\nvoid startGeofencing() async {\n  Geofencing.instance.addGeofenceStatusChangedListener(_onGeofenceStatusChanged);\n  Geofencing.instance.addGeofenceErrorCallbackListener(_onGeofenceError);\n  \n  // You can add listeners as needed.\n  Geofencing.instance.addLocationChangedListener(LocationChanged);\n  Geofencing.instance.addLocationServicesStatusChangedListener(LocationServicesStatusChanged);\n  \n  await Geofencing.instance.start(regions: _regions);\n}\n\nFuture\u003cvoid\u003e _onGeofenceStatusChanged(\n  GeofenceRegion geofenceRegion,\n  GeofenceStatus geofenceStatus,\n  Location location,\n) async {\n  final String regionId = geofenceRegion.id;\n  final String statusName = geofenceStatus.name;\n  print('region(id: $regionId) $statusName');\n}\n\nvoid _onGeofenceError(Object error, StackTrace stackTrace) {\n  print('error: $error\\n$stackTrace');\n}\n```\n\n5. You can add or remove regions even after the service starts.\n\n```dart\nvoid addRegions() {\n  Geofencing.instance.addRegion(GeofenceRegion);\n  Geofencing.instance.addRegions(Set\u003cGeofenceRegion\u003e);\n}\n\nvoid removeRegions() {\n  Geofencing.instance.removeRegion(GeofenceRegion);\n  Geofencing.instance.removeRegions(Set\u003cGeofenceRegion\u003e);\n  Geofencing.instance.removeRegionById(String);\n  Geofencing.instance.clearAllRegions();\n}\n```\n\n6. You can pause or resume the service.\n\n```dart\nvoid pauseGeofencing() {\n  Geofencing.instance.pause();\n}\n\nvoid resumeGeofencing() {\n  Geofencing.instance.resume();\n}\n```\n\n7. Stop the geofencing service. If you want to keep added regions, set `keepsRegions` to `true`.\n\n```dart\nvoid stopGeofencing() async {\n  Geofencing.instance.removeGeofenceStatusChangedListener(_onGeofenceStatusChanged);\n  Geofencing.instance.removeGeofenceErrorCallbackListener(_onGeofenceError);\n  Geofencing.instance.removeLocationChangedListener(LocationChanged);\n  Geofencing.instance.removeLocationServicesStatusChangedListener(LocationServicesStatusChanged);\n  Geofencing.instance.clearAllListeners();\n  \n  await Geofencing.instance.stop(keepsRegions: true);\n}\n```\n\n## More Documentation\n\nGo [here](./documentation/models_documentation.md) to learn about the `models` provided by this plugin.\n\nGo [here](./documentation/migration_documentation.md) to `migrate` to the new version.\n\n## Support\n\nIf you find any bugs or issues while using the plugin, please register an issues on [GitHub](https://github.com/Dev-hwang/geofencing_api/issues). You can also contact us at \u003chwj930513@naver.com\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-hwang%2Fgeofencing_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdev-hwang%2Fgeofencing_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-hwang%2Fgeofencing_api/lists"}