{"id":2809082,"date":"2025-06-10T07:30:14","date_gmt":"2025-06-10T14:30:14","guid":{"rendered":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=2809082"},"modified":"2025-06-09T06:33:36","modified_gmt":"2025-06-09T13:33:36","slug":"build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter","status":"publish","type":"blog","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter","title":{"rendered":"Build smarter location-aware apps with Geotriggers in ArcGIS Maps SDK for Flutter"},"author":366402,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"_acf_changed":false,"_searchwp_excluded":""},"categories":[738191],"tags":[773372,776092,765552,221062,35001],"industry":[],"product":[761642,776202,36601],"class_list":["post-2809082","blog","type-blog","status-publish","format-standard","hentry","category-developers","tag-flutter","tag-flutter-maps-sdk","tag-geotriggers","tag-location-intelligence","tag-mobile-development","product-platform","product-sdk-flutter","product-developers"],"acf":{"authors":[{"ID":366402,"user_firstname":"Kossi Martino","user_lastname":"Yovo","nickname":"Martino Yovo","user_nicename":"kyovo","display_name":"Martino Yovo","user_email":"kyovo@esri.com","user_url":"https:\/\/martinoyovo.com","user_registered":"2024-12-17 19:40:58","user_description":"Martino is a Product Engineer at Esri, a Google Developer Expert and a Developer Experience Engineer. He builds tools and SDKs that make technology more accessible and has supported thousands of developers through training, mentorship, and open-source contributions. Martino is passionate about helping engineers turn ideas into impactful products.","user_avatar":"<img data-del=\"avatar\" src='https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/11\/56723384-213x200.png' class='avatar pp-user-avatar avatar-96 photo ' height='96' width='96'\/>"}],"short_description":"Build smarter, location-aware apps with Geotriggers using the ArcGIS Maps SDK for Flutter. Add spatial awareness with ease and precision.","flexible_content":[{"acf_fc_layout":"content","content":"<h2><strong>Introduction<\/strong><\/h2>\n<p>Ever wanted to provide notifications to users based on their location? With the latest release of v200.7 in the <a href=\"https:\/\/developers.arcgis.com\/flutter\/\">ArcGIS Maps SDK for Flutter<\/a>, you can now use geotriggers to build spatially aware apps to either alert a driver when they approach a school zone or announce a warning as someone enters a hazard area.<\/p>\n<p data-start=\"561\" data-end=\"940\">This article was inspired by the <a href=\"https:\/\/mediaspace.esri.com\/media\/1_51igflaj?kalturaStartTime=80\" target=\"_blank\" rel=\"noopener\">2025 Esri Developer &amp; Technology Summit plenary demo<\/a>, presented by my colleague Jen Merritt which beautifully showcased how geotriggers can unlock real-time spatial awareness in Flutter apps. Building on that example, you\u2019ll create a fully working app that combines <strong data-start=\"815\" data-end=\"833\">voice guidance<\/strong>, <strong data-start=\"835\" data-end=\"853\">route tracking<\/strong>, and <strong data-start=\"859\" data-end=\"891\">location-based notifications<\/strong>, all powered by the ArcGIS Maps SDK for Flutter.<\/p>\n"},{"acf_fc_layout":"image","image":{"ID":2813202,"id":2813202,"title":"Geotriggers_Flutter_Banner","filename":"Geotriggers_Flutter_Banner.png","filesize":626765,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\/geotriggers_flutter_banner","alt":"","author":"366402","description":"","caption":"Real-Time Navigation and Safety Alerts with Geotriggers in Flutter","name":"geotriggers_flutter_banner","status":"inherit","uploaded_to":2809082,"date":"2025-05-28 23:49:44","modified":"2025-06-04 22:46:07","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":1920,"height":1080,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner.png","medium-width":464,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner.png","medium_large-width":768,"medium_large-height":432,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner.png","large-width":1920,"large-height":1080,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner-1536x864.png","1536x1536-width":1536,"1536x1536-height":864,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner.png","2048x2048-width":1920,"2048x2048-height":1080,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner-826x465.png","card_image-width":826,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_Flutter_Banner.png","wide_image-width":1920,"wide_image-height":1080}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<p>Whilst the focus of this blog is on the Flutter Maps SDK, the Geotriggers API functionality described here can also be applied to the whole suite of ArcGIS Maps SDKs for Native Apps, including the Qt, .NET, Kotlin and Swift Maps SDKs.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2><strong>What we&#8217;ll build<\/strong><\/h2>\n<p>A Flutter app that:<\/p>\n<ul>\n<li>Loads a map and displays a navigation route<\/li>\n<li>Simulates a moving location<\/li>\n<li>Uses Geotriggers to detect entry\/exit into warning zones<\/li>\n<li>Plays voice alerts based on the Geotrigger type<\/li>\n<li>Visually updates route progress and warnings in the UI<\/li>\n<li>Uses intuitive controls and widgets for navigation<\/li>\n<\/ul>\n"},{"acf_fc_layout":"content","content":"<h2><strong>What are Geotriggers?<\/strong><\/h2>\n<p><a href=\"https:\/\/developers.arcgis.com\/kotlin\/device-location\/work-with-geotriggers\/\" target=\"_blank\" rel=\"noopener\">Geotriggers<\/a> are a set of rules that monitor real-world locations. You can define a condition like: <em>&#8220;When the user enters this zone, show a warning&#8221;<\/em> and your app will listen for it in real-time.<\/p>\n<p>With the Flutter Maps SDK, you can:<\/p>\n<ul>\n<li>Watch for entry\/exit in a zone<\/li>\n<li>Trigger actions using Arcade expressions<\/li>\n<li>Work offline or with online services<\/li>\n<\/ul>\n<h2><strong>Requirements<\/strong><\/h2>\n<p>To follow this blog, you should have a basic understanding of building Flutter apps and installing packages.<\/p>\n<ul>\n<li>Add the <a href=\"https:\/\/pub.dev\/packages\/arcgis_maps\/versions\">arcgis_maps<\/a> package to your Flutter project.<\/li>\n<li>Generate and configure your <a href=\"https:\/\/developers.arcgis.com\/documentation\/security-and-authentication\/api-key-authentication\/tutorials\/create-an-api-key\/\">ArcGIS API Key<\/a>.<\/li>\n<\/ul>\n<p>For detailed instructions, including platform-specific steps, refer to the <a href=\"https:\/\/developers.arcgis.com\/flutter\/\">official ArcGIS Maps SDK for Flutter documentation<\/a>.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Setting up the Map<\/strong><\/h2>\n<p>The initial location is a fixed coordinate, useful for testing and previewing routes without relying on live data.<\/p>\n<pre><code><span style=\"color: #d73a49;\">final<\/span> _initialLocation = ArcGISPoint(\r\n  x: -<span style=\"color: #005cc5;\">1.2163758893108882<\/span>,\r\n  y: <span style=\"color: #005cc5;\">54.16376654622336<\/span>,\r\n  spatialReference: SpatialReference.wgs84,\r\n);\r\n\r\n<span style=\"color: #d73a49;\">final<\/span> _nextDeliveryLocation = ArcGISPoint(\r\n  x: -<span style=\"color: #005cc5;\">0.655327<\/span>,\r\n  y: <span style=\"color: #005cc5;\">54.477301<\/span>,\r\n  spatialReference: SpatialReference.wgs84,\r\n);<\/code><\/pre>\n<p>The initial location is a fixed coordinate, useful for testing and previewing routes without relying on live data.<\/p>\n<p>However, in a real-world app, you can replace this with the user\u2019s actual GPS location. If you&#8217;d like to see how to access live location in the Flutter Maps SDK, refer to my previous article.<\/p>\n<p>Next, we display a map centered on the initial location using the <code>ArcGISMapView<\/code> widget from the ArcGIS Maps SDK for Flutter.<\/p>\n<p>Here\u2019s how it looks like:<\/p>\n<pre><code><span style=\"color: #d73a49;\">final<\/span> _mapViewController = ArcGISMapView.createController();\r\n\r\nArcGISMapView(\r\n  controllerProvider: () =&gt; _mapViewController,\r\n  onMapViewReady: onMapViewReady,\r\n);<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<p>Inside <code>onMapViewReady<\/code>, we assign a navigation-style basemap and center the map:<\/p>\n<pre><code>\r\n<span style=\"color: #d73a49;\">final<\/span> map = ArcGISMap.withBasemapStyle(BasemapStyle.arcGISNavigation);\r\n_mapViewController.arcGISMap = map;\r\n\r\n_mapViewController.setViewpoint(\r\n  Viewpoint.fromCenter(_initialLocation, scale: <span style=\"color: #005cc5;\">50000<\/span>),\r\n);\r\n<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Creating and Solving a Route<\/strong><\/h2>\n<p>Once the map is ready, we create a <strong>route<\/strong> from the starting point to the destination using the ArcGIS <strong>RouteTask<\/strong> service.<\/p>\n<pre><code>Future&lt;<span style=\"color: #d73a49;\">void<\/span>&gt; initRoute() <span style=\"color: #d73a49;\">async<\/span> {\r\n  <span style=\"color: #d73a49;\">final<\/span> initialStop = Stop(_initialLocation);\r\n  <span style=\"color: #d73a49;\">final<\/span> destinationStop = Stop(_nextDeliveryLocation);\r\n\r\n  <span style=\"color: #d73a49;\">final<\/span> routeTask = RouteTask.withUri(\r\n    <span style=\"color: #e36209;\">Uri<\/span>.parse(<span style=\"color: #032f62;\">'https:\/\/route-api.arcgis.com\/arcgis\/rest\/services\/World\/Route\/NAServer\/Route_World'<\/span>),\r\n  );\r\n\r\n  <span style=\"color: #d73a49;\">final<\/span> routeParameters = <span style=\"color: #d73a49;\">await<\/span> routeTask.createDefaultParameters();\r\n  routeParameters.setStops([initialStop, destinationStop]);\r\n  routeParameters.returnRoutes = <span style=\"color: #d73a49;\">true<\/span>;\r\n  routeParameters.returnDirections = <span style=\"color: #d73a49;\">true<\/span>;\r\n\r\n  <span style=\"color: #d73a49;\">final<\/span> routeResult = <span style=\"color: #d73a49;\">await<\/span> routeTask.solveRoute(routeParameters);\r\n\r\n  <span style=\"color: #d73a49;\">if<\/span> (routeResult.routes.isNotEmpty) {\r\n    <span style=\"color: #d73a49;\">final<\/span> route = routeResult.routes.first;\r\n    <span style=\"color: #6a737d;\">\/\/ Save the route and directions for later navigation.<\/span>\r\n  }\r\n}<\/code><\/pre>\n<p>This gives us a <strong>polyline<\/strong> representing the route geometry, a <strong>list of direction maneuvers<\/strong> (like turns and exits), and estimates for travel time and distance.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Displaying the Route Preview<\/strong><\/h2>\n"},{"acf_fc_layout":"image","image":{"ID":2821592,"id":2821592,"title":"display_route_preview_2","filename":"display_route_preview_updated.png","filesize":149980,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\/display_route_preview_updated","alt":"Route Preview Screen","author":"366402","description":"","caption":"Route Preview Screen","name":"display_route_preview_updated","status":"inherit","uploaded_to":2809082,"date":"2025-06-04 23:21:02","modified":"2025-06-05 22:01:47","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":308,"height":692,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated.png","medium-width":116,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated.png","medium_large-width":308,"medium_large-height":692,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated.png","large-width":308,"large-height":692,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated.png","1536x1536-width":308,"1536x1536-height":692,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated.png","2048x2048-width":308,"2048x2048-height":692,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated-207x465.png","card_image-width":207,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/display_route_preview_updated.png","wide_image-width":308,"wide_image-height":692}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<p>Before navigation starts, it\u2019s helpful to visually preview the planned route along with the destination. This method clears existing overlays, draws the route with a styled polyline, and marks the destination with a custom composite symbol:<\/p>\n<pre><code><span style=\"color: #d73a49;\">void<\/span> displayRoutePreview(Polyline routeGeometry) {\r\n  <span style=\"color: #e36209;\">print<\/span>(<span style=\"color: #032f62;\">\"display preview route\"<\/span>);\r\n  _mapViewController.graphicsOverlays.clear();\r\n  setState(() {\r\n    _showPreview = !_showPreview;\r\n  });\r\n\r\n  <span style=\"color: #d73a49;\">final<\/span> baseLineSymbol = SimpleLineSymbol(color: Colors.cyan, width: <span style=\"color: #005cc5;\">10<\/span>);\r\n  <span style=\"color: #d73a49;\">final<\/span> topLineSymbol = SimpleLineSymbol(color: Colors.cyanAccent, width: <span style=\"color: #005cc5;\">3<\/span>);\r\n\r\n  _remainingRouteGraphic = Graphic(\r\n    geometry: routeGeometry,\r\n    symbol: CompositeSymbol(symbols: [baseLineSymbol, topLineSymbol]),\r\n  );\r\n\r\n  <span style=\"color: #d73a49;\">final<\/span> baseSymbol = SimpleMarkerSymbol(color: Colors.cyan, size: <span style=\"color: #005cc5;\">20<\/span>);\r\n  <span style=\"color: #d73a49;\">final<\/span> topSymbol = SimpleMarkerSymbol(color: Color(<span style=\"color: #005cc5;\">0xFFF3F3F3<\/span>), size: <span style=\"color: #005cc5;\">10<\/span>);\r\n  <span style=\"color: #d73a49;\">final<\/span> compSymbol = CompositeSymbol(symbols: [baseSymbol, topSymbol]);\r\n\r\n  <span style=\"color: #d73a49;\">final<\/span> destinationGraphic = Graphic(\r\n    geometry: _nextDeliveryLocation,\r\n    symbol: compSymbol,\r\n  )..zIndex = <span style=\"color: #005cc5;\">100<\/span>;\r\n\r\n  _routeGraphicsOverlay.graphics.addAll([\r\n    _remainingRouteGraphic,\r\n    destinationGraphic,\r\n  ]);\r\n\r\n  _mapViewController.graphicsOverlays.add(_routeGraphicsOverlay);\r\n\r\n  _mapViewController.setViewpointGeometry(\r\n    routeGeometry.extent,\r\n    paddingInDiPs: <span style=\"color: #005cc5;\">50.0<\/span>,\r\n  );\r\n}<\/code><\/pre>\n<p>This gives the user immediate visual feedback about the route and the delivery destination before the trip begins.<\/p>\n<p>Now that we have the route, we can move on to launching the navigation experience.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Simulating Navigation<\/strong><\/h2>\n"},{"acf_fc_layout":"image","image":{"ID":2821642,"id":2821642,"title":"simulating_navigation","filename":"simulating_navigation.png","filesize":97657,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\/simulating_navigation","alt":"Navigation Guidance with Real-Time Instructions","author":"366402","description":"","caption":"Navigation Guidance with Real-Time Instructions","name":"simulating_navigation","status":"inherit","uploaded_to":2809082,"date":"2025-06-04 23:37:20","modified":"2025-06-05 22:02:04","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":304,"height":682,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation.png","medium-width":116,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation.png","medium_large-width":304,"medium_large-height":682,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation.png","large-width":304,"large-height":682,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation.png","1536x1536-width":304,"1536x1536-height":682,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation.png","2048x2048-width":304,"2048x2048-height":682,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation-207x465.png","card_image-width":207,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/simulating_navigation.png","wide_image-width":304,"wide_image-height":682}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<p>Since we\u2019re testing without real GPS movement, we simulate travel along the route using a <code>SimulatedLocationDataSource<\/code>.<\/p>\n<p>We load a pre-recorded path from a <code>.json<\/code> file and replay it over the route geometry.<\/p>\n<p>Here\u2019s how the simulated location is configured:<\/p>\n<pre><code>Future&lt;<span style=\"color: #d73a49;\">void<\/span>&gt; initStaticLocation() <span style=\"color: #d73a49;\">async<\/span> {\r\n  <span style=\"color: #d73a49;\">final<\/span> json = <span style=\"color: #d73a49;\">await<\/span> rootBundle.loadString(<span style=\"color: #032f62;\">'assets\/simulated_location.json'<\/span>);\r\n  <span style=\"color: #d73a49;\">final<\/span> polyline = Geometry.fromJsonString(json) <span style=\"color: #d73a49;\">as<\/span> Polyline;\r\n  _locationDataSource.setLocationsWithPolyline(polyline);\r\n  _mapViewController.locationDisplay.dataSource = _locationDataSource;\r\n  <span style=\"color: #d73a49;\">await<\/span> _locationDataSource.start();\r\n}<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<p>The JSON file contains a list of coordinates forming a <strong>polyline<\/strong>. These points are replayed at a controlled speed to simulate movement. This is useful for development and testing, but in a real app, we would instead rely on live location updates.<\/p>\n<pre><code>{\r\n  <span style=\"color: #005cc5;\">\"paths\"<\/span>: [\r\n    [\r\n      [\r\n        <span style=\"color: #005cc5;\">-1.2163758893108882<\/span>,\r\n        <span style=\"color: #005cc5;\">54.16376654622336<\/span>\r\n      ],\r\n      [\r\n        <span style=\"color: #005cc5;\">-1.2163758893108882<\/span>,\r\n        <span style=\"color: #005cc5;\">54.16376654622336<\/span>\r\n      ]\r\n    ]\r\n  ]\r\n}<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Real-Time Navigation<\/strong><\/h2>\n<p>In a production scenario, we use the device\u2019s live location with <code>SystemLocationDataSource<\/code>:<\/p>\n<pre><code><span style=\"color: #d73a49;\">final<\/span> _locationDataSource = SystemLocationDataSource();\r\n<span style=\"color: #d73a49;\">late<\/span> StreamSubscription&lt;Location&gt; _locationSubscription;<\/code><\/pre>\n<p>Inside <code>initState<\/code>, we subscribe to the live location stream and update the current position:<\/p>\n<pre><code>_locationSubscription = _locationDataSource.onLocationChanged.listen((location) {\r\n  <span style=\"color: #d73a49;\">final<\/span> position = location.position;\r\n  <span style=\"color: #d73a49;\">final<\/span> point = ArcGISPoint(\r\n    x: position.x,\r\n    y: position.y,\r\n    spatialReference: SpatialReference.wgs84,\r\n  );\r\n  _currentPosition = point; <span style=\"color: #6a737d;\">\/\/ _initialPosition renamed as _currentPosition for real-time tracking.<\/span>\r\n});<\/code><\/pre>\n<p>Don&#8217;t forget to cancel the subscription in dispose to avoid memory leaks:<\/p>\n<pre><code><span style=\"color: #005cc5;\">@override<\/span>\r\n<span style=\"color: #d73a49;\">void<\/span> dispose() {\r\n  ...\r\n  _locationSubscription.cancel();\r\n  ...\r\n  <span style=\"color: #d73a49;\">super<\/span>.dispose();\r\n}<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Starting Navigation and Voice Guidance<\/strong><\/h2>\n<p>Once the location updates are in place, we can start <strong>tracking<\/strong> the user\u2019s position along the route and <strong>speaking navigation instructions<\/strong> during travel.<\/p>\n<p>To do this, we combine:<\/p>\n<ul>\n<li><code>RouteTracker<\/code> : a class from the <strong>Flutter Maps SDK<\/strong> that monitors the user\u2019s progress along a route and detects maneuvers (turns, exits, arrivals).<\/li>\n<li><code>flutter_tts<\/code> : a <a href=\"https:\/\/pub.dev\/packages\/flutter_tts\" target=\"_blank\" rel=\"noopener\">Flutter package<\/a> for text-to-speech, which we use to speak directions out loud.<\/li>\n<\/ul>\n<h3><strong>Setting Up Route Tracker<\/strong><\/h3>\n<p>We create a <code>RouteTracker<\/code> to monitor the navigation session:<\/p>\n<pre><code><span style=\"color: #d73a49;\">late<\/span> RouteTracker _routeTracker;\r\n\r\nFuture&lt;<span style=\"color: #d73a49;\">void<\/span>&gt; startNavigation() <span style=\"color: #d73a49;\">async<\/span> {\r\n  _routeTracker = RouteTracker.create(\r\n    routeResult: _routeResult,\r\n    routeIndex: <span style=\"color: #005cc5;\">0<\/span>,\r\n    skipCoincidentStops: <span style=\"color: #d73a49;\">true<\/span>,\r\n  )!;\r\n\r\n  <span style=\"color: #6a737d;\">\/\/ Set the unit system for voice guidance.<\/span>\r\n  _routeTracker.voiceGuidanceUnitSystem = UnitSystem.imperial;\r\n}<\/code><\/pre>\n<p>The <code>RouteTracker<\/code> automatically follows the user\u2019s location, updates the progress along the route and generates <strong>VoiceGuidance<\/strong> events at the right moments.<\/p>\n<p><code>voiceGuidanceUnitSystem<\/code> allows you to control whether distances are announced in <strong>imperial units<\/strong> (miles, feet) or <strong>metric units<\/strong> (kilometers, meters). In our case, we set it to <strong>imperial<\/strong>, but you can easily adjust based on your app\u2019s audience or location.<\/p>\n<h3><strong>Installing Flutter TTS<\/strong><\/h3>\n<p>First, add the <code>flutter_tts<\/code> package to your project:<\/p>\n<pre><code>flutter pub add flutter_tts<\/code><\/pre>\n<p>Then install it:<\/p>\n<pre><code>flutter pub get<\/code><\/pre>\n<blockquote style=\"border-left: 4px solid #1b7ac2; background-color: #e3f2fd; padding: 10px; border-radius: 2px;\"><p><strong style=\"color: #1b7ac2;\">\ud83d\udca1 Tip:<\/strong> Flutter TTS works best on a <strong>real device<\/strong>. Simulators and emulators might not support voice output properly.<\/p><\/blockquote>\n"},{"acf_fc_layout":"content","content":"<h3><strong>Integrating Text-to-Speech (TTS)<\/strong><\/h3>\n<p>We initialize Flutter TTS in our initState:<\/p>\n<pre><code><span style=\"color: #d73a49;\">late<\/span> FlutterTts _ttsEngine;\r\n\r\n<span style=\"color: #005cc5;\">@override<\/span>\r\n<span style=\"color: #d73a49;\">void<\/span> initState() {\r\n  <span style=\"color: #d73a49;\">super<\/span>.initState();\r\n  _ttsEngine = FlutterTts()\r\n    ..setLanguage(<span style=\"color: #032f62;\">'en-US'<\/span>)\r\n    ..setSpeechRate(<span style=\"color: #005cc5;\">0.5<\/span>); <span style=\"color: #6a737d;\">\/\/ Optional: slower speech for clarity.<\/span>\r\n}<\/code><\/pre>\n<p>This configures the TTS engine to speak at a moderate speed using US English. By default, the language is set to US English, but you can change the language to any supported locale by passing a different code (e.g., &#8216;fr-FR&#8217;, &#8216;es-ES&#8217;, &#8216;de-DE&#8217;).<\/p>\n<p>Once initialized, we set up a listener to respond to new voice guidance events:<\/p>\n<pre><code><span style=\"color: #d73a49;\">late<\/span> StreamSubscription&lt;VoiceGuidance&gt; _voiceGuidanceSubscription;\r\n\r\n<span style=\"color: #d73a49;\">void<\/span> listenToVoiceGuidance() {\r\n  _voiceGuidanceSubscription = _routeTracker.onNewVoiceGuidance.listen(\r\n    (voiceGuidance) {\r\n      updateVoiceGuidance(voiceGuidance.text);\r\n    },\r\n  );\r\n}\r\n\r\n<span style=\"color: #d73a49;\">void<\/span> updateVoiceGuidance(<span style=\"color: #e36209;\">String<\/span> text) <span style=\"color: #d73a49;\">async<\/span> {\r\n  <span style=\"color: #d73a49;\">await<\/span> _ttsEngine.speak(text);\r\n}<\/code><\/pre>\n<p>Every time a new maneuver is triggered (like &#8220;turn right&#8221; or &#8220;continue forward&#8221;), the app will <strong>speak it out loud<\/strong> automatically.<\/p>\n<p>At this stage: our app follows the route, updates directions visually and speaks directions to guide the user.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Triggering Warnings with Geotriggers<\/strong><\/h2>\n"},{"acf_fc_layout":"image","image":{"ID":2822362,"id":2822362,"title":"trigger_warnings","filename":"4-1.png","filesize":135028,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\/4-66","alt":"Location-Aware Alerts with Geotriggers","author":"366402","description":"","caption":"Location-Aware Alerts with Geotriggers","name":"4-66","status":"inherit","uploaded_to":2809082,"date":"2025-06-05 22:20:05","modified":"2025-06-05 22:20:31","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":304,"height":682,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1.png","medium-width":116,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1.png","medium_large-width":304,"medium_large-height":682,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1.png","large-width":304,"large-height":682,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1.png","1536x1536-width":304,"1536x1536-height":682,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1.png","2048x2048-width":304,"2048x2048-height":682,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1-207x465.png","card_image-width":207,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/06\/4-1.png","wide_image-width":304,"wide_image-height":682}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<p>In addition to following the route, our app can detect when the user enters or exits <strong>pre-defined zones<\/strong> (like school zones, hazard areas, or delivery points) and <strong>trigger warnings<\/strong> automatically.<\/p>\n<p><strong>Geotriggers don\u2019t detect areas on their own<\/strong>. Instead, we must <strong>explicitly define<\/strong> these zones (typically as polygons, circles, or buffers), and then configure geotriggers to monitor user movement relative to them. The Flutter Maps SDK handles the logic for triggering events when the user enters or exits these defined areas.<\/p>\n"},{"acf_fc_layout":"content","content":"<h3><strong>Loading Predefined Geographical Zones<\/strong><\/h3>\n<p>To power location-based notifications with geotriggers, we first need to load the spatial data that defines where those zones are such as school zones, hazard areas, or delivery points. In this example, we\u2019re loading two hosted feature layers from ArcGIS Online:<\/p>\n<ul>\n<li>One for the <strong>warning points<\/strong> (individual locations)<\/li>\n<li>Another for the <strong>buffer zones<\/strong> (areas around those points)<\/li>\n<\/ul>\n<p>Here\u2019s how to load both layers and prepare them for use:<\/p>\n<pre><code>Future&lt;<span style=\"color: #d73a49;\">void<\/span>&gt; loadFeatureLayers() <span style=\"color: #d73a49;\">async<\/span> {\r\n  <span style=\"color: #d73a49;\">final<\/span> portal = Portal.arcGISOnline();\r\n  <span style=\"color: #d73a49;\">final<\/span> item = PortalItem.withPortalAndItemId(\r\n    portal: portal,\r\n    itemId: <span style=\"color: #032f62;\">'49e3861dd16d4b4abdadbb1acbf26bd8'<\/span>,\r\n  );\r\n  <span style=\"color: #d73a49;\">final<\/span> bufferItem = PortalItem.withPortalAndItemId(\r\n    portal: portal,\r\n    itemId: <span style=\"color: #032f62;\">'ad36192fc08340cb877d31593e3ef204'<\/span>,\r\n  );\r\n  _pointFeatureLayer = FeatureLayer.withFeatureLayerItem(item);\r\n  _bufferFeatureLayer = FeatureLayer.withFeatureLayerItem(bufferItem);\r\n  <span style=\"color: #d73a49;\">await<\/span> _pointFeatureLayer.load();\r\n  <span style=\"color: #d73a49;\">await<\/span> _bufferFeatureLayer.load();\r\n  _pointFeatureLayer.isVisible = <span style=\"color: #d73a49;\">false<\/span>;\r\n  _bufferFeatureLayer.isVisible = <span style=\"color: #d73a49;\">false<\/span>;\r\n  _warningPointsTable = _pointFeatureLayer.featureTable;\r\n  _mapViewController.arcGISMap!.operationalLayers.addAll([\r\n    _bufferFeatureLayer,\r\n    _pointFeatureLayer,\r\n  ]);\r\n}<\/code><\/pre>\n<p>These layers will be used later to trigger geofence-style alerts notifications that are activated when a user enters or exits a defined geographic area\u2014as the user moves along the route.<\/p>\n"},{"acf_fc_layout":"content","content":"<h3><strong>Setting Up Geotrigger Monitoring<\/strong><\/h3>\n<p>First, we prepare a <strong>feature layer<\/strong> that contains warning zones, and configure the trigger:<\/p>\n<pre><code>Future&lt;<span style=\"color: #d73a49;\">void<\/span>&gt; loadFeatureLayers() <span style=\"color: #d73a49;\">async<\/span> {\r\n  <span style=\"color: #d73a49;\">final<\/span> portal = Portal.arcGISOnline();\r\n  <span style=\"color: #d73a49;\">final<\/span> item = PortalItem.withPortalAndItemId(\r\n    portal: portal,\r\n    itemId: <span style=\"color: #032f62;\">'49e3861dd16d4b4abdadbb1acbf26bd8'<\/span>,\r\n  );\r\n  <span style=\"color: #d73a49;\">final<\/span> bufferItem = PortalItem.withPortalAndItemId(\r\n    portal: portal,\r\n    itemId: <span style=\"color: #032f62;\">'ad36192fc08340cb877d31593e3ef204'<\/span>,\r\n  );\r\n  _pointFeatureLayer = FeatureLayer.withFeatureLayerItem(item);\r\n  _bufferFeatureLayer = FeatureLayer.withFeatureLayerItem(bufferItem);\r\n  <span style=\"color: #d73a49;\">await<\/span> _pointFeatureLayer.load();\r\n  <span style=\"color: #d73a49;\">await<\/span> _bufferFeatureLayer.load();\r\n  _pointFeatureLayer.isVisible = <span style=\"color: #d73a49;\">false<\/span>;\r\n  _bufferFeatureLayer.isVisible = <span style=\"color: #d73a49;\">false<\/span>;\r\n  _warningPointsTable = _pointFeatureLayer.featureTable;\r\n  _mapViewController.arcGISMap!.operationalLayers.addAll([\r\n    _bufferFeatureLayer,\r\n    _pointFeatureLayer,\r\n  ]);\r\n}<\/code><\/pre>\n<p>We define a <strong>geofence<\/strong> around points of interest. As the user moves (based on simulated or real location), the app <strong>monitors<\/strong> whether they enter or exit a zone. If triggered, the app sends a warning.<\/p>\n<h3><strong>Handling Geotrigger Events<\/strong><\/h3>\n<p>When a geotrigger fires (user enters or exits a warning zone), we react like this:<\/p>\n<pre><code><span style=\"color: #d73a49;\">void<\/span> handleGeotriggerEvent(GeotriggerNotificationInfo info) {\r\n  <span style=\"color: #d73a49;\">final<\/span> fenceInfo = info <span style=\"color: #d73a49;\">as<\/span> FenceGeotriggerNotificationInfo;\r\n\r\n  setState(() {\r\n    <span style=\"color: #d73a49;\">if<\/span> (fenceInfo.fenceNotificationType == FenceNotificationType.entered) {\r\n      _warningActive = <span style=\"color: #d73a49;\">true<\/span>;\r\n      _warningType = fenceInfo.message;\r\n      updateVoiceGuidance(<span style=\"color: #032f62;\">'Warning, <span style=\"color: #24292e;\">$_warningType<\/span> ahead.'<\/span>);\r\n    } <span style=\"color: #d73a49;\">else<\/span> <span style=\"color: #d73a49;\">if<\/span> (fenceInfo.fenceNotificationType == FenceNotificationType.exited) {\r\n      _warningActive = <span style=\"color: #d73a49;\">false<\/span>;\r\n      updateVoiceGuidance(<span style=\"color: #032f62;\">'End of <span style=\"color: #24292e;\">$_warningType<\/span> zone.'<\/span>);\r\n    }\r\n  });\r\n}<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Building the Navigation Interface<\/strong><\/h2>\n<p>The app\u2019s interface is built using standard Flutter widgets layered over the <code>ArcGISMapView<\/code> using a Stack layout. It includes:<\/p>\n<ul>\n<li>A route preview panel before navigation starts<\/li>\n<li>A directions banner powered by <code>RouteTracker<\/code><\/li>\n<li>A warning widget triggered by geotriggers<\/li>\n<li>Floating buttons for zoom, mute, and toggling zones<\/li>\n<li>A bottom bar to start or stop navigation<\/li>\n<\/ul>\n<p>You can explore all these widgets in the full code (more details on this below) and customize them to fit your app&#8217;s design.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2><strong>Full Project Code + Demo<\/strong><\/h2>\n<p>You can find the complete source code for this project on GitHub: <a href=\"https:\/\/github.com\/martinoyovo\/geo_navigation_flutter\"><strong>https:\/\/github.com\/martinoyovo\/geo_navigation_flutter<\/strong><\/a>.<\/p>\n<p style=\"text-align: left;\">You can also check out the video below to see the app in action!<\/p>\n<div style=\"text-align: center;\"><video src=\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/Geotriggers_demo_final.mp4\" controls=\"controls\" width=\"305\" height=\"150\"><\/video><\/div>\n"},{"acf_fc_layout":"content","content":"<h2 style=\"text-align: left;\"><strong>Conclusion<\/strong><\/h2>\n<p style=\"text-align: left;\">With Geotriggers in the ArcGIS Maps SDK for Flutter, you can go beyond basic maps and routing to build <strong>context-aware apps<\/strong> that react to the world around your users. From safety alerts to dynamic navigation, geotriggers offer a powerful way to make your apps truly location-smart.<\/p>\n<p style=\"text-align: left;\">But this is just the beginning. You can expand this example with <strong>real-time GPS, Arcade expressions, or live data feeds<\/strong>. Find more powerful examples in the <a class=\"\" href=\"https:\/\/github.com\/Esri\/arcgis-maps-sdk-flutter-samples\" target=\"_blank\" rel=\"noopener\" data-start=\"356\" data-end=\"400\">ArcGIS Maps SDK Sample Viewer on GitHub<\/a>.<\/p>\n<p style=\"text-align: left;\">Ready to build your own location-aware app? Start exploring the <a href=\"https:\/\/developers.arcgis.com\/flutter\/\">Flutter Maps SDK<\/a> and bring geospatial intelligence to life.<\/p>\n<p style=\"text-align: left;\" data-start=\"446\" data-end=\"565\">See my colleague Jen Merritt&#8217;s live demo from the Esri Developer &amp; Technology Summit plenary in action below, and get inspired to bring geotriggers into your own apps.<\/p>\n"},{"acf_fc_layout":"kaltura","video_id":"1_51igflaj","time":true,"start":"80","stop":""}],"related_articles":[{"ID":2630272,"post_author":"366402","post_date":"2024-12-17 17:22:38","post_date_gmt":"2024-12-18 01:22:38","post_content":"","post_title":"Handling location permission in ArcGIS Maps SDK for Flutter","post_excerpt":"","post_status":"publish","comment_status":"closed","ping_status":"closed","post_password":"","post_name":"handling-location-permission-in-flutter","to_ping":"","pinged":"","post_modified":"2024-12-20 03:46:10","post_modified_gmt":"2024-12-20 11:46:10","post_content_filtered":"","post_parent":0,"guid":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=2630272","menu_order":0,"post_type":"blog","post_mime_type":"","comment_count":"0","filter":"raw"},{"ID":2622922,"post_author":"10242","post_date":"2024-12-12 14:58:48","post_date_gmt":"2024-12-12 22:58:48","post_content":"","post_title":"How to map vehicle meeting points using ArcGIS Maps SDK for Flutter","post_excerpt":"","post_status":"publish","comment_status":"closed","ping_status":"closed","post_password":"","post_name":"map-vehicle-meeting-points-flutter","to_ping":"","pinged":"","post_modified":"2024-12-13 03:06:04","post_modified_gmt":"2024-12-13 11:06:04","post_content_filtered":"","post_parent":0,"guid":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=2622922","menu_order":0,"post_type":"blog","post_mime_type":"","comment_count":"0","filter":"raw"},{"ID":2600092,"post_author":"3811","post_date":"2024-11-25 07:55:15","post_date_gmt":"2024-11-25 15:55:15","post_content":"","post_title":"Introducing the ArcGIS Maps SDK for Flutter","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"introducing-the-arcgis-maps-sdk-for-flutter","to_ping":"","pinged":"","post_modified":"2024-11-26 11:40:30","post_modified_gmt":"2024-11-26 19:40:30","post_content_filtered":"","post_parent":0,"guid":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=2600092","menu_order":0,"post_type":"blog","post_mime_type":"","comment_count":"0","filter":"raw"}],"show_article_image":true,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/05\/geotrigger_article_small_banner.png","wide_image":false},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Build location-aware apps with Geotriggers in the Flutter Maps SDK<\/title>\n<meta name=\"description\" content=\"Build smarter, location-aware apps with Geotriggers using the ArcGIS Maps SDK for Flutter. Add spatial awareness with ease and precision.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build smarter location-aware apps with Geotriggers in ArcGIS Maps SDK for Flutter\" \/>\n<meta property=\"og:description\" content=\"Build smarter, location-aware apps with Geotriggers using the ArcGIS Maps SDK for Flutter. Add spatial awareness with ease and precision.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\" \/>\n<meta property=\"og:site_name\" content=\"ArcGIS Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/esrigis\/\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@ESRI\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\"},\"author\":{\"name\":\"Martino Yovo\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/6a6793a4e379c3efd9a8ca8650a626e6\"},\"headline\":\"Build smarter location-aware apps with Geotriggers in ArcGIS Maps SDK for Flutter\",\"datePublished\":\"2025-06-10T14:30:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\"},\"wordCount\":12,\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"keywords\":[\"flutter\",\"Flutter Maps SDK\",\"GeoTriggers\",\"Location intelligence\",\"mobile development\"],\"articleSection\":[\"Developers\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\",\"name\":\"Build location-aware apps with Geotriggers in the Flutter Maps SDK\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\"},\"datePublished\":\"2025-06-10T14:30:14+00:00\",\"description\":\"Build smarter, location-aware apps with Geotriggers using the ArcGIS Maps SDK for Flutter. Add spatial awareness with ease and precision.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.esri.com\/arcgis-blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build smarter location-aware apps with Geotriggers in ArcGIS Maps SDK for Flutter\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"name\":\"ArcGIS Blog\",\"description\":\"Get insider info from Esri product teams\",\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\",\"name\":\"Esri\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"width\":400,\"height\":400,\"caption\":\"Esri\"},\"image\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/esrigis\/\",\"https:\/\/x.com\/ESRI\",\"https:\/\/www.linkedin.com\/company\/5311\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/6a6793a4e379c3efd9a8ca8650a626e6\",\"name\":\"Martino Yovo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/11\/56723384-213x200.png\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/11\/56723384-213x200.png\",\"caption\":\"Martino Yovo\"},\"description\":\"Martino is a Product Engineer at Esri, a Google Developer Expert and a Developer Experience Engineer. He builds tools and SDKs that make technology more accessible and has supported thousands of developers through training, mentorship, and open-source contributions. Martino is passionate about helping engineers turn ideas into impactful products.\",\"sameAs\":[\"https:\/\/martinoyovo.com\",\"https:\/\/facebook.com\/yovo.martino\",\"https:\/\/instagram.com\/martinoyovo\",\"https:\/\/linkedin.com\/in\/martino-yovo\",\"https:\/\/x.com\/https:\/\/x.com\/martinoyovo\",\"https:\/\/www.youtube.com\/@martinoyovo\"],\"gender\":\"male\",\"award\":[\"Google Developer Expert\"],\"knowsAbout\":[\"Program Management\",\"Community Building and leading\",\"Youth Employment\",\"Youth Skilling\",\"Flutter\",\"Software Development\"],\"knowsLanguage\":[\"English\",\"French\",\"Ewe\"],\"jobTitle\":\"Product Engineer\",\"worksFor\":\"Esri\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/author\/kyovo\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Build location-aware apps with Geotriggers in the Flutter Maps SDK","description":"Build smarter, location-aware apps with Geotriggers using the ArcGIS Maps SDK for Flutter. Add spatial awareness with ease and precision.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter","og_locale":"en_US","og_type":"article","og_title":"Build smarter location-aware apps with Geotriggers in ArcGIS Maps SDK for Flutter","og_description":"Build smarter, location-aware apps with Geotriggers using the ArcGIS Maps SDK for Flutter. Add spatial awareness with ease and precision.","og_url":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter","og_site_name":"ArcGIS Blog","article_publisher":"https:\/\/www.facebook.com\/esrigis\/","twitter_card":"summary_large_image","twitter_site":"@ESRI","twitter_misc":{"Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter#article","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter"},"author":{"name":"Martino Yovo","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/6a6793a4e379c3efd9a8ca8650a626e6"},"headline":"Build smarter location-aware apps with Geotriggers in ArcGIS Maps SDK for Flutter","datePublished":"2025-06-10T14:30:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter"},"wordCount":12,"publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"keywords":["flutter","Flutter Maps SDK","GeoTriggers","Location intelligence","mobile development"],"articleSection":["Developers"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter","url":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter","name":"Build location-aware apps with Geotriggers in the Flutter Maps SDK","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#website"},"datePublished":"2025-06-10T14:30:14+00:00","description":"Build smarter, location-aware apps with Geotriggers using the ArcGIS Maps SDK for Flutter. Add spatial awareness with ease and precision.","breadcrumb":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/sdk-flutter\/developers\/build-smarter-location-aware-apps-with-geotriggers-in-arcgis-maps-sdk-for-flutter#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.esri.com\/arcgis-blog\/"},{"@type":"ListItem","position":2,"name":"Build smarter location-aware apps with Geotriggers in ArcGIS Maps SDK for Flutter"}]},{"@type":"WebSite","@id":"https:\/\/www.esri.com\/arcgis-blog\/#website","url":"https:\/\/www.esri.com\/arcgis-blog\/","name":"ArcGIS Blog","description":"Get insider info from Esri product teams","publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization","name":"Esri","url":"https:\/\/www.esri.com\/arcgis-blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","width":400,"height":400,"caption":"Esri"},"image":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/esrigis\/","https:\/\/x.com\/ESRI","https:\/\/www.linkedin.com\/company\/5311\/"]},{"@type":"Person","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/6a6793a4e379c3efd9a8ca8650a626e6","name":"Martino Yovo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/11\/56723384-213x200.png","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/11\/56723384-213x200.png","caption":"Martino Yovo"},"description":"Martino is a Product Engineer at Esri, a Google Developer Expert and a Developer Experience Engineer. He builds tools and SDKs that make technology more accessible and has supported thousands of developers through training, mentorship, and open-source contributions. Martino is passionate about helping engineers turn ideas into impactful products.","sameAs":["https:\/\/martinoyovo.com","https:\/\/facebook.com\/yovo.martino","https:\/\/instagram.com\/martinoyovo","https:\/\/linkedin.com\/in\/martino-yovo","https:\/\/x.com\/https:\/\/x.com\/martinoyovo","https:\/\/www.youtube.com\/@martinoyovo"],"gender":"male","award":["Google Developer Expert"],"knowsAbout":["Program Management","Community Building and leading","Youth Employment","Youth Skilling","Flutter","Software Development"],"knowsLanguage":["English","French","Ewe"],"jobTitle":"Product Engineer","worksFor":"Esri","url":"https:\/\/www.esri.com\/arcgis-blog\/author\/kyovo"}]}},"text_date":"June 10, 2025","author_name":"Martino Yovo","author_page":"https:\/\/www.esri.com\/arcgis-blog\/author\/kyovo","custom_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2025\/08\/Newsroom-Keyart-Wide-1920-x-1080.jpg","primary_product":"ArcGIS Maps SDK for Flutter","tag_data":[{"term_id":773372,"name":"flutter","slug":"flutter","term_group":0,"term_taxonomy_id":773372,"taxonomy":"post_tag","description":"","parent":0,"count":6,"filter":"raw"},{"term_id":776092,"name":"Flutter Maps SDK","slug":"flutter-maps-sdk","term_group":0,"term_taxonomy_id":776092,"taxonomy":"post_tag","description":"","parent":0,"count":5,"filter":"raw"},{"term_id":765552,"name":"GeoTriggers","slug":"geotriggers","term_group":0,"term_taxonomy_id":765552,"taxonomy":"post_tag","description":"","parent":0,"count":4,"filter":"raw"},{"term_id":221062,"name":"Location intelligence","slug":"location-intelligence","term_group":0,"term_taxonomy_id":221062,"taxonomy":"post_tag","description":"","parent":0,"count":12,"filter":"raw"},{"term_id":35001,"name":"mobile development","slug":"mobile-development","term_group":0,"term_taxonomy_id":35001,"taxonomy":"post_tag","description":"","parent":0,"count":8,"filter":"raw"}],"category_data":[{"term_id":738191,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":738191,"taxonomy":"category","description":"","parent":0,"count":426,"filter":"raw"}],"product_data":[{"term_id":761642,"name":"ArcGIS Location Platform","slug":"platform","term_group":0,"term_taxonomy_id":761642,"taxonomy":"product","description":"","parent":36601,"count":215,"filter":"raw"},{"term_id":776202,"name":"ArcGIS Maps SDK for Flutter","slug":"sdk-flutter","term_group":0,"term_taxonomy_id":776202,"taxonomy":"product","description":"","parent":36601,"count":19,"filter":"raw"},{"term_id":36601,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":36601,"taxonomy":"product","description":"","parent":0,"count":765,"filter":"raw"}],"primary_product_link":"https:\/\/www.esri.com\/arcgis-blog\/?s=#&products=sdk-flutter","_links":{"self":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/2809082","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/users\/366402"}],"replies":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/comments?post=2809082"}],"version-history":[{"count":0,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/2809082\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/media?parent=2809082"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/categories?post=2809082"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/tags?post=2809082"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/industry?post=2809082"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/product?post=2809082"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}