Question #19MediumThird-Party Libraries

Usage of 3 party libraries location , intl , upload file , download file

#geolocator#intl#dio#location#internationalization#file-upload#file-download#third-party-packages

Answer

Overview

Flutter has a rich ecosystem of third-party packages that extend functionality for common tasks. This guide covers four essential package categories: location services, internationalization, file uploads, and file downloads.

Package Comparison

PackagePurposeLatest Version (2026)Popularity
geolocatorLocation services & GPS12.x15K+ likes
intlInternationalization & formatting0.19.x20K+ likes
dioFile upload/download with progress5.4.018K+ likes
httpSimple HTTP requests1.x17K+ likes

1. Location Services (Geolocator)

Installation

yaml
dependencies:
  geolocator: ^12.0.0

Getting Current Location

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

Future<Position> getCurrentLocation() async {
  // Check permissions
  LocationPermission permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
  }

  // Get current position
  Position position = await Geolocator.getCurrentPosition(
    desiredAccuracy: LocationAccuracy.high,
  );

  return position;
}

// Usage
void main() async {
  Position position = await getCurrentLocation();
  print('Lat: ${position.latitude}, Long: ${position.longitude}');
}

Real-Time Location Tracking

dart
StreamSubscription<Position>? positionStream;

void startLocationTracking() {
  LocationSettings locationSettings = LocationSettings(
    accuracy: LocationAccuracy.high,
    distanceFilter: 10, // Update every 10 meters
  );

  positionStream = Geolocator.getPositionStream(
    locationSettings: locationSettings,
  ).listen((Position position) {
    print('Updated: ${position.latitude}, ${position.longitude}');
  });
}

void stopLocationTracking() {
  positionStream?.cancel();
}

Distance Calculation

dart
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
  return Geolocator.distanceBetween(lat1, lon1, lat2, lon2);
}

// Distance in meters
double distance = calculateDistance(37.7749, -122.4194, 34.0522, -118.2437);
print('Distance: ${(distance / 1000).toStringAsFixed(2)} km');

2. Internationalization (intl)

Installation

yaml
dependencies:
  flutter_localizations:
    sdk: flutter
  intl: ^0.19.0

Date & Number Formatting

dart
import 'package:intl/intl.dart';

// Date formatting
String formatDate() {
  DateTime now = DateTime.now();
  
  // US format
  String usDate = DateFormat.yMMMd('en_US').format(now);
  // Output: Jan 15, 2026
  
  // French format
  String frDate = DateFormat.yMMMd('fr_FR').format(now);
  // Output: 15 janv. 2026
  
  return usDate;
}

// Number formatting
String formatNumber() {
  double amount = 1234567.89;
  
  // Currency
  String currency = NumberFormat.currency(
    locale: 'en_US',
    symbol: '\$',
  ).format(amount);
  // Output: $1,234,567.89
  
  // Compact
  String compact = NumberFormat.compact().format(amount);
  // Output: 1.2M
  
  return currency;
}

Message Localization

dart
import 'package:intl/intl.dart';

class AppLocalizations {
  static String welcome(String name) {
    return Intl.message(
      'Welcome, $name!',
      name: 'welcome',
      args: [name],
    );
  }
  
  static String itemCount(int count) {
    return Intl.plural(
      count,
      zero: 'No items',
      one: '1 item',
      other: '$count items',
      name: 'itemCount',
      args: [count],
    );
  }
}

3. File Upload (Dio)

Installation

yaml
dependencies:
  dio: ^5.4.0
  image_picker: ^1.0.0  # For selecting files

Single File Upload

dart
import 'package:dio/dio.dart';
import 'package:image_picker/image_picker.dart';

Future<void> uploadFile() async {
  final dio = Dio();
  
  // Pick image
  final ImagePicker picker = ImagePicker();
  final XFile? image = await picker.pickImage(source: ImageSource.gallery);
  
  if (image != null) {
    // Create FormData
    FormData formData = FormData.fromMap({
      'file': await MultipartFile.fromFile(
        image.path,
        filename: 'upload.jpg',
      ),
      'user_id': '12345',
    });
    
    // Upload with progress tracking
    Response response = await dio.post(
      'https://api.example.com/upload
      data: formData,
      onSendProgress: (sent, total) {
        double progress = (sent / total) * 100;
        print('Upload progress: ${progress.toStringAsFixed(0)}%');
      },
    );
    
    print('Upload successful: ${response.data}');
  }
}

Multiple File Upload

dart
Future<void> uploadMultipleFiles(List<String> filePaths) async {
  final dio = Dio();
  
  List<MultipartFile> files = [];
  for (String path in filePaths) {
    files.add(await MultipartFile.fromFile(path));
  }
  
  FormData formData = FormData.fromMap({
    'files': files,
  });
  
  await dio.post(
    'https://api.example.com/upload-multiple
    data: formData,
  );
}

4. File Download (Dio)

Simple File Download

dart
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';

Future<void> downloadFile(String url, String fileName) async {
  final dio = Dio();
  
  // Get app directory
  final dir = await getApplicationDocumentsDirectory();
  final savePath = '${dir.path}/$fileName';
  
  // Download with progress
  await dio.download(
    url,
    savePath,
    onReceiveProgress: (received, total) {
      if (total != -1) {
        double progress = (received / total) * 100;
        print('Download progress: ${progress.toStringAsFixed(0)}%');
      }
    },
  );
  
  print('File downloaded to: $savePath');
}

// Usage
void main() async {
  await downloadFile(
    'https://example.com/sample.pdf
    'document.pdf',
  );
}

Download with Cancellation

dart
class FileDownloader {
  CancelToken? cancelToken;
  
  Future<void> downloadWithCancel(String url, String savePath) async {
    final dio = Dio();
    cancelToken = CancelToken();
    
    try {
      await dio.download(
        url,
        savePath,
        cancelToken: cancelToken,
        onReceiveProgress: (received, total) {
          print('Progress: ${(received / total * 100).toStringAsFixed(0)}%');
        },
      );
    } on DioException catch (e) {
      if (CancelToken.isCancel(e)) {
        print('Download cancelled');
      } else {
        print('Download error: ${e.message}');
      }
    }
  }
  
  void cancelDownload() {
    cancelToken?.cancel('User cancelled download');
  }
}

Platform Configuration

Android (AndroidManifest.xml)

xml
<!-- Location permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<!-- Internet permission for uploads/downloads -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

iOS (Info.plist)

xml
<!-- Location permissions -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>App needs location access for maps</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>App needs background location</string>

Best Practices

Location Services:

  • Always check and request permissions before accessing location
  • Use appropriate accuracy levels to save battery
  • Cancel location streams when not needed
  • Handle permission denied scenarios gracefully

Internationalization:

  • Support at least 2-3 major languages for global apps
  • Test with different locales and RTL languages
  • Use
    text
    intl
    for all date/number formatting (never hardcode formats)
  • Extract all user-facing strings for translation

File Uploads/Downloads:

  • Show progress indicators for better UX
  • Implement retry logic for failed uploads/downloads
  • Validate file size and type before uploading
  • Handle network errors gracefully
  • Use cancellation tokens for long operations
  • Compress images before uploading to save bandwidth

Learning Resources

Performance Tip: Use Dio instead of the basic HTTP package for file operations, as it provides better performance, progress tracking, and advanced features like interceptors and request cancellation.