{"id":18836806,"url":"https://github.com/loup-v/beacons","last_synced_at":"2025-06-11T08:33:14.111Z","repository":{"id":56826515,"uuid":"134009476","full_name":"loup-v/beacons","owner":"loup-v","description":"Flutter beacons plugin for Android and iOS.","archived":false,"fork":false,"pushed_at":"2020-02-05T17:14:42.000Z","size":275,"stargazers_count":78,"open_issues_count":33,"forks_count":54,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-27T01:33:54.957Z","etag":null,"topics":["altbeacon","beacon","beacons","flutter","flutter-plugin","geolocation","ibeacon","ibeacons","location"],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loup-v.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}},"created_at":"2018-05-18T22:24:26.000Z","updated_at":"2024-02-06T14:47:39.000Z","dependencies_parsed_at":"2022-09-20T22:10:40.617Z","dependency_job_id":null,"html_url":"https://github.com/loup-v/beacons","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loup-v%2Fbeacons","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loup-v%2Fbeacons/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loup-v%2Fbeacons/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loup-v%2Fbeacons/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loup-v","download_url":"https://codeload.github.com/loup-v/beacons/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248830884,"owners_count":21168361,"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":["altbeacon","beacon","beacons","flutter","flutter-plugin","geolocation","ibeacon","ibeacons","location"],"created_at":"2024-11-08T02:32:08.806Z","updated_at":"2025-04-14T06:21:31.258Z","avatar_url":"https://github.com/loup-v.png","language":"Dart","readme":"# Beacons\n\n[![pub package](https://img.shields.io/pub/v/beacons.svg)](https://pub.dartlang.org/packages/beacons)\n\n[Flutter plugin](https://pub.dartlang.org/packages/beacons/) to work with beacons.  \nSupports Android API 16+ and iOS 8+.  \n\nFeatures:\n\n* Automatic permission management\n* Ranging\n* Monitoring (including background)\n\n\nSupported beacons specifications:\n\n* iBeacon (iOS \u0026 Android)\n* Altbeacon (Android)\n\n\n## Installation\n\nAdd to pubspec.yaml:\n\n```yaml\ndependencies:\n  beacons: ^0.3.0\n```\n\n**Note:** The plugin is written in Swift for iOS.  \nThere is a known issue for integrating swift plugin into Flutter project using the Objective-C template. Follow the instructions from [Flutter#16049](https://github.com/flutter/flutter/issues/16049) to resolve the issue (Cocoapods 1.5+ is mandatory).\n\n\n### Setup specific for Android\n\nCreate a subclass of `FlutterApplication`:\n\n```kotlin\nclass App : FlutterApplication() {\n\n    override fun onCreate() {\n        super.onCreate()\n\n        // Beacons setup for Android\n        BeaconsPlugin.init(this, object : BeaconsPlugin.BackgroundMonitoringCallback {\n            override fun onBackgroundMonitoringEvent(event: BackgroundMonitoringEvent): Boolean {\n                val intent = Intent(this@App, MainActivity::class.java)\n                startActivity(intent)\n                return true\n            }\n        })\n    }\n}\n```\n\nAnd register it in `android/app/src/main/AndroidManifest.xml`:\n\n```xmln\n\u003cmanifest ...\u003e\n  ...\n  \u003capplication\n    android:name=\".App\"\n    android:label=\"beacons_example\"\n    android:icon=\"@mipmap/ic_launcher\"\u003e\n    ...\n  \u003c/application\u003e\n\u003c/manifest\u003e\n```\n\n`BeaconsPlugin.BackgroundMonitoringCallback` is required to react to background monitoring events. The callback will be executed when a monitoring event is detected while the app is running in background. In the snipped above, it will start the Flutter app. It will also allow to receive a callback on the Flutter side. See background monitoring section for more details.\n\nFor permission, see below.\n\n### Setup specific for iOS\n\nNothing. Contrary to the general opinion, you do not need to enable any background mode.\n\nFor permission, see below.\n\n\n### Permission\n\nIn order to use beacons related features, apps are required to ask the location permission. It's a two step process:\n\n1. Declare the permission the app requires in configuration files\n2. Request the permission to the user when app is running (the plugin can handle this automatically)\n\n#### For iOS\n\nThere are two available permissions in iOS: `when in use` and `always`.  \nThe latter is required for background monitoring.\n\nFor more details about what you can do with each permission, see:  \nhttps://developer.apple.com/documentation/corelocation/choosing_the_authorization_level_for_location_services\n\nPermission must be declared in `ios/Runner/Info.plist`:\n\n```xml\n\u003cdict\u003e\n  \u003c!-- When in use --\u003e\n  \u003ckey\u003eNSLocationWhenInUseUsageDescription\u003c/key\u003e\n  \u003cstring\u003eReason why app needs location\u003c/string\u003e\n\n  \u003c!-- Always --\u003e\n  \u003c!-- for iOS 11 + --\u003e\n  \u003ckey\u003eNSLocationAlwaysAndWhenInUseUsageDescription\u003c/key\u003e\n  \u003cstring\u003eReason why app needs location\u003c/string\u003e\n  \u003c!-- for iOS 9/10 --\u003e\n  \u003ckey\u003eNSLocationAlwaysUsageDescription\u003c/key\u003e\n  \u003cstring\u003eReason why app needs location\u003c/string\u003e\n  ...\n\u003c/dict\u003e\n```\n\n#### For Android\n\nThere are two available permissions in Android: `coarse` and `fine`.  \nFor beacons related features, there are no difference between the two permission.\n\nPermission must be declared in `android/app/src/main/AndroidManifest.xml`:\n\n```xml\n\u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n  \u003cuses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" /\u003e\n  \u003c!-- or --\u003e\n  \u003cuses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" /\u003e\n\u003c/manifest\u003e\n```\n\n## How-to\n\nRanging and monitoring APIs are designed as reactive streams.  \n\n* The first subscription to the stream will start the ranging/monitoring ;\n* The last cancelling (when there are no more subscription) on the stream will stop the ranging/monitoring operation.\n\n### Ranging beacons\n\n```dart\nBeacons.ranging(\n  region: new BeaconRegionIBeacon(\n    identifier: 'test',\n    proximityUUID: '7da11b71-6f6a-4b6d-81c0-8abd031e6113',\n  ),\n  inBackground: false, // continue the ranging operation in background or not, see below\n).listen((result) {\n  // result contains a list of beacons\n  // list can be empty if no matching beacons were found in range\n}\n```\n\n#### Background ranging\n\nWhen turned off, ranging will automatically pause when app goes to background and resume when app comes back to foreground. Otherwise it will actively continue in background until the app is terminated by the OS.\n\nRanging beacons while the app is terminated is not supported by the OS. For this kind of usage, see background monitoring.\n\n### Monitoring beacons\n\n```dart\nBeacons.monitoring(\n  region: new BeaconRegionIBeacon(\n    identifier: 'test',\n    proximityUUID: '7da11b71-6f6a-4b6d-81c0-8abd031e6113',\n  ),\n  inBackground: false, // continue the monitoring operation in background or not, see below\n).listen((result) {\n  // result contains the new monitoring state:\n  // - enter\n  // - exit\n}\n```\n\n#### Background monitoring\n\nWhen turned off, monitoring will automatically pause when app goes to background and resume when app comes back to foreground. Otherwise it will actively continue in background until the app is terminated by the OS.\n\nOnce the app has been terminated, the monitoring will continue.  \nIf a monitoring event happens, the OS will start the app in background for several seconds (nothing will be visible for the user). The OS is providing you the opportunity to perform some quick operation, like showing a local notification.\n\nIn order to listen to background monitoring events, you can subscribe to a special  stream. This stream is passive: it does not start a monitoring operation. You are still required to start it using `Beacons.monitoring(inBackground: true)`.\n\nBecause the OS will run the app in background for several seconds only, before terminating it again, the good place to setup the listener is during app startup.\n\n```dart\nclass MyApp extends StatefulWidget {\n  MyApp() {\n    Beacons.backgroundMonitoringEvents().listen((event) {\n      final BackgroundMonitoringEventType type = event.type // didEnterRegion, didExitRegion or didDetermineState\n      final BeaconRegion region = event.region // The monitored region associated to the event\n      final MonitoringState state = event.state // useful for type = didDetermineState\n\n      // do something quick here to react to the background monitoring event, like showing a notification\n    });\n  }\n\n  @override\n  _MyAppState createState() =\u003e new _MyAppState();\n}\n```\n\nFor testing background monitoring and what result you should expect, read:  \nhttps://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html\n\nAlternatively to starting/stoping monitoring using `Beacons.monitoring()` stream subscription, you can use the following imperative API:\n\n```dart\n// Result will be successful if monitoring has started, or contain the reason why it has not (permission denied, etc)\nfinal BeaconsResult result = await Beacons.startMonitoring(\n  region: BeaconRegionIBeacon(\n    identifier: 'test',\n    proximityUUID: 'uuid',\n  ),\n  inBackground: true,\n);\n\nawait Beacons.stopMonitoring(\n  region: BeaconRegionIBeacon(\n    identifier: 'test',\n    proximityUUID: 'uuid',\n  ),\n);\n```\n\nNote that these functions can only start/stop the monitoring.  \nTo receive the associated monitoring events, listen to the stream from `Beacons.backgroundMonitoringEvents()`.\n\n### Beacons types\n\nFor every API that requires or return a region or a beacon, you can work with the different types of beacons specs.\n\nRegardless of the beacons specs, each region requires an unique identifier that are used by the engine under the hood to uniquely identify and manage a ranging/monitoring request.\n\n#### Generic\n\n```dart\nBeacons.ranging(region: BeaconRegion(\n    identifier: 'test',\n    ids: ['id1', 'id2', 'id3'],\n  ),\n).listen((result) {\n  final Beacon beacon = result.beacons.first;\n});\n```\n\n#### iBeacon\n\n```dart\nBeacons.ranging(region: BeaconRegionIBeacon(\n    identifier: 'test',\n    proximityUUID: 'some-uuid',\n    major:0,\n    minor: 0,\n  ),\n).listen((result) {\n  final BeaconIBeacon beacon = BeaconIBeacon.from(result.beacons.first);\n});\n```\n\n\n\n## Under the hood\n\n* iOS uses native iOS CoreLocation\n* Android uses the third-party library [android-beacon-library](https://github.com/AltBeacon/android-beacon-library) (Apache License 2.0)\n\nEach technology has its own specificities.  \nThe plugin does its best to abstract it and expose a common logic, but for an advanced usage, you would probably still need to familiarize yourself with the native technology.\n\n\n## Sponsor\n\nBeacons plugin development is sponsored by [Pointz](https://www.pointz.io/), a startup that rewards people for spending time at local, brick and mortar businesses. [Pointz](https://www.pointz.io/) is proudly based in Birmingham, AL.\n\n\n## Author\n\nBeacons plugin is developed by Loup, a mobile development studio based in Montreal and Paris.  \nYou can contact us at \u003chello@intheloup.io\u003e\n\n\n## License\n\nApache License 2.0\n","funding_links":[],"categories":["插件","Device [🔝](#readme)","Plugins"],"sub_categories":["蓝牙 / NFC / 信号灯","设备","Device","Bluetooth / NFC / Beacon"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floup-v%2Fbeacons","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floup-v%2Fbeacons","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floup-v%2Fbeacons/lists"}