Skip to content

Navigating Libraries, APIs, and Remote Content – Day 9 Android 14 Masterclass

Navigating Libraries, APIs, and Remote Content - Day 9 Android 14 Masterclass
Become a developer with our complete learning paths
Become a developer with our complete learning paths

Navigating Libraries, APIs, and Remote Content – Day 9 Android 14 Masterclass

Welcome to Day 9 of the Android 14 & Kotlin Masterclass. Today, we’ll explore JSON, the backbone of data interchange, and understand the pivotal role of APIs in software communication. Our journey will cover Gradle scripts, essential for building Android apps, and the use of dependencies to enhance app functionality. We’ll also look at Retrofit and Coroutines, transformative in handling network operations and asynchronous tasks in Kotlin. Join us as we navigate these critical components, enhancing our development skills.

 

1. JSON (JavaScript Object Notation) for Android Development

Theory

JSON stands for JavaScript Object Notation. It is a lightweight data interchange format that is easy for humans to read and write and easy for machines to parse and generate.

JSON is a text format that is completely language-independent but uses conventions that are familiar to programmers of the C family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others.

Syntax

JSON is built on two structures:

  • A collection of name/value pairs: In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values: In most languages, this is realized as an array, vector, list, or sequence.

Here are the basic structures in JSON:

  • Objects: An object is an unordered set of name/value pairs, enclosed by curly braces {}. An object can contain other objects, arrays, and basic data types.
  • Arrays: An array is an ordered collection of values, enclosed by square brackets []. Arrays can contain objects, other arrays, and basic data types.
  • Values: A value can be a string, number, boolean, null, object, or array.

Here are some examples to illustrate the syntax of JSON:

Example 1: Simple JSON Object

{
    "name": "John Doe",
    "age": 30,
    "is_student": false
}

Example 2: Nested JSON Object

{
    "person": {
        "name": "John Doe",
        "address": {
            "street": "123 Main St",
            "city": "Anytown",
            "zipcode": "12345"
        }
    }
}

Free JSON APIs

Theory

Free JSON APIs provide a way for developers to access various types of data in a structured JSON format over the internet.

These APIs, or Application Programming Interfaces, allow developers to interact with external services and retrieve or send data programmatically.

Free JSON APIs are publicly available and do not require payment, making them ideal for practice, testing, and small projects.

Syntax

To access a free JSON API, you typically make HTTP requests (GET, POST, PUT, DELETE) to a specific endpoint URL.

 

2. Understanding API (Application Programming Interface)

Theory:

An API is a set of rules and definitions that allows software applications to communicate with each other. It defines the methods and data formats that applications can use to request and exchange information.

APIs play a crucial role in enabling the functionality that users have come to expect from modern software, allowing different systems to interact with each other in a seamless manner.

APIs can be found in various types, such as:

  • Web APIs: These are accessible over the internet using HTTP/HTTPS protocols. They allow applications to interact with external services and data sources, and are commonly used in web development to integrate third-party services.
  • Library or Framework APIs: These are sets of routines, protocols, and tools for building software and applications. A library API simplifies complex actions, making it easier to develop software.
  • Operating System APIs: These APIs allow applications to interact with the operating system, enabling functionalities like reading files, interacting with hardware devices, and more.

Components

An API typically consists of the following components:

  • Endpoints: Specific paths or URLs where API requests can be made.
  • Methods: HTTP methods such as GET, POST, PUT, DELETE, which define the type of operation to perform.
  • Requests: The actual call to the API, consisting of the endpoint, method, headers, and any data sent to the API.
  • Responses: The data returned by the API, usually in a format like JSON or XML, along with status codes indicating the success or failure of the request.

Example: Android Development

Here’s a simple example of a web API request:

  1. Endpoint: https://api.example.com/users
  2. Method: GET
  3. Request: A call is made to https://api.example.com/users to retrieve a list of users.
  4. Response: The API returns a JSON containing the list of users and a status code.
[
    {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
    },
    {
        "id": 2,
        "name": "Jane Smith",
        "email": "jane@example.com"
    }
]

