Aplicacions amb Flutter, Dart i Flame

Tutorial Flutter Flame Projectes   Recursos CITCEA
Exemples Dart Dades pràctiques     Inici

Llegim les coordenades GPS

Ara anem a mostrar la geolocalització. De moment, farem unes modificacions senzilles al programa que teníem per tal de gestionar els permisos d'ús del GPS i mostrar les coordenades obtingudes a la pantalla. Més endavant ja millorarem el programa, per deixar-lo més acabat.

Amb la biblioteca geolocator podem saber el lloc on es troba l'usuari. A més, disposem de l'opció de calcular la distància entre dues posicions. Per emprar aquesta biblioteca, cal anar al fitxer pubspec.yaml per dir-li que la volem fer servir. Ho hem de posar a dependencies, indicant quina és la versió que volem, que normalment ja ens surt de manera automàtica. Quan vam escriure aquest text era la 14.0.2.

dependencies:
  flutter:
    sdk: flutter
  geolocator: ^14.0.2

Un cop afegit, cal picar al botó per baixar el paquet (baixar). En el programa, cal importar el paquet shared_preferences.dart.

import 'package:shared_preferences/geolocator.dart';

A més, cal donar permís de geolocalització. Això ho farem anar al fitxer AndroidManifest.xml que es troba a la carpeta main de la carpeta src de la carpeta app de la carpeta android i afegir les línies del permís després de la de manifest i abans de la d'application:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <application
...

Atenció: Cal tenir en compte que l'absència d'aquest permís pot donar problemes a l'executar l'aplicació en el dispositiu, malgrat aquesta funcioni correctament en el simulador.

A la pantalla principal, necessitarem una funció per comprovar els permisos. Aquesta funció l'executarem a l'iniciar la pantalla principal. De moment, el resultat de la comprovació el guardarem a una variable, per mostrar-lo a la pantalla.

...
class _PantPrincipalState extends State<PantPrincipal> {
  String _textPosicio = 'Posició desconeguda';
  String _textPermis = 'Permisos no verificats.';
  Future<String>? _rebut;
  CridaWeb cridaWeb = CridaWeb();

  @override
  void initState() {
    super.initState();
    comprovaPermisos();
  }

  Future<void> comprovaPermisos() async {
    LocationPermission permis = await Geolocator.checkPermission();

    if (permis == LocationPermission.denied) {
      setState(() {
        _textPermis = 'Permís desactivat. Demanant permís...';
      });
      permis = await Geolocator.requestPermission();
    }
    setState(() {
      if (permis == LocationPermission.whileInUse || permis == LocationPermission.always) {
        _textPermis = 'Permís activat.';
      } else {
        _textPermis = 'Permís denegat permanentment.';
      }
    });
  }
...

També tindrem una funció per llegir la posició.

...
  Future<void> llegeixPosicio() async {
    try {
      final LocationSettings configPosicio = LocationSettings(
        accuracy: LocationAccuracy.high,
        distanceFilter: 100,
      );
      Position posicio = await Geolocator.getCurrentPosition(locationSettings: configPosicio);
      setState(() {
        _textPosicio = 'Latitud: ${posicio.latitude}, Longitud: ${posicio.longitude}';
      });
    } catch (e) {
      setState(() {
        _textPosicio = 'Error: $e';
      });
    }
  }
...

El programa de la pantalla principal quedarà així:

pant_principal.dart
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:telegram/data/crida_web.dart';
class PantPrincipal extends StatefulWidget {
  const PantPrincipal({super.key});

  @override
  State<PantPrincipal> createState() => _PantPrincipalState();
}

class _PantPrincipalState extends State<PantPrincipal> {
  String _textPosicio = 'Posició desconeguda';
  String _textPermis = 'Permisos no verificats.';
  Future<String>? _rebut;
  CridaWeb cridaWeb = CridaWeb();

  @override
  void initState() {
    super.initState();
    comprovaPermisos();
  }

  Future<void> comprovaPermisos() async {
    LocationPermission permis = await Geolocator.checkPermission();

    if (permis == LocationPermission.denied) {
      setState(() {
        _textPermis = 'Permís desactivat. Demanant permís...';
      });
      permis = await Geolocator.requestPermission();
    }
    setState(() {
      if (permis == LocationPermission.whileInUse || permis == LocationPermission.always) {
        _textPermis = 'Permís activat.';
      } else {
        _textPermis = 'Permís denegat permanentment.';
      }
    });
  }

  Future<void> llegeixPosicio() async {
    try {
      final LocationSettings configPosicio = LocationSettings(
        accuracy: LocationAccuracy.high,
        distanceFilter: 100,
      );
      Position posicio = await Geolocator.getCurrentPosition(locationSettings: configPosicio);
      setState(() {
        _textPosicio = 'Latitud: ${posicio.latitude}, Longitud: ${posicio.longitude}';
      });
    } catch (e) {
      setState(() {
        _textPosicio = 'Error: $e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    String txtEnv = "";
    return Scaffold(
      appBar: AppBar(title: Text("Enviar missatge"),),
      body: Column(
        children: [
          Text(_textPermis),
          SizedBox(height: 20),
          Text(_textPosicio),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: llegeixPosicio,
            child: Text('GPS'),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              maxLines: 2,
              decoration: InputDecoration(
                hintText: "Escriu el que vols enviar",
                border: OutlineInputBorder(),
              ),
              onChanged: (txt){
                txtEnv = txt;
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextButton(
              onPressed: () {
                setState(() {
                  _rebut = cridaWeb.enviaDades(txtEnv);
                });
              },
              child: Text("Envia text"),
            ),
          ),
          FutureBuilder(future: _rebut, builder: (context, snapshot){
            if(snapshot.connectionState == ConnectionState.waiting){
              return CircularProgressIndicator();
            } else if(snapshot.hasError){
              return Text("Error: ${snapshot.error}");
            } else if(snapshot.hasData){
              return escriuResultats(snapshot.data);
            } else {
              return Text("");
            }
          })
        ],
      ),
    );
  }
}

Widget escriuResultats(String? dades){
  if(dades != null){
    return Text(dades.toString());
  }
  return Text("Alguna cosa ha fallat");
}

 

 

 

 

 

 

 

 

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.