Source: https://developers.woosmap.com/products/geofencing-sdk/flutter-plugin/guides/setup/

> For clean Markdown of any page, append `.md` to the page URL.

> For a complete documentation index, see https://developers.woosmap.com/llms.txt

# Flutter Plugin



The Woosmap Geofencing SDK allows you to monitor Geofences, track your user's location and connect with the Woosmap Search and Distance APIs.

Find Geofencing Flutter package release notes in the [Changelog section](https://pub.dev/packages/geofencing_flutter_plugin/changelog) of the pub.dev website.

## Install the Woosmap Geofencing Flutter plugin

### Prerequisites

Before you begin, ensure you have installed and setup Flutter platform on your machine.
See this [get-started](https://docs.flutter.dev/get-started/install).

### Installation

Add Woosmap Geofencing flutter plugin to your project using this command line:

```shell
flutter pub add geofencing_flutter_plugin
```

**Adding the platform**

For iOS

- **info.plist**: Please check info.plist updated with the following keys:
  - NSLocationAlwaysAndWhenInUseUsageDescription
  - NSLocationAlwaysUsageDescription
  - NSLocationWhenInUseUsageDescription
  - UIBackgroundModes

```xml
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Used to test the library</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Used to test the library</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Used to test the library</string>
<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>location</string>
</array>
```

### Supported Platforms

- iOS (Plugin supports iOS 15 and higher)
- Android (Plugin supports Android 33 and higher)

**App closed limitations**
Because of the Flutter framework, callbacks are not triggered when the application is closed.
Locations and geofence events are well stored in the device, and you can retrieve them through getter methods included in this plugin.

### Modules

- **GeofencingFlutterPlugin**: Woosmap contains methods to monitor location and regions.

### Objects(Read Only)

- **Location**: Represents the location object
- **POI**: Represents Point of Interest
- **Region**: Represents a geographical region/Geofence

### Types

- **ProfileSource**: Represents tracking profile source. It can either be `ProfileSource.local` or `ProfileSource.external`
- **RegionType**: Represents the type of the region. Possible values are `RegionType.circle` and `RegionType.isochrone`

## Usage

```dart
import 'package:geofencing_flutter_plugin/geofencing_flutter_plugin.dart';

final geofencingFlutterPlugin = GeofencingFlutterPlugin();
...
```

### Check and request permissions

Before initializing the SDK, you must request for required location permissions.

To check if the user grants location permissions call `getPermissionsStatus` method.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.getPermissionsStatus();

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

Parameter status will be a string, one of:

- `GRANTED_BACKGROUND`: The user has been granted location access even when the app is not running in foreground.
- `GRANTED_FOREGROUND`: Location access is granted only while a user uses the app.
- `DENIED`: Location access is denied.
- `UNKNOWN`: Without providing or denying any permission, it will return unknown.

**_Please note_**: Plugin will not work as expected if location access is denied.

**Requesting location access**
To request location access call `requestPermissions` method of the plugin. This will result in displaying location access permission dialog. This method accepts a boolean parameter `withBackgroundAccess`. If this parameter is true, the plugin will ask for background location access. The code snippet below asks for background location access.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.requestPermissions(withBackgroundAccess: true);

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

**Check Bluetooth permissions**

In order to get beacon-fencing running on Android devices you need to make sure that all the Bluetooth related permissions are granted to the plugin.

To check if the Bluetooth permissions are granted by the user call `getBLEPermissionsStatus` method.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.getBLEPermissionsStatus();
returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

Parameter status will be a string, one of:

- `GRANTED` : User has granted bluetooth access.
- `DENIED`: Bluetooth access is denied.
- `BACKGROUND_LOCATION_DENIED`: Background location access is denied. You first need to request background location permission.

**Requesting Bluetooth permissions**

To request Bluetooth access call `requestBLEPermissions` method of the plugin. This will result in displaying Bluetooth access permission dialog.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.requestBLEPermissions();
returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

**_Note_**: For beacon-fencing to work you will also need to request background location access. To request background location access please invoke `requestPermissions` method of the plugin with background parameter enabled.

### Initializing the plugin

The plugin automatically sends the required authentication headers (`X-Api-Key` and platform identifiers) with every API request. If you're calling Woosmap REST APIs directly without the plugin, you'll need to set these headers yourself. See [Authenticating from Mobile Apps](/api-reference/authentication/#authenticating-from-mobile-apps-or-server-side-via-headers) for details.

Plugin can be initialized by simply calling `initialize` method.

```dart
Map<String, String> woosmapSettings = {
    "privateKeyWoosmapAPI": "<<WOOSMAP_KEY>>",
    "trackingProfile": "liveTracking"
};

Future<String?> returnVal = geofencingFlutterPlugin.initialize(woosmapSettings);

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: $error');
});
```

Both configuration options `privateKeyWoosmapAPI` and `trackingProfile` are optional. You can also initialize the plugin by passing a null configuration.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.initialize();

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: $error');
});
```

You can also set the Woosmap API key later by calling `setWoosmapApiKey` method.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.setWoosmapApiKey("<<WOOSMAP_KEY>>");

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

### Tracking

Once you have initialized plugin and user has authorised location permissions, you can start tracking the user’s location.

To start tracking, call:

```dart
Future<String?> returnVal = geofencingFlutterPlugin.startTracking('liveTracking');

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

To stop tracking, call:

```dart
Future<String?> returnVal = geofencingFlutterPlugin.stopTracking();

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

Method `startTracking` accepts only following tracking profiles

- liveTracking
- passiveTracking
- optimalPassiveTracking
- visitsTracking
- beaconTracking

### Notifications on Android devices

Geofencing SDK uses foreground service on Android when using `liveTracking` and `optimalPassiveTracking` profile. The SDK needs to show an ongoing notification in order to work properly while tracking using these profiles.

You need to make sure that permission to post notification is granted before initiating tracking with `liveTracking` and `optimalPassiveTracking`.

To request permission invoke `requestNotificationPermissions` method.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.requestNotificationPermissions();

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: ${error.message}');
});
```

### Customize notifications on Android devices

Notifications on Android devices can be customized using following configuration options. These options should be passed wile initializing the plugin.

- **`androidNotificationTitle`**: Title of the notification.
- **`androidNotificationText`**: Content text of the notification.
- **`androidNotificationIconName`**: Set the notification icon name from Android `drawable` or `mipmap` folder.
- **`androidNotificationIconUrl`**: Set the notification icon fron Flutter assets by providing the asset path.

```dart
WoosmapGeofencingOptions options = WoosmapGeofencingOptions(
          androidNotificationText: "Notification Title goes here",
          androidNotificationTitle: "Notification Description goes here",
          androidNotificationIconName: "assets/ic_alarm.png");

Future<String?> returnVal = geofencingFlutterPlugin.initialize(options);
```

### Location

To listen to the location, call `watchLocation` method. After successful invocation of the method, you'll need to call `getWatchLocationStream` method which will return a stream of `Location` object. Once you obtain stream call listen method of the stream.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.watchLocation();

returnVal.then((value){
    //Get the location stream
    watchLocationStream = geofencingFlutterPlugin.getWatchLocationStream();
    //Listen to the stream
    watchLocationStream.listen((location){
        //Location updates will be received here.
        if (location != null) {
            debugPrint(location.locationDescription);
        } else {
            debugPrint("Location is null");
        }
    });
}).catchError((error) {
    debugPrint('An error occurred: $error');
});
```

### To stop getting location updates

Call `clearLocationWatch` method to remove all locations in the local db.

```dart
Future<String?> returnVal = geofencingFlutterPlugin.clearLocationWatch();

returnVal.then((value){
    debugPrint(value!);
}).catchError((error) {
    debugPrint('An error occurred: $error');
});
```