API Key

An API key is a code passed in by computer programs calling an API (for reading or writing data) to identify the calling program, its developer, or its user to the website.

They’re often used to control access.

Purpose of an API Key

  1. Authentication: An API key is a simple encrypted string that identifies an application or user. It is often used as a way to ensure that the entity making the API request is authorized to access or modify the data being requested.
  2. Authorization: API keys can also be used to control access to specific endpoints or data. For example, an API key might grant access to some endpoints or services but not others.
  3. Rate Limiting: API keys allow the API provider to monitor the usage of their API, limiting the number of requests that can be made in a specific time period. This is a way to prevent abuse, manage load on the API servers, and ensure fair usage.
  4. Tracking and Analytics: API keys allow the API provider to track the usage of their API, gathering data on how, when, and by whom the API is being consumed. This can be useful for analytics, auditing, and improving the API.

Key Points to Remember:

  • In essence, an API acts as a bridge that allows different software applications to talk to each other, enabling the sharing of functionality and data in a secure and efficient manner.
  • APIs are fundamental to modern software development, enabling the creation of rich, integrated, and versatile applications.
  • An API key is a powerful tool for accessing and manipulating data via APIs, but it must be managed carefully to prevent unauthorized access and ensure the security of the data being accessed or modified.

 

3. Gradle Scripts in Android 14 Studio

Gradle scripts are essential files that manage the build process of an Android application.

Here’s a brief overview:

  1. Project-level build.gradle (Top-level): Located at the root of your project, this file defines configurations common across all modules, such as repositories and classpath dependencies.
  2. Module-level build.gradle (App-level): Located in each module, this file specifies module-specific configurations like application ID, SDK versions, and dependencies.
  3. Gradle Properties: These are configurations that apply globally across tasks and projects, like memory settings.
  4. Gradle Tasks: Tasks are actions that Gradle executes during the build process, such as compiling and packaging the application.

In essence, Gradle scripts configure, customize, and automate the steps in compiling, building, and packaging your Android application in Android Studio.

 

4. Dependencies in Android 14 Studio

Dependencies refer to external libraries or modules that your Android project relies on to function correctly.

These dependencies can provide various functionalities, such as network operations, image loading, data persistence, and more, allowing you to build feature-rich applications without reinventing the wheel.

Here’s a focused explanation:

1. Library Dependencies

  • Kotlin and Android Libraries: Pre-built libraries specifically designed to be used with Kotlin and Android, such as Kotlin Coroutines for asynchronous programming or Retrofit for network operations.
  • Example: Adding Retrofit as a dependency in your Android project to handle HTTP requests and responses.

2. SDK Dependencies

  • Android Support Libraries: Libraries like AndroidX or Jetpack components, which offer backward-compatible versions of new Android features and other helpful utilities.
  • Example: Using AndroidX RecyclerView to display lists of items in your application.

3. Remote Dependencies

  • Maven and JCenter: Dependencies hosted on remote repositories. Gradle handles the downloading and integration of these libraries automatically.
  • Example: Adding a remote dependency from Maven Central in your build.gradle file.

How to Add Dependencies in Kotlin Android Projects

In Kotlin Android projects, dependencies are added in the build.gradle.kts (Kotlin DSL) or build.gradle (Groovy DSL) file of the app module. Here’s how you might add a dependency using Groovy DSL:

dependencies {
    // Kotlin standard library
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    
    // Retrofit for network operations
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    
    // AndroidX RecyclerView
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
}

Key Points to Remember:

  • In Kotlin and Android development, dependencies are external, reusable code libraries or modules that you integrate into your project to utilize pre-built functionalities, saving development time and effort.
  • They are essential for leveraging existing, well-tested code to enhance the features and reliability of your Android applications.

 

5. Retrofit: Android Development

Retrofit is a type-safe HTTP client for Android and Java, and it is highly used in Kotlin-based Android applications.

Developed by Square, Retrofit simplifies the process of consuming JSON or XML data which is transformed into Kotlin or Java objects in your application.

