geofence_sdk 0.2.0
geofence_sdk: ^0.2.0 copied to clipboard
Geofencing for Flutter over native iOS & Android region monitoring: server-managed zone sync, background enter/exit/dwell events, offline queue, local notifications.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:geofence_sdk/geofence_sdk.dart';
// Live production backend + working SDK key. The backend authorizes requests by
// the app's bundle/package id via the `X-App-Id` header, which the native SDK
// sends automatically (the example ships with package id `com.geofencesdk.example`).
const _baseUrl = 'https://api.geofencekit.com';
const _apiKey = 'sdk_823a5331130b3b0ba24226a212389386da9aa3fd';
void main() => runApp(const GeofenceExampleApp());
class GeofenceExampleApp extends StatelessWidget {
const GeofenceExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Geofence SDK Example',
theme: ThemeData(colorSchemeSeed: Colors.green, useMaterial3: true),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _sdk = GeofenceSdk();
String _log = 'Not configured yet.';
PermissionStatus? _permission;
List<Fence> _fences = const [];
bool _busy = false;
void _append(String line) => setState(() => _log = '$line\n$_log');
Future<void> _run(String label, Future<void> Function() action) async {
setState(() => _busy = true);
_append('> $label...');
try {
await action();
} catch (e) {
_append('x $label failed: $e');
} finally {
setState(() => _busy = false);
}
}
Future<void> _configure() => _run('configure', () async {
await _sdk.configure(
const GeofenceConfig(
baseUrl: _baseUrl,
apiKey: _apiKey,
userId: 'flutter_example_user',
),
);
_append('ok configured against $_baseUrl');
});
Future<void> _requestPermissions() => _run('requestPermissions', () async {
final status = await _sdk.requestPermissions();
setState(() => _permission = status);
_append('ok permission = $status');
});
Future<void> _checkPermission() => _run('permissionStatus', () async {
final status = await _sdk.permissionStatus();
setState(() => _permission = status);
_append('ok status = $status');
});
Future<void> _start() => _run('start', () async {
final fences = await _sdk.start();
setState(() => _fences = fences);
_append('ok monitoring ${fences.length} fence(s)');
});
Future<void> _stop() => _run('stop', () async {
await _sdk.stop();
setState(() => _fences = const []);
_append('ok stopped');
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Geofence SDK Example')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Wrap(
spacing: 8,
runSpacing: 8,
children: [
FilledButton(
onPressed: _busy ? null : _configure,
child: const Text('Configure'),
),
FilledButton(
onPressed: _busy ? null : _requestPermissions,
child: const Text('Request permission'),
),
OutlinedButton(
onPressed: _busy ? null : _checkPermission,
child: const Text('Check status'),
),
FilledButton(
onPressed: _busy ? null : _start,
child: const Text('Start'),
),
OutlinedButton(
onPressed: _busy ? null : _stop,
child: const Text('Stop'),
),
],
),
const SizedBox(height: 12),
Text('Permission: ${_permission ?? "-"}'),
Text('Fences: ${_fences.length}'),
const Divider(),
Expanded(
child: SingleChildScrollView(
child: Text(
_log,
style: const TextStyle(fontFamily: 'monospace'),
),
),
),
],
),
),
);
}
}