mapzone_flutter_alert_plugin

Flutter plugin for the MapZone Speed Alert SDK. It delivers real-time speed-limit signs, over-speed status, upcoming signs, speed-camera and toll-gate alerts, and voice warnings β€” for Android and iOS β€” behind a single Dart API.

The plugin wraps the native Speed Alert engine, pulled automatically from the published native packages:

  • Android: com.github.mapzone-global:mapzone_speed_alert_android:2.0.1 (JitPack)
  • iOS: MapZoneSpeedAlertSDK 2.0.1 (CocoaPods)

Table of Contents

Features

  • 🚦 Current speed-limit sign + compliance status (compliant / approaching / exceeding)
  • ⏭️ Next sign, speed camera and toll gate with distance-to-go
  • πŸ”Š Voice-alert WAV clips forwarded to Flutter with trigger + priority
  • πŸ”‡ Per-category voice muting (setMutedAlertTypes); muting a camera / toll category also hides its on-screen sign
  • πŸ“ Two GPS modes:
    • Standalone: the plugin captures native GPS and drives the engine
    • Injected: feed navigation-snapped GPS via processExternalLocation()
  • πŸ–ΌοΈ Sign images delivered as PNG bytes with native change-detection caching (no re-encoding every frame)

Requirements

Platform Minimum
Android minSdk 24, JitPack repository (see Android Setup)
iOS iOS 14.0 (raise to 15.0 if your app also uses a navigation SDK that requires it)

Installation

Add the plugin to your app:

flutter pub add mapzone_flutter_alert_plugin

The native Speed Alert SDK (2.0.1) is declared by the plugin and resolved automatically β€” you do not build it yourself. You only need to make the two package hosts reachable from your app (below).

Android Setup

The Android SDK is hosted on JitPack, so your app must declare that repository. In modern Gradle the repository has to be added by the app, not the plugin β€” add it to your android/settings.gradle (or android/build.gradle):

// android/settings.gradle(.kts) β€” inside dependencyResolutionManagement { repositories { … } }
maven { url = uri("https://jitpack.io") }

Permissions are already declared by the plugin (listed here for reference): ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, INTERNET, FOREGROUND_SERVICE, FOREGROUND_SERVICE_LOCATION.

iOS Setup

The iOS SDK is a published CocoaPods pod, so a plain pod install resolves it β€” no extra source needed.

Add the location usage descriptions to ios/Runner/Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Used to provide real-time speed alerts.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Keeps speed alerts running while you drive.</string>
<key>UIBackgroundModes</key>
<array><string>location</string></array>

Set the app deployment target to 14.0 in ios/Podfile:

platform :ios, '14.0'

Quick Start

import 'package:mapzone_flutter_alert_plugin/mapzone_flutter_alert_plugin.dart';

final alert = VietmapAlertController.instance;

// 1. Configure the engine. bundleId is read natively from the app itself and
//    must match the bundle id registered for the API key.
await alert.initialize(const AlertConfig(
  baseUrl: 'https://driving.map.zone',
  apiKeyId: 'YOUR_API_KEY_ID',
  apiKey: 'YOUR_API_KEY',
  vehicleId: 'YOUR_VEHICLE_ID',
  vehicleType: VehicleType.car, // car=1, motorcycle=2, truck=3, … emergency=9
  seats: 4,
  weight: 1500, // kg (int)
));

// 2. Listen to the alert streams.
alert.onReady.listen((r) => print('ready: ${r.linkCount} links'));
alert.onAlert.listen((e) {
  // e.currentSpeedLimitSign is Uint8List? PNG -> Image.memory(...)
  // e.speedStatus, e.nextDistanceMeters, e.cameraDistanceMeters, e.tollDistanceMeters
});
alert.onVoice.listen((v) => playWav(v.wav, v.priority)); // your audio player
alert.onResult.listen((r) { if (!r.success) print('error ${r.errorCode}'); });
alert.onLocation.listen((l) => print('${l.speedKmh} km/h'));

// 3. Standalone mode β€” native GPS capture.
if (await alert.requestLocationPermissions()) {
  await alert.start();
}

// 4. Tear down.
await alert.stop();
await alert.reset();

Register alert.registerLifecycleObserver() once to forward background/foreground transitions to the engine.

GPS modes

The engine needs a stream of GPS positions. There are two ways to provide them:

  • Standalone β€” call start() and the plugin captures native GPS itself. Best when the alert engine is the only thing that needs location.

  • Injected β€” feed positions yourself with processExternalLocation(). Use this to reuse the snapped location from a navigation SDK so the alert and the map agree:

    await alert.processExternalLocation(
      lat: 21.02, lng: 105.83, bearing: 90, speedKmh: 45,
    );
    

Muting voice categories

setMutedAlertTypes silences specific VoiceAlertType categories (speed camera, toll, red-light camera, no-overtaking, rest station, …). Muting a camera or toll category also hides its on-screen sign; the other categories are voice-only (they have no icon). Core speed-limit and speeding cues can never be muted β€” they are safety cues and are always announced.

await alert.setMutedAlertTypes([VoiceAlertType.speedCamera, VoiceAlertType.toll]);
await alert.setMutedAlertTypes([]); // re-enable all

Vehicle types

VehicleType codes match the native SDK enum:

car=1, motorcycle=2, truck=3, coach=4, bus=5, taxi=6, bicycle=7, pedestrian=8, emergency=9.

Only some types support speed alerts; an unsupported type is reported through onResult with error code 3003.

Error codes

AlertResult.errorCode:

0 success Β· 1001 invalid parameter (e.g. coordinates out of bounds) Β· 2003 unauthorized / expired API key Β· 3003 unsupported vehicle type Β· < 0 network / parsing error.

API Reference

Method Description
initialize(AlertConfig) Create / configure the native engine
configureVehicle(...) Re-create the engine with a new vehicle profile
start() / stop() Native GPS capture on / off (standalone mode)
processExternalLocation(...) Inject a GPS frame (injected mode)
updateZoneLocation(lat, lng) Lightweight zone-cache warm-up
setMutedAlertTypes(List<VoiceAlertType>) Mute voice per category
getLinkCoords(linkId) Matched-link polyline as [lat,lng] pairs (Android only)
reset() Free native memory
requestLocationPermissions() / hasLocationPermissions() Runtime permissions
registerLifecycleObserver() / unregisterLifecycleObserver() App lifecycle forwarding

Event streams

Stream Payload
onAlert Speed-limit / next-sign / camera / toll signs (PNG) + distances + speed status
onVoice Voice clip: WAV bytes + trigger + priority
onReady Zone loaded: linkCount, alertCount
onResult Success flag + errorCode + message
onLocation Current latitude / longitude / speedKmh / bearing

Example

See example/ for a single-screen demo app: a map screen with a destination search box (autocomplete / place v4). Pick a destination β†’ the route is built and drawn β†’ start simulated navigation; the snapped GPS is fed into the engine via processExternalLocation, the speed-limit / camera / toll signs render as a HUD, a speed chip shows the over-speed status, and a floating button configures voice muting per VoiceAlertType. Vehicle profile and route simulation are set from a settings dialog.

The route / map is drawn by the example's own navigation SDK β€” this alert plugin does not render maps; it only consumes GPS and emits sign / voice events.

Fill your Speed Alert credentials (and the map API key) in example/lib/env.dart before running.

License

MIT β€” see LICENSE.

Libraries

mapzone_flutter_alert_plugin
Flutter plugin for the Speed Alert SDK by Vietmap.