Here’s a detailed explanation in the context of Kotlin and Android development:

1. Functionality

  • HTTP Requests: Retrofit simplifies the process of making HTTP requests to REST APIs, handling various aspects like URL construction, session handling, and error processing.
  • Data Conversion: Retrofit can automatically convert the JSON or XML responses from the APIs into Kotlin objects, making the data easy to use in your application.

2. Annotations

  • Retrofit uses annotations to define API endpoints and HTTP methods (GET, POST, PUT, DELETE, etc.), making the code more readable and concise.

3. Integration with Coroutines

  • Retrofit has seamless integration with Kotlin Coroutines, which allows for easy implementation of asynchronous API requests and responses.

4. Customization

  • Retrofit allows for extensive customization, such as adding headers, authentication, or custom converters, to tailor the HTTP client according to the needs of the application.

Example in Kotlin Android Project

Here’s a simple example of how Retrofit might be used in a Kotlin Android application:

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET

// Define the API endpoints
interface ApiService {
    @GET("users/1")
    suspend fun getUser(): User
}

// Create a Retrofit instance
val retrofit = Retrofit.Builder()
    .baseUrl("<https://jsonplaceholder.typicode.com/>")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

// Create an API service instance
val apiService = retrofit.create(ApiService::class.java)

// Make an API request
val user = apiService.getUser()

In this example, a Retrofit instance is created, specifying the base URL of the API and a converter factory to handle the conversion of JSON responses into Kotlin objects.

An interface (ApiService) defines the API endpoints, and a request is made to fetch a user.

Key Points to Remember:

  • Retrofit is a powerful and efficient library that simplifies network operations in Kotlin and Android development, making it easier to consume REST APIs, handle HTTP requests and responses, and work with retrieved data in a type-safe manner.
  • It is widely adopted due to its ease of use, flexibility, and compatibility with modern Android and Kotlin programming paradigms like Coroutines.

 

6. Coroutines in Android Development

Coroutines are a powerful feature in Kotlin that makes asynchronous programming more manageable and concise.

They help in simplifying the code that deals with operations like network calls, database transactions, and other tasks that can be performed asynchronously.

Theory

Coroutines facilitate writing asynchronous code in a sequential manner, making it more readable and understandable.

They allow you to write non-blocking code, meaning that the execution can be paused and resumed, allowing other tasks to run in the meantime.

This is particularly useful in UI applications like Android, where you don’t want to block the main thread to keep the UI responsive.

Syntax and Components: Android Development

  1. Suspend Keyword
  • Suspend Functions: Functions marked with the suspend keyword are the building blocks of coroutines. They can be paused and resumed, allowing for non-blocking asynchronous execution.
  • Usage: Suspend functions can be invoked from other suspend functions or within a coroutine scope.
  1. Coroutine Builders
  • launch: Starts a new coroutine without blocking the current thread and returns a reference to the coroutine as a Job.
  • async: Starts a new coroutine and returns a Deferred, which is a non-blocking cancellable future that represents the result.
  1. Coroutine Scopes
  • Scopes control the lifetime of coroutines. For example, in Android, you might use a scope tied to the application’s lifecycle.

Code Examples: Android 14 Studio

Example 1: Using a Suspend Function

suspend fun fetchData() {
    // Simulate a network call or any asynchronous operation
    delay(1000)
    println("Data fetched successfully")
}

// Calling the suspend function within a coroutine scope
GlobalScope.launch {
    fetchData()
}

Explanation:

  • suspend fun fetchData() {...}: This is a suspend function. It can do long-running operations like network requests without blocking the main thread. The suspend keyword indicates that the function can be paused and resumed.
  • delay(1000): This line simulates a delay, representing a long-running task like fetching data from the internet. It delays the coroutine for 1000 milliseconds (1 second), without blocking the main thread.
  • GlobalScope.launch {...}: This line launches a new coroutine. A coroutine is like a lightweight thread that can run asynchronous code.
  • fetchData(): Inside the coroutine, we call our suspend function. It will execute without blocking the main thread, meaning the application remains responsive.

