CSE-4078 - Lecture - Week 8

CSE-4078 Mobile Application Development Lectures

Week 8 Presented by Rehan Sarwar

App of the Week

Duration: 3:25


Geo Location

In mobile application development, leveraging geolocation services is crucial for applications that provide context-aware functionality such as maps, ride-sharing, and location-based services.

Utilizing the GeoLocator Flutter Package:

  • The GeoLocator package is a widely-used Flutter library for accessing location services.

  • Dependency required: geolocator: ^10.1.0

  • Import Statement:

    import 'package:geolocator/geolocator.dart';  

Getting Current and Last Known Location


Current Location:To obtain the device's current location with high accuracy:

Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);  
  • This method can be used live during the app's runtime, such as when the user requests their location.


Last Known Location:To retrieve the last known location of the device, which might be less accurate but quicker to obtain:

Position position = await Geolocator.getLastKnownPosition();  
  • Useful in scenarios where immediate response is required, and precise location is not critical.

Adding Permissions to Android Manifest

For the application to access location services, necessary permissions must be added to the Android Manifest file.

  1. Navigate to: android > app > src > main > AndroidManifest.xml

  2. Add the following entries for permissions:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />  
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
    <uses-permission android:name="android.permission.INTERNET" />  
  3. Ensure that you handle permissions appropriately during runtime as users can change them.

Permission for Location Services

Checking Permission Before Use:

LocationPermission permission = await Geolocator.checkPermission();  
  • Always confirm that the necessary permissions are granted before attempting to access location services.

Requesting Permission:

LocationPermission permission = await Geolocator.requestPermission();  
  • This prompts the user to authorize location access if it has not already been granted.

Geo Location Must be Async

Asynchronous programming is key when accessing geolocation services. Here's an example of how to structure an asynchronous function to get the current location:

void getLocation() async {  
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);  
}  

Code to Get Current Location

void getcurrentPos() async {  
    LocationPermission permissions = await Geolocator.checkPermission();  
    if (permissions == LocationPermission.denied) {  
        permissions = await Geolocator.requestPermission();  
        if (permissions == LocationPermission.denied) {  
            print("Permission denied");  
            return;  
        }  
    }  
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);  
    print(position.latitude);  
    print(position.longitude);  
}  
  • In the function above, it first checks for the required permissions and requests them if not granted, then retrieves and prints the current latitude and longitude of the device.

Asynchronous Programming: Futures, Async, Await


Asynchronous operations allow Flutter applications to perform tasks like fetching location data without blocking the main execution thread.Example Function:

void example() async {  
    await ...;  
}  
  • The use of async and await allows for a cleaner handling of asynchronous code.

Future: Represents Latent Values

In Dart, a Future represents a potential value or error that may not yet be available. It has three states:

  • Uncompleted: Still waiting for a return from an async function.

  • Completed with a value: Successfully retrieved the information.

  • Completed with an error: An error occurred while processing.

Example of Asynchronous Programming:

Future<void> printOrderMessage() async {  
    print('Awaiting user order...');  
    var order = await fetchUserOrder();  
    print('Your order is: $order');  
}  
  • This illustrates how to wait for another Future (in this case, fetchUserOrder) to complete before proceeding.

Internal State for a StatefulWidget

In Flutter, State objects maintain information that may fluctuate throughout the widget lifecycle. Understanding states is critical to effective widget management:

  • Access state information synchronously during the widget’s lifecycle.

  • Different State Lifecycle Methods include:

    • initState(): Called when the widget is first inserted into the tree.

    • activate(): Invoked when the widget is reintegrated into the widget tree.

    • build(BuildContext context): Responsible for building the UI of the widget.

    • setState() method call: Triggers a rebuild of the widget with new data.

    • deactivate(): Used during temporary removal from the tree.

    • dispose(): Cleans up resources for permanent removal.

APIs - Application Program Interface

APIs are crucial for integrating external services into applications, allowing developers to utilize functionalities without building them from scratch:

  • APIs provide sets of routines, protocols, and tools for building software applications.

  • To utilize APIs, developers often need to sign up for keys that authorize access to services.

API Request and Response Flow

Here’s a brief overview of how API interaction generally flows within an application context:

  1. User checks the menu and places an order.

  2. The waiter relays the order to the kitchen.

  3. The kitchen prepares and delivers the order to the user.

Getting Weather API Key

To integrate weather data into your application:

  1. Create an account on a service such as OpenWeatherMap.

  2. Generate an API key for access.

  3. Confirm the account via email for activation.

Using HTTP Package

The HTTP package provides the tools to make network requests to RESTful APIs.

  • Dependency required: http: ^0.13.4

  • Import Statement:

    import 'package:http/http.dart' as http;  

Making a Network Request

Example Function for Fetching Weather Data:

Future<http.Response> fetchWeather() async {  
    return await http.get(Uri.parse('http://api.openweathermap.org/data/2.5/weather?q={city name}&appid={API_key}'));  
}  
  • The function performs a GET request to fetch the weather for a specified city using the provided API key.

Getting Response Code and Body

Once the response is received, you can retrieve the body and status code:

  • Response Body:

var body = response.body;  
  • Status Code:

var statusCode = response.statusCode;  

HTTP Response Codes:

  • Response Categories:

    • Informational (100–199)

    • Successful (200–299)

    • Redirection (300–399)

    • Client Errors (400–499)

    • Server Errors (500–599)

JSON (JavaScript Object Notation)


JSON is a lightweight data interchange format that is easy to read and write for humans and machines.Structure Example:

{  
  "TrackID": "AR921BFF",  
  "Type": "Coupe",  
  "Speed": 42.6,  
  "ReportedDT": "Tue Apr 23 16:45:44 PDT 2019",  
  "Geometry": {  
      "x": -90.401309,  
      "y": 39.247178  
  }  
}  

Parsing the JSON

To parse JSON data within your Dart application, use the dart:convert library.

  • Import Statement:

    import 'dart:convert';  
  • Parsing Example:

var longitude = jsonDecode(data)['coord']['lon'];  
  • Utilize jsonDecode to convert JSON strings into usable Dart objects.