0% found this document useful (0 votes)
3 views11 pages

Index

The document provides a guide on using Flutter Riverpod 2 with the Geolocator package to obtain current latitude and longitude. It outlines the use of FutureProvider for one-time location fetches and StreamProvider for continuous updates, along with necessary permission handling. Additionally, it includes example code for setting up providers, a UI page, and navigation using GoRouter after fetching location data.

Uploaded by

Ko Aung Thu Oo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views11 pages

Index

The document provides a guide on using Flutter Riverpod 2 with the Geolocator package to obtain current latitude and longitude. It outlines the use of FutureProvider for one-time location fetches and StreamProvider for continuous updates, along with necessary permission handling. Additionally, it includes example code for setting up providers, a UI page, and navigation using GoRouter after fetching location data.

Uploaded by

Ko Aung Thu Oo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

2025-05-07

In Flutter Riverpod 2, to get the current latitude and longitude, you typically
integrate with the geolocator or location package. Since these involve
asynchronous and possibly one-time or streaming values, the right type of
Riverpod provider depends on how you want to access location data:

✅ Common Options
1. For one-time fetch (e.g., current location once):
Use a FutureProvider.

dart
Copy
Edit
final currentLocationProvider = FutureProvider((ref) async {
// Ensure permissions are handled before this
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
});
2. For continuous updates (e.g., tracking location):
Use a StreamProvider.

dart
Copy
Edit
final locationStreamProvider = StreamProvider((ref) {
return Geolocator.getPositionStream(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.high,

1 / 11
2025-05-07

distanceFilter: 10,
),
);
});
💡 Don't forget:
You need to request permission before accessing the location:

dart
Copy
Edit
await Geolocator.requestPermission();
Or check and handle permission status properly.

👇 Example Widget
class LocationWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final locationAsync =
ref.watch(currentLocationProvider);

return locationAsync.when(
data: (position) => Text(
'Lat: ${position.latitude}, Lon:
${position.longitude}'),
loading: () => CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
);
}
}

2 / 11
2025-05-07

Let me know if you’re using location package instead of geolocator, or if you


want to cache the result or trigger it manually!

Simple example

Sure Andrew! Here's a complete working example of using Flutter + Riverpod 2 +


Geolocator to get the current latitude and longitude. This example includes
permission handling, provider setup, and a widget to display the location.

✅ Step-by-step:
1. Add dependencies in pubspec.yaml
yaml
Copy
Edit
dependencies:
flutter:
sdk: flutter
flutter_riverpod: ^2.4.0
geolocator: ^10.1.0
2. Main Dart File (main.dart)
dart
Copy
Edit
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:geolocator/geolocator.dart';

3 / 11
2025-05-07

void main() {
runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {


const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Location with Riverpod',
theme: ThemeData(primarySwatch: Colors.blue),
home: const LocationPage(),
);
}
}
3. Providers (location_provider.dart)

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:geolocator/geolocator.dart';

final locationPermissionProvider = FutureProvider<bool>


((ref) async {
LocationPermission permission = await
Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
}
return permission == LocationPermission.always ||
permission == LocationPermission.whileInUse;

4 / 11
2025-05-07

});

final currentLocationProvider = FutureProvider<Position>


((ref) async {
final hasPermission = await
ref.watch(locationPermissionProvider.future);
if (!hasPermission) {
throw Exception('Location permission denied');
}
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
});

4. UI Page (location_page.dart)
dart
Copy
Edit
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'location_provider.dart';

class LocationPage extends ConsumerWidget {


const LocationPage({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final locationAsync = ref.watch(currentLocationProvider);

5 / 11
2025-05-07

return Scaffold(
appBar: AppBar(title: const Text('Your Location')),
body: Center(
child: locationAsync.when(
data: (position) => Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Latitude: ${position.latitude}'),
Text('Longitude: ${position.longitude}'),
],
),
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
),
),
);

}
}
🔐 Android Permissions (AndroidManifest.xml)
Add inside the tag:

xml
Copy
Edit

6 / 11
2025-05-07

✅ Summary:
FutureProvider handles the async location request.

locationPermissionProvider checks and requests permission.

UI reacts with .when(...) to display location or loading/error states.

Let me know if you want this to also support live updates using StreamProvider,
or want to use location package instead!

You said:
in location_page.dart want to redirect another route when read lat, long using go
router

2/2

ChatGPT said:
Perfect! You can redirect to another route using GoRouter after the latitude and
longitude are successfully fetched.

Let me show you the updated location_page.dart using go_router and


WidgetsBinding.instance.addPostFrameCallback() to trigger navigation once when
the location is available.

✅ Updated: location_page.dart with navigation


dart
Copy
Edit
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

7 / 11
2025-05-07

import 'package:go_router/go_router.dart';
import 'location_provider.dart';

class LocationPage extends ConsumerWidget {


const LocationPage({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final locationAsync = ref.watch(currentLocationProvider);

ref.listen(currentLocationProvider, (previous, next) {


next.whenData((position) {
// Navigate after frame is rendered to avoid build
context issues
WidgetsBinding.instance.addPostFrameCallback((_) {
context.go('/result?
lat=${position.latitude}&lng=${position.longitude}');
});
});
});

return Scaffold(
appBar: AppBar(title: const Text('Getting Location...')),
body: Center(
child: locationAsync.when(
data: (_) => const CircularProgressIndicator(), //
Redirect will happen soon
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
),

8 / 11
2025-05-07

),
);

}
}
🗺 Example GoRouter Setup (main.dart or router.dart)
dart
Copy
Edit
final _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const LocationPage(),
),
GoRoute(
path: '/result',
builder: (context, state) {
final lat = state.uri.queryParameters['lat'];
final lng = state.uri.queryParameters['lng'];
return ResultPage(latitude: lat!, longitude: lng!);
},
),
],
);
🧭 Example Result Page (result_page.dart)
dart

9 / 11
2025-05-07

Copy
Edit
import 'package:flutter/material.dart';

class ResultPage extends StatelessWidget {


final String latitude;
final String longitude;

const ResultPage({
super.key,
required this.latitude,
required this.longitude,
});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Location Result')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Latitude: $latitude'),
Text('Longitude: $longitude'),
],
),
),
);
}

10 / 11
2025-05-07

}
Let me know if you want to pass the values using extra or state object instead of
query parameters!

11 / 11

You might also like