Example 2: Using the Suspend Keyword with a Return Value

suspend fun fetchData(): String {
    delay(1000)
    return "Data fetched successfully"
}

GlobalScope.launch {
    val result = fetchData()
    println(result)
}

Explanation:

  • suspend fun fetchData(): String {...}: This suspend function is similar to the previous one, but it returns a string.
  • return "Data fetched successfully": After the delay, this function returns a message as a string.
  • val result = fetchData(): Here, we call the suspend function inside a coroutine, and the returned message is stored in the variable result.
  • println(result): The message stored in result is printed to the console.

Example 3: Using Coroutine Builders in Android

// In an Android ViewModel or any lifecycle-aware component
viewModelScope.launch {
    val result = fetchData()
    // Update UI with the fetched data
}

Explanation:

  • viewModelScope.launch {...}: This line launches a coroutine within the scope of an Android ViewModel. It means the coroutine will be canceled when the ViewModel is cleared, preventing memory leaks.
  • val result = fetchData(): We call the suspend function inside the coroutine, and its result is stored in the variable result.
  • // Update UI with the fetched data: This comment indicates where you would update the UI of your Android app with the fetched data. Since it’s inside a coroutine launched in the ViewModel scope, it’s safe to update the UI here.

Key Points to Remember:

  • Coroutines in Kotlin offer a powerful way to handle asynchronous operations, making the code more readable and manageable.
  • The suspend keyword is central to coroutines, allowing functions to be paused and resumed, facilitating non-blocking asynchronous execution.
  • Using coroutines helps in keeping the UI responsive and managing background tasks efficiently in Android applications.

 

7. @GET and HTTP GET Request

@GET Annotation

@GET is an annotation used to specify that a particular function should make an HTTP GET request to a specified endpoint.

  • Purpose: The @GET annotation tells Retrofit that the following function is used to make an HTTP GET request.
  • Usage: It is used above a function in an interface, and you usually pass the endpoint (the remaining part of the URL) as a parameter to the @GET annotation.

HTTP GET Request

  • Purpose: An HTTP GET request is used to retrieve data from a specified resource in a network such as a server.
  • Usage in Retrofit: When using Retrofit, you define an interface to declare endpoints and HTTP methods. Functions in this interface represent different API calls, and they are annotated with HTTP method annotations like @GET.

Code Example and Explanation

import retrofit2.http.GET

interface ApiService {
    @GET("users/1")
    suspend fun getUser(): User
}

Explanation:

  • interface ApiService {...}: This is an interface where we define our API endpoints. It’s like a contract that specifies what kind of network requests our app can make.
  • @GET("users/1"): This annotation indicates that the function getUser() should make an HTTP GET request to the endpoint "users/1". The "users/1" is appended to the base URL specified when creating the Retrofit instance.
  • suspend fun getUser(): User: This is a suspend function, meaning it can be paused and resumed. It is expected to return a User object. Retrofit takes care of executing this function in a background thread, making the network request, and retrieving the data.

Key Points to Remember:

  • In Kotlin and Android development, using Retrofit, the @GET annotation is a straightforward way to declare that a function should perform an HTTP GET request to retrieve data from a specific endpoint.
  • Coupled with suspend functions, it allows for easy and efficient network operations in a coroutine context, ensuring that the network operations don’t block the main thread, keeping the application responsive.

 

8. Let’s look closer into some of the code we used today: Android 14

Part 1: Setting up the Retrofit Builder

retrofit.Builder()
    .baseUrl("base url path")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

Explanation:

  • retrofit.Builder(): This initializes a new Retrofit builder. A builder is used to configure and create a Retrofit instance.
  • .baseUrl("base url path"): Here, you set the base URL for the API endpoints. All endpoint paths specified in your API interface will be appended to this base URL.
  • .addConverterFactory(GsonConverterFactory.create()): This line adds a converter factory to the builder. A converter factory is used to convert the JSON response from the API into Kotlin or Java objects. In this case, GsonConverterFactory is used, which utilizes the Gson library to handle the conversion.
  • .build(): Finally, this method call creates and returns a Retrofit instance configured with the settings you specified in the builder.

Part 2: Creating the API Service

retrofit.create(ApiService::class.java)

Explanation:

  • retrofit.create(ApiService::class.java): This line tells the Retrofit instance to create an implementation of the ApiService interface. The ApiService interface contains method definitions that represent different API endpoints, each annotated with the HTTP method and endpoint path.
  • ApiService::class.java: This part specifies the class type of the API service interface that Retrofit should create an implementation for.

In summary, the first part of the code configures and creates a Retrofit instance, setting the base URL and specifying how JSON responses should be converted to Kotlin objects.

The second part instructs Retrofit to create an implementation of an API service interface, which you can use to execute network requests based on the method definitions in the interface.

 

9. Try, Catch and Finally in Kotlin and Android Development

Theory

When you write code, sometimes things don’t go as planned, and errors or exceptions occur, like trying to access a file that doesn’t exist or dividing a number by zero.

try, catch, and finally are mechanisms to handle such exceptions gracefully, allowing the program to continue running or failing with a clear error message.

  • try Block: Here, you write the code that might cause an exception. It’s like saying, “Let’s TRY to execute this code.”
  • catch Block: If an exception occurs in the try block, the catch block catches it. You can handle the exception here, like displaying an error message. It’s like saying, “If something goes wrong in the try block, CATCH the error here.”
  • finally Block: This block executes regardless of whether an exception occurred. It’s often used for cleanup, like closing files or releasing resources. It’s like saying, “Do this FINALLY, no matter what.”

Syntax and Code Examples: Android Development

Example 1: Basic try-catch

try {
    val result = 10 / 0
    println(result)
} catch (e: ArithmeticException) {
    println("Cannot divide by zero")
}

Explanation:

  • The code tries to divide 10 by zero, which is not allowed, causing an ArithmeticException.
  • The catch block catches this exception, and instead of crashing, it prints “Cannot divide by zero.”

Example 2: try-catch-finally

try {
    val numbers = arrayOf(1, 2, 3)
    println(numbers[5])
} catch (e: ArrayIndexOutOfBoundsException) {
    println("Index is out of bounds")
} finally {
    println("This will execute regardless of an exception")
}

Explanation:

  • The code tries to access the fifth element of an array that only has three elements, causing an ArrayIndexOutOfBoundsException.
  • The catch block catches this exception and prints “Index is out of bounds.”
  • The finally block executes after everything else, printing “This will execute regardless of an exception.”

Example 3: Multiple catch Blocks

try {
    val input = "abc"
    val number = input.toInt()
} catch (e: NumberFormatException) {
    println("Input is not a number")
} catch (e: Exception) {
    println("An unknown error occurred")
}

Explanation:

  • The code tries to convert a string that is not a number into an integer, causing a NumberFormatException.
  • The first catch block catches this specific exception and prints “Input is not a number.”

try, catch, and finally are essential tools in Kotlin (and many other programming languages) to handle exceptions or errors gracefully, ensuring that your program doesn’t crash unexpectedly and can handle different error conditions elegantly.

 

10. Let’s discuss the CircularProgressIndicator

Theory: Android Development

CircularProgressIndicator is a visual component, or “widget,” that you can include in your Android app’s user interface.

It displays a spinning circle, often used to indicate that the app is busy doing something in the background, like loading data or processing a user request.

It tells the user, “Please wait, something is happening, and the app hasn’t frozen.”

Usage

You would typically show a CircularProgressIndicator when you want to indicate that a task is ongoing, and hide it once the task is completed. It helps improve the user experience by providing feedback on the app’s status and activities.

Syntax and Code Example

Here’s a simple example of how you might use CircularProgressIndicator in a Jetpack Compose function:

import androidx.compose.runtime.Composable
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Text

@Composable
fun LoadingScreen(isLoading: Boolean) {
    if (isLoading) {
        CircularProgressIndicator()
        Text("Loading, please wait...")
    } else {
        Text("Content loaded!")
    }
}

Explanation:

  • @Composable: This annotation indicates that the following function is a Composable function, meaning it defines a part of the UI in Jetpack Compose.
  • CircularProgressIndicator(): This line creates and displays the spinning circle. It will show up on the screen when the function is called with isLoading set to true.
  • if (isLoading) {...} else {...}: This part checks whether isLoading is true or false. If true, it displays the CircularProgressIndicator and a text message “Loading, please wait…”. If false, it displays a different text message, “Content loaded!”.

CircularProgressIndicator is a helpful visual tool in Android apps to indicate that something is happening in the background, reassuring users that the app is actively processing their request or loading content, and they should wait for the process to complete.

 

11. LazyVerticalGrid or LazyGridColumn: Android Development

Theory

LazyVerticalGrid is a component that allows you to display multiple items in a grid format vertically.

It’s “lazy” because it only renders the items that fit on the screen, and as you scroll, it reuses the item views, making it efficient and smooth.

It’s particularly useful when you want to display a collection of items, like images or products, in a grid layout.

Usage

You might use LazyVerticalGrid when you want to present a list of items in a more visually organized manner rather than a simple vertical list.

It allows for a more compact and visually appealing presentation, especially when displaying images or cards.

Syntax and Code Examples: Android Development

Example 1: Basic Usage of LazyVerticalGrid

import androidx.compose.foundation.lazy.LazyVerticalGrid
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.layout.GridCells

@Composable
fun SimpleGrid() {
    val items = List(100) { "Item $it" } // Creating a list of 100 items

    LazyVerticalGrid(
        cells = GridCells.Fixed(3), // Setting the number of columns
    ) {
        items(items) { item ->
            Text(item) // Displaying each item in the grid
        }
    }
}

Explanation:

  • LazyVerticalGrid: This is where the grid is created. It takes several parameters, including the number of columns and the content to display.
  • cells = GridCells.Fixed(3): This sets the number of columns in the grid. In this case, it creates a grid with 3 columns.
  • items(items): This function takes the list of items to display in the grid. It goes through each item in the list and applies the code inside the curly braces {}.
  • Text(item): This is where each item is displayed. In this case, it simply displays the text of each item.

Example 2: Displaying Images in a LazyVerticalGrid

@Composable
fun ImageGrid(images: List<Image>) {
    LazyVerticalGrid(
        cells = GridCells.Fixed(4), // Setting the number of columns
    ) {
        items(images) { image ->
            // Displaying each image in the grid
            Image(painter = image.painter, contentDescription = null) 
        }
    }
}

Explanation:

  • In this example, the grid is used to display images. Each cell in the grid will show an image from the list.
  • items(images): This function takes a list of images to display in the grid.
  • Image(painter = image.painter, contentDescription = null): This line displays an image in each cell of the grid.

Key Points to Remember:

  • LazyVerticalGrid in Jetpack Compose is a powerful and efficient way to display collections of items in a grid format, allowing for a more organized and visually appealing presentation.
  • It’s especially useful for displaying images, products, or any collection of similar items in your Android app.

 

12. Displaying Remote Images: Android 14 Studio

Displaying remote images means loading and showing images from the internet in your application. In the context of Android development using Kotlin and Jetpack Compose, there are specific components and functions to handle this task efficiently and gracefully.

Theory

Displaying a remote image involves fetching an image from a URL and displaying it within the app’s user interface.

Jetpack Compose provides the Image composable, along with utilities like rememberAsyncImagePainter, to manage the loading and displaying of remote images.

Components: Android Development

  • Image Composable: A component that displays images in the UI.
  • rememberAsyncImagePainter Function: A function that handles the asynchronous loading of an image from a URL or other sources. It manages the image loading lifecycle, such as loading, success, and error states.

Syntax and Code Examples

Example 1: Basic Usage of Displaying a Remote Image

import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import com.google.accompanist.imageloading.rememberAsyncImagePainter

@Composable
fun DisplayRemoteImage(imageUrl: String) {
    Image(
        painter = rememberAsyncImagePainter(imageUrl),
        contentDescription = null // Description for accessibility
    )
}

Explanation:

  • Image Composable: This is where the image will be displayed. It takes various parameters, including a painter that draws the image and a content description for accessibility.
  • painter = rememberAsyncImagePainter(imageUrl): This line is crucial. rememberAsyncImagePainter(imageUrl) manages the loading of the image from the provided URL (imageUrl). It handles the different states like loading, success, and error.

Example 2: Using a Placeholder Image

@Composable
fun DisplayRemoteImageWithPlaceholder(imageUrl: String) {
    val painter = rememberAsyncImagePainter(
        imageUrl,
        builder = {
            placeholder(painterResource(id = R.drawable.placeholder))
        }
    )

    Image(
        painter = painter,
        contentDescription = null // Description for accessibility
    )
}

Explanation:

  • placeholder(painterResource(id = R.drawable.placeholder)): This part specifies a placeholder image to be displayed while the remote image is loading. It uses a local drawable resource as the placeholder.

Key Points to Remember:

  • Displaying remote images in Jetpack Compose involves using the Image composable along with utilities like rememberAsyncImagePainter to manage the loading and displaying of images from URLs.
  • It allows for efficient and graceful handling of remote images, ensuring a smooth and responsive user experience.

 

13. Android Manifest and allowing your app to use Internet

What is the Android Manifest?

The Android Manifest (AndroidManifest.xml) is a special file in every Android app project. It contains essential information about the app, such as the app’s name, icon, and permissions it needs to work correctly.

What Does “Permission to Use the Internet” Mean?

When we talk about giving an app “permission to use the internet,” we mean allowing the app to connect to the internet to send or receive data. This could be for various purposes like fetching images, getting updates, or communicating with a database.

How to Give Your App Internet Permission

To give your app permission to access the internet, you need to add a specific line in the AndroidManifest.xml file.

Here’s a step-by-step guide:

Step 1: Locate the AndroidManifest.xml File

  • Open your Android project in an IDE like Android Studio.
  • Find the AndroidManifest.xml file. It is usually located in the app/src/main directory of your project.

Step 2: Add the Internet Permission

  • Open the AndroidManifest.xml file.
  • Add the following line within the <manifest> tags, but outside of the <application> tags:
<uses-permission android:name="android.permission.INTERNET" />

Example:

Here is how your AndroidManifest.xml file might look after adding the internet permission:

<manifest xmlns:android="<http://schemas.android.com/apk/res/android>"
    package="com.example.myapp">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!-- Other application settings and activities go here -->
    </application>

</manifest>

Adding internet permission to your Android app involves a simple modification to the AndroidManifest.xml file.

This permission is crucial for apps that need to communicate over the internet, ensuring they operate correctly and access the necessary resources or data.

 

Conclusion: Navigating Libraries, APIs, and Remote Content – Day 9 Android 14 Masterclass

Wrapping up Day 9 of our Android 14 & Kotlin Masterclass, we’ve covered a spectrum of topics fundamental to advanced Android development. From JSON and APIs to Retrofit, Coroutines, and effective UI implementation, we’ve gained valuable insights and practical skills. These learnings are pivotal for crafting sophisticated Android applications and navigating the complexities of modern app development with Kotlin. Let’s leverage this knowledge to create innovative and efficient applications.

 

If you want to skyrocket your Android career, check out our The Complete Android 14 & Kotlin Development Masterclass. Learn Android 14 App Development From Beginner to Advanced Developer.

Master Jetpack Compose to harness the cutting-edge of Android development, gain proficiency in XML — an essential skill for numerous development roles, and acquire practical expertise by constructing real-world applications.

 

Check out Day 7 of this course here.

Check out Day 8 of this course here.

Check out Day 10 of this course here.

Lost in coding? Discover our Learning Paths!
Lost in coding? Discover our Learning Paths!
Tired of being just an average developer?
Stop wasting your time and learn coding the right (and easy) way!
Tired of being just an average developer?
Stop wasting your time and learn coding the right (and easy) way!
Enter your email and we will send you the PDF guide:
Enter your email and we will send you the PDF guide