Questions: List Plso - V9S8C6Fqtib6Olje4F-Mvtw-Hnwa6
Questions: List Plso - V9S8C6Fqtib6Olje4F-Mvtw-Hnwa6
- Wei-Meng Lee, Beginning Android’" 4 Application Development, 2012 by John Wiley &
Sons
Questions
Unit 1
Unit 2
Unit 3
1. What is Intent, intent objects and fields? List and explain types of Intents
2. Explain the steps for sending and receiving the implicit intents.
3. What is Broadcast Receiver? How do you create Broadcast Receiver?
4. How do you make an HTTP connection to connect to internet?
5. What is a Service? How do you implement Started Service and Bound Service? Explain.
6. What is a Notification? Explain the implementation steps for creating Notifications.
7. Explain the Notification design guidelines.
8. List and Explain the Notification Priorities.
9. Define Loader? Explain, how do you start and restart a loader?
10. Explain Image Views to display pictures in Android Mobile.
11. Explain Activity Launch modes using attributes and intent flags.
12. Describe these App components, Intent filters, Content Sharing and Threads.
13. Describe these App components - Intent, Activity and Threads.
14. What is meant by UI architecture explain? What is intent? How many different
intent types are there?
15. How data is accessing and building a content provider? What would be the result
if not have network connectivity?
16. Develop an App having some animations and graphics.
17. Discuss Wireless Communications in Modern Mobile Technologies?
18. Write in detail about recent trends in communication protocols for IOT nodes?
19. Using the Intent Service to Simplify the Earthquake Update Service. Explain?
Unit 4
Unit 5
**********************************************************************
******
Unit 1
Android SDK tool is an important component of Android SDK. It consists of a complete set of
development and debugging tools. Below are the SDK developer tools:
Android Emulator.
Android SDK build tools are used for building actual binaries of Android App. The main
functions of Android SDK Build tools are built, debug, run and test Android applications. The
latest version of the Android SDK Build tool is 30.0.3. While downloading or updating
Android in our System, one must ensure that its latest version is download in SDK
Components.
3. Android Emulator
An Android Emulator is a device that simulates an Android device on your system. Suppose
we want to run our android application that we code. One option is that we will run this on
our Android Mobile by Enabling USB Debugging on our mobile. Another option is using
Android Emulator. In Android Emulator the virtual android device is shown on our system on
which we run the Android application that we code.
Thus, it simply means that without needing any physical device Android SDK component
“Android Emulator” provides a virtual device on the System where we run our Application.
The emulator’s come with the configuration for Various android phones, tablets, Wear OS,
and Android TV devices.
In Android Virtual Emulator all functions that are feasible on real Android mobile is works on
virtual Device like:
But there is one disadvantage of this emulator is that. It is very slow when System’s PC has
less RAM. It works fine when a maximum GB of RAM is present on our device.
Android SDK Platform-tools is helpful when we are working on Project and they will show the
error messages at the same time. It is specifically used for testing. It includes:
Android Debug Bridge (ADB), is a command-line tool that helps to communicate with
the device. It allows us to perform an action such as Installing App and Debugging App
etc.
Systrace tools help to collect and inspect timing information. It is very crucial for App
Debugging.
Android SDK tool is a component of SDK tool. It consists of a set of tools which and other
Utilities which are crucial for the development of Android Application. It contains the
complete set of Debugging and Development tools for android.
6. SDK Platforms
For Each Android Software, one SDK platform is available as shown below:
Like in this Android 11.0(R) is installed.
These are numbered according to the android version. The new version of the SDK platform
has more features and more compatible but the old version is less compatible with fewer
features. Like in Android 11.0(R) have more compatible and have more feature but the below
versions like Android 10.0(Q), Android4.4(KitKat) have less feature and is less compatible.
In SDK Update Sites, some sites are embedded in it which will check for Android SDK Updates
Tools. In this, one must ensure we don’t unclick the button below because these are checked
by default which will check for updates if we will unclick it then it doesn’t check updates for
those.
Here’s a breakdown of what Android has that other platforms might not offer:
1. Open-Source Nature (Android Open Source Project - AOSP)
Android is based on the Android Open Source Project (AOSP), meaning that its source code is
open for modification, allowing manufacturers, developers, and even enthusiasts to
customize the operating system to their needs.
Custom ROMs: Android users can install custom ROMs (like LineageOS, Pixel
Experience, etc.), which provide personalized experiences, features, and tweaks that
are not available in the stock version of the OS.
Wide Customization: Developers can create custom Android operating systems, and
users have the flexibility to change almost every aspect of the OS, including themes,
UI, and behavior.
Unlike iOS, which is exclusive to Apple, Android runs on devices from a wide range of
manufacturers, including Samsung, Google, Xiaomi, OnePlus, LG, Motorola, and many others.
Variety of Devices: Users can choose from a broad selection of devices in terms of
price, design, features, and functionality. Whether you're looking for budget-friendly
phones or high-end flagship devices, Android has something for everyone.
3. Google Integration
Google is deeply embedded in Android, offering a range of unique services and features that
enhance the user experience:
Google Assistant: Android offers native access to Google Assistant, one of the most
powerful voice-activated virtual assistants. It is integrated into the Android system,
making it highly functional and versatile for daily tasks, navigation, home automation,
and more.
Google Play Store: The Google Play Store offers a vast selection of apps, games, and
media, with better integration of services like Google Play Music, Movies, and News.
Android users also have access to a more open app ecosystem.
Android allows extensive customization options that are much more advanced compared to
iOS and other platforms:
Custom Lock Screens: In addition to home screens, Android offers a variety of lock
screen options, allowing users to modify or add widgets, shortcuts, and notifications.
Default Apps: Android allows users to set third-party apps as defaults (e.g., changing
the default browser, SMS app, or dialer), something that’s much more restricted on iOS.
Advanced Themes and Skins: Many manufacturers offer unique themes, skins, and
wallpapers that users can apply to further personalize their devices.
Android provides a file system with extensive access for users and apps:
Full File System Access: Android allows file managers and apps to access the file
system more freely. Users can browse and manage their files using built-in file
managers or third-party apps.
External Storage Support: Android supports external storage devices like microSD
cards, USB drives, and OTG devices. This feature is often not available or severely
limited on iOS devices.
File Sharing: Android's built-in file-sharing options, such as the ability to send files via
Bluetooth, NFC, or Wi-Fi Direct, offer a broader range of sharing capabilities compared
to other platforms.
Third-Party App Stores: Apart from the official Google Play Store, Android allows
apps to be distributed from third-party app stores like Amazon Appstore, Aptoide, or
even direct APK (Android Package) installations. Users can download and install apps
from sources outside the Play Store, although this comes with security risks if not done
carefully.
APK Installation: Unlike iOS, which is locked to the App Store for app installation,
Android allows the installation of APK files directly from the internet, enabling users to
try apps not yet available on the Play Store or sideload apps for testing purposes.
App Signing and Distribution for Developers: Android allows developers more
control over app distribution. Developers can distribute APKs directly to users or via
private channels, making it easier to test and deploy apps without needing to go
through an app store approval process.
7. Multiple App Background Processing
Background Services: Android has a rich API for running background services (such
as Service or JobScheduler), which are crucial for long-running tasks like syncing data,
playing music, or updating location. iOS offers background tasks but with more
limitations.
Push Notifications: Android supports push notifications and background tasks more
flexibly, allowing apps to wake up or trigger specific actions even when they're not
running in the foreground.
Android supports a broad range of connectivity options that can be utilized across various
devices:
NFC: Android devices can use NFC (Near Field Communication) for tasks such as
contactless payments, data transfer, or pairing devices.
Android Auto: Android Auto allows users to seamlessly connect their Android device
to their car’s infotainment system, providing access to apps like navigation, music, and
messaging.
Android offers more flexibility to developers in terms of app development and distribution:
Java and Kotlin: Android development can be done using Java or Kotlin (which is
officially preferred by Google). This provides flexibility in choosing programming
languages compared to iOS, which is limited to Swift and Objective-C.
Native Code Support (NDK): Android supports the use of native code (C, C++)
through the Android NDK (Native Development Kit), allowing for more performance-
intensive applications (e.g., games or apps that require low-level hardware access).
Explain Android Software Stack framework with neat figure.
Platform architecture
bookmark_border
Android is an open source, Linux-based software stack created for a wide array of devices
and form factors. Figure 1 shows the major components of the Android platform.
Linux kernel
The foundation of the Android platform is the Linux kernel. For example, the Android Runtime
(ART) relies on the Linux kernel for underlying functionalities such as threading and low-level
memory management.
Using a Linux kernel lets Android take advantage of key security features and lets device
manufacturers develop hardware drivers for a well-known kernel.
The hardware abstraction layer (HAL) provides standard interfaces that expose device
hardware capabilities to the higher-level Java API framework. The HAL consists of multiple
library modules, each of which implements an interface for a specific type of hardware
component, such as the camera or Bluetooth module. When a framework API makes a call to
access device hardware, the Android system loads the library module for that hardware
component.
Android runtime
For devices running Android version 5.0 (API level 21) or higher, each app runs in its own
process and with its own instance of the Android Runtime (ART). ART is written to run multiple
virtual machines on low-memory devices by executing Dalvik Executable format (DEX) files, a
bytecode format designed specifically for Android that's optimized for a minimal memory
footprint. Build tools, such as d8, compile Java sources into DEX bytecode, which can run on
the Android platform.
On Android 9 (API level 28) and higher, conversion of an app package's DEX files to
more compact machine code
Prior to Android version 5.0 (API level 21), Dalvik was the Android runtime. If your app runs
well on ART, then it can work on Dalvik as well, but the reverse might not be true.
Android also includes a set of core runtime libraries that provide most of the functionality of
the Java programming language, including some Java 8 language features, that the Java API
framework uses.
Many core Android system components and services, such as ART and HAL, are built from
native code that requires native libraries written in C and C++. The Android platform provides
Java framework APIs to expose the functionality of some of these native libraries to apps. For
example, you can access OpenGL ES through the Android framework’s Java OpenGL API to
add support for drawing and manipulating 2D and 3D graphics in your app.
If you are developing an app that requires C or C++ code, you can use the Android NDK to
access some of these native platform libraries directly from your native code.
The entire feature-set of the Android OS is available to you through APIs written in the Java
language. These APIs form the building blocks you need to create Android apps by simplifying
the reuse of core, modular system components and services, which include the following:
A rich and extensible view system you can use to build an app’s UI, including lists,
grids, text boxes, buttons, and even an embeddable web browser
A notification manager that enables all apps to display custom alerts in the status bar
Content providers that enable apps to access data from other apps, such as the
Contacts app, or to share their own data
Developers have full access to the same framework APIs that Android system apps use.
System apps
Android comes with a set of core apps for email, SMS messaging, calendars, internet
browsing, contacts, and more. Apps included with the platform have no special status among
the apps the user chooses to install. So, a third-party app can become the user's default web
browser, SMS messenger, or even the default keyboard. Some exceptions apply, such as the
system's Settings app.
The system apps function both as apps for users and to provide key capabilities that
developers can access from their own app. For example, if you want your app to deliver SMS
messages, you don't need to build that functionality yourself. You can instead invoke
whichever SMS app is already installed to deliver a message to the recipient you specify.
AVDs are used to mimic different types of Android devices, screen sizes, resolutions, Android
versions, and hardware configurations, allowing developers to test their apps in a variety of
environments.
Emulation of Hardware and OS: Virtual devices simulate the device’s screen,
buttons, sensors, and other hardware components, allowing the developer to run
Android applications on them.
Multiple Configurations: You can create multiple virtual devices with different
hardware profiles and Android versions to test the app's compatibility with a variety of
devices.
Testing Without Physical Device: AVDs allow developers to test apps on different
Android versions or screen sizes without having to buy different physical devices.
2. Navigate to AVD Manager: You can open the AVD Manager from the toolbar by
clicking on the "Tools" menu and selecting AVD Manager, or by clicking the "Device
Manager" icon on the toolbar.
3. Create a New Virtual Device: In the AVD Manager window, click the Create Virtual
Device button.
o Choose Device Type: Select the device you want to emulate (e.g., Pixel 4,
Nexus 5X).
o Select System Image: Choose the system image (Android version) that you
want the AVD to run. You can select different Android OS versions (such as
Android 10, 11, etc.).
o Configure AVD: Adjust the settings for the device (RAM, CPU architecture, SD
card size, etc.).
4. Run the Virtual Device: Once the AVD is created, click the green Play button next to
the device to launch the emulator.
Example:
Testing an app designed for tablets and phones with different screen sizes can be done by
creating multiple virtual devices with different screen dimensions and resolutions.
2. SDK Manager
The SDK Manager is a tool used in Android Studio to manage the Android Software
Development Kit (SDK) components, which include the necessary libraries, tools, platform
versions, and documentation required to develop Android applications. It helps you install
and update the SDK, as well as manage system images, APIs, and other Android tools.
Install and Update SDK Components: It allows you to download and update Android
SDK tools and APIs, including libraries, build tools, and different versions of Android
(such as Android 9, 10, etc.).
Managing SDK Platforms: The SDK Manager helps you manage different versions of
Android, ensuring that your development environment has the necessary Android
platform(s) for building apps that work across various devices.
Add-ons and Extras: You can also install additional tools and add-ons like Google Play
services, Android support libraries, and device drivers.
Monitoring SDK Health: It shows you the installed components and available updates
or missing components to ensure the environment is up-to-date and complete for
development.
2. Navigate to SDK Manager: Click on Tools > SDK Manager in the top menu, or click
the "SDK Manager" icon on the toolbar.
o The SDK Manager window will open, showing you various tabs like SDK
Platforms and SDK Tools.
o SDK Platforms Tab: You can download different Android versions (API levels). If
you need an older version of Android (like 5.0), you can select it and install it.
o SDK Tools Tab: You can install and update essential SDK tools like Android SDK
Build-Tools, Android Emulator, and other developer tools.
If you are developing an app targeting Android 10 (API Level 29), you would go to the SDK
Platforms tab in the SDK Manager and check Android 10. Then, in the SDK Tools tab,
ensure that the "Android Emulator" and other relevant tools are installed for testing your app.
AVD Manager is focused on managing and running virtual devices (emulators) to test
Android apps, simulating the behavior of an actual device.
SDK Manager is used to manage the SDK tools, platforms, and libraries necessary for
Android development, ensuring you have the proper components installed to build and
run apps on different Android versions and devices.
1. Package Declaration:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp"
android:versionCode="1"
android:versionName="1.0">
o The package attribute specifies the unique identifier for the application (usually
in reverse domain format).
2. Application Tag: The <application> tag encloses all components of the application,
such as activities, services, and broadcast receivers. This tag also specifies global
configurations like icons, themes, and the application name.
<application
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
3. Permissions: The <uses-permission> tag is used to declare the permissions that the
app requires to access certain resources or perform specific actions (e.g., accessing the
internet, using the camera).
<uses-permission android:name="android.permission.INTERNET"/>
4. Activities, Services, and Broadcast Receivers: Each component of the app (such
as Activity, Service, BroadcastReceiver, etc.) must be declared inside the <application>
tag to let the system know about them.
<activity android:name=".MainActivity">
<intent-filter>
</intent-filter>
</activity>
5. Intents and Filters: The <intent-filter> tag is used to declare the types of intents an
activity or service can handle. For example, a launcher activity typically has an intent
filter with the MAIN action and LAUNCHER category.
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
The Manifest file is used to declare all components of the application, such as:
Services: Background services that handle tasks such as music playback, network
requests, etc.
For example:
<activity android:name=".MainActivity">
<intent-filter>
</intent-filter>
</activity>
2. Specifying Permissions
The Manifest file is used to request permissions that are required by the application. For
example, if your app needs to access the camera, storage, or internet, you must specify
these permissions in the manifest.
Example:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
Without declaring necessary permissions in the manifest, the app will not have access to
these resources and will not function as expected.
The Manifest allows you to specify the minimum SDK version (minSdkVersion) and the
target SDK version (targetSdkVersion) that the application supports. This ensures
compatibility with different Android versions.
Example:
minSdkVersion: Specifies the minimum Android version your app can run on.
targetSdkVersion: Specifies the Android version your app is optimized for (i.e., the
version you’ve tested against).
The Manifest is responsible for mapping intents to the appropriate activities or services.
By using <intent-filter>, the manifest file defines what actions the app can perform and how
it can interact with other apps or the system.
Example:
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
This allows the app to handle specific types of intents, such as opening a specific URL or
responding to a particular action (e.g., opening the app via a link).
In the Manifest, you can specify the hardware and software features required by the
application. For example, if your app requires a camera, accelerometer, or GPS, you can
declare this in the manifest so that the system knows about the app's requirements.
Example:
<uses-feature android:name="android.hardware.location.gps"/>
This ensures that the app will only be available to users with the appropriate device features.
The Manifest also contains metadata about the overall app, such as the app's name, icon,
theme, and splash screen.
Example:
<application
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
This defines the theme and icon that will be displayed when the app is installed.
The Manifest defines the main entry point of the application using an <activity> tag with an
intent filter. The MainActivity is typically defined as the entry point of the app, which is
launched when the app is opened.
Example:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
Explain the steps for creating the Virtual device.
Creating a Virtual Device (AVD) in Android Studio allows you to emulate an Android device
on your computer for testing and development purposes. Here are the detailed steps to
create a Virtual Device:
o Launch Android Studio on your computer. Make sure you have installed Android
Studio and the necessary SDK tools.
o In Android Studio, go to the top menu bar and click on Tools > AVD Manager.
o Alternatively, you can click on the "Device Manager" icon located on the
toolbar, which also opens the AVD Manager.
o In the AVD Manager window, click the Create Virtual Device button. This starts
the process of creating a new AVD.
o You will be presented with a list of hardware profiles for different devices.
These profiles include various phones, tablets, wearables, and TVs.
o Choose a device model (e.g., Pixel 4, Nexus 5X, Android TV, etc.) that closely
matches the kind of device you want to test.
Tip: If you need to create a custom device profile, you can click on "New Hardware Profile"
to define your custom configuration, including screen size, resolution, and other hardware
characteristics.
o The next step involves choosing a system image (Android version) that your
virtual device will run. The system image includes the Android operating system
and other essential components like Google APIs.
o You will see a list of available system images, including different versions of
Android (e.g., Android 10, Android 11, etc.).
o Select a system image based on the Android version you want to test. For
instance, you can select Android 10 (Q) or Android 11 (R).
o If you haven’t downloaded the system image yet, click on the Download link
next to the version, and it will automatically download and install it.
o After selecting the system image, you will be presented with the AVD
Configuration screen. Here, you can adjust the settings for your virtual device.
o Device Orientation: Set whether you want your device to be in portrait or
landscape mode.
o RAM and CPU settings: You can configure the RAM, VM heap, and CPU
architecture (ARM, x86, etc.) based on your system's capabilities.
o SD Card: Optionally, you can configure the SD Card size for your virtual device
if needed.
You can also click on Show Advanced Settings to modify other options like Network
Latency, Graphics, Emulated Performance, and more.
o Your newly created virtual device will now appear in the AVD Manager window
under "Virtual Devices".
o To run the virtual device, click the green Play button next to the device you just
created. This will launch the Android Emulator with the virtual device you
configured.
o The emulator will take some time to boot up, depending on your computer’s
specifications and the device you selected. Once the emulator is started, it will
appear as a virtual Android device on your screen.
o You can interact with the device just like a real Android device.
After creating your virtual device, you can always make changes or create additional AVDs:
o In the AVD Manager, click on the pencil icon next to your device name to edit its
configuration. You can modify settings like system images, memory, and storage
size.
o If you no longer need the virtual device, you can click on the trash can icon in
the AVD Manager to delete it.
o The Project View displays your project files in a hierarchical structure. This
structure represents the different directories and subdirectories that make up
your project. You can expand and collapse these directories to view their
contents.
ProjectName/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ └── myapp/
│ │ │ │ └── MainActivity.java
│ │ │ ├── res/
│ │ │ │ ├── layout/
│ │ │ │ │ └── activity_main.xml
│ │ │ │ └── values/
│ │ │ │ └── strings.xml
│ │ │ └── AndroidManifest.xml
│ └── build.gradle
├── build/
├── gradle/
└── settings.gradle
2. Different Views (Android, Project, and Packages): Android Studio offers different
ways to view your project structure:
o Android View: This is the most user-friendly and recommended view for most
Android developers. It simplifies the view by organizing the project files into
logical categories like Java, Resources, Manifests, Gradle Scripts, etc.
It helps to separate the code, resources, and configuration files into distinct
sections, making it easier to navigate.
o Project View: This view shows the file structure exactly as it is in your file
system, with the complete directory structure. It's useful when you want to see
everything, including hidden files and non-Android-specific configurations.
o Packages View: This is a more traditional view, showing only the Java package
structure. It’s similar to how you would view packages in Java IDEs like IntelliJ or
Eclipse.
3. Quick Access to Key Files: The Project View allows you to quickly access essential
files and directories used in your Android app development:
o Java Code: The src/main/java/ directory contains all the Java files that define
the behavior of your app’s activities, services, and other components.
o Resources: The res/ folder contains various resources like layout XML files,
images, drawables, and values (strings, colors, dimensions).
o Gradle Scripts: The build.gradle file, located in the project’s root folder and
app/ folder, is crucial for managing dependencies, plugins, and project
configurations.
4. Search Functionality:
o Android Studio allows you to search for specific files or classes within the Project
View using the Search bar. You can quickly locate any file, class, or resource in
your project.
5. Contextual Operations:
o You can perform many operations directly from the Project View using the right-
click (context) menu. Common operations include:
New File: You can create new activities, layouts, or other resource files
directly from the Project View.
Show in Explorer/Finder: You can open the selected file or folder in your
system's file explorer.
o The Gradle Scripts section in the Project View allows you to manage build
configurations, dependencies, and project setup. The build.gradle files define the
behavior of the Gradle build system.
Let’s say you want to access the MainActivity.java file and the activity_main.xml layout
file:
1. In Android View:
o Navigate to app > src > main > java > com > example > myapp >
MainActivity.java to find the Java code.
o Navigate to app > src > main > res > layout > activity_main.xml to access
the XML layout.
2. In Project View:
o You can expand the directories to see the file structure exactly as it is on your file
system. This view shows you the raw structure, so you can see files like .gitignore
and build directories as well.
o Right-clicking on the file will allow you to open, delete, or refactor it easily.
Features of Android
Android Open Source Project so we can customize the OS based on our requirements.
Android supports different types of connectivity for GSM, CDMA, Wi-Fi, Bluetooth, etc.
for telephonic conversation or data transfer.
Using wifi technology we can pair with other devices while playing games or using
other applications.
We can manage all data storage-related activities by using the file manager.
It contains a wide range of media supports like AVI, MKV, FLV, MPEG4, etc. to play or
record a variety of audio/video.
It also supports different image formats like JPEG, PNG, GIF, BMP, MP3, etc.
Android supports multi-tasking means we can run multiple applications at a time and
can switch between them.
The design of the Android Application has guidelines from Google, which becomes
easier for developers to produce more intuitive user applications.
Fragmentation gives more power to Android Applications. This means the application
can run two activities on a single screen.
Releasing the Android application in the Google play store is easier when it is compared
to other platforms.
With neat diagram, show the major components of Android
stack.
Covered above
o Define the app’s purpose: Understand the problem your app is solving or the
functionality it provides.
2. Design:
o Wireframing and Prototyping: Design the layout and user interface (UI) of the
app using tools like Figma, Adobe XD, or Sketch.
o User Interface (UI) design: Create specific UI elements, icons, and app assets.
3. Development:
o Integrate Libraries & APIs: Integrate third-party libraries, SDKs, and services
such as Firebase, Google Maps, etc.
4. Testing:
o Unit Testing: Test individual components of the app (e.g., functions or methods)
using testing frameworks like JUnit.
o Integration Testing: Test how different parts of the app work together.
o UI Testing: Ensure the app’s UI is working as expected with frameworks like
Espresso.
o Manual Testing: Run the app on real devices or emulators to check for bugs or
usability issues.
5. Debugging:
o Use tools like Logcat, Android Profiler, and Breakpoints to find and fix bugs.
o Build APK/Bundle: Use Android Studio to compile and package the app into an
APK (Android Package) or App Bundle (AAB) for distribution.
o Signing: Sign the APK or AAB with a private key for security and to allow it to be
installed on devices.
o Google Play Store: Upload the APK/AAB to the Google Play Store, complete with
app descriptions, screenshots, and other metadata.
o Other Distribution Channels: Optionally distribute the APK via other platforms
or direct links.
o Monitor App Performance: Track the app’s performance using tools like
Firebase Analytics and Google Play Console.
o Bug Fixes and Updates: Push regular updates to fix bugs, introduce new
features, and maintain compatibility with the latest Android versions.
Click on the download button for your operating system (Windows, macOS, or Linux).
Android Studio provides the latest stable version of the IDE with all the necessary SDKs
and tools.
For Windows:
o Run the downloaded .exe file and follow the installation instructions.
o Make sure to select the option to install the Android Virtual Device (AVD) if
prompted, as it is necessary for running your app on an emulator.
For macOS:
o Open the downloaded .dmg file and drag the Android Studio icon to the
Applications folder.
For Linux:
o Extract the downloaded .zip file and follow the instructions in the official
documentation.
Once installed, open Android Studio by clicking on its icon (on Windows, macOS, or
Linux).
The first time you launch Android Studio, it will ask if you want to import previous
settings (if applicable). You can choose to import or select the "Do not import settings"
option.
Android Studio will guide you through the setup process. This includes downloading the
necessary SDK components (such as Android SDK, Emulator, and required system
libraries).
3. Configure SDK and Emulator
During the first launch, Android Studio will prompt you to install the Android SDK. The
SDK is essential for Android development, as it contains APIs and tools for building
Android applications.
o If you don't have a physical Android device for testing, you can set up a virtual
device using the Android Emulator.
o In Android Studio, navigate to Tools > AVD Manager to create a new Android
Virtual Device (AVD).
o Choose a device type (e.g., Pixel, Nexus) and select the Android version (API
Level) you want to use for testing.
When you open Android Studio, click on Start a new Android Studio project to
create a new app.
Android Studio provides various templates like Empty Activity, Basic Activity,
Navigation Drawer Activity, etc. Choose a template that best fits the structure of
your app.
o Package name: A unique identifier for your app (usually in reverse domain
format like com.example.myapp).
o Minimum API Level: Choose the lowest version of Android your app will
support.
After the configuration, Android Studio will create the project with the necessary files
(like MainActivity.java or MainActivity.kt, activity_main.xml, etc.).
Open the MainActivity.java or MainActivity.kt file in the src folder to write the
functionality for your app. This file typically includes the main logic for starting your
app and handling user interactions.
Open the activity_main.xml file under the res/layout/ folder to design the user
interface.
You can either write XML code directly or use the Layout Editor in Android Studio to
drag-and-drop elements (like buttons, text fields, etc.).
If you're using a physical Android device for testing, enable Developer Mode and USB
Debugging on the device, then connect it via USB.
To run the application, click the Run button (the green triangle icon) at the top of
Android Studio.
Select the device or emulator where you want to run your app.
Android Studio automatically builds the APK file (Android Package) when you run the
app. You can also manually build the APK by selecting Build > Build APK from the
menu.
Test the app on a virtual device (Android Emulator) or a physical Android device.
Step 2: Debugging
You can debug the app using Logcat (to view logs), breakpoints, and Android
Profiler (to analyze app performance).
Set breakpoints in the Java/Kotlin code by clicking on the left margin of the editor
window. When running the app in debug mode, it will pause at the breakpoints,
allowing you to inspect variables and step through the code.
Based on the testing feedback, modify the code or UI components (e.g., add new
features, fix bugs, improve performance).
To distribute your app (e.g., via Google Play Store), you need to generate a signed
APK or App Bundle.
Navigate to Build > Generate Signed APK and follow the instructions to create a
signed version of the app with a private key.
Once the APK is signed, you can upload it to the Google Play Store via the Google Play
Console.
Fill out metadata (description, screenshots, etc.) for your app on the Play Store.
After deploying the app, use Google Analytics or Firebase to monitor the
performance and usage of your app.
Regularly update your app to add new features, improve performance, and fix any bugs
based on user feedback.
Before running your app on an Android emulator, you need to have a Virtual Device
configured in Android Studio.
o If you haven't created a virtual device yet, click on Create Virtual Device.
o Select a device from the list of available devices (e.g., Pixel 4, Nexus 5X).
o Click Next.
o Choose a system image (select the Android version you want to use).
o You can modify settings like device orientation, RAM allocation, and graphics
settings if needed.
o In Android Studio, click on the Run button (green triangle icon) at the top of the
IDE.
o In the Select Deployment Target dialog, you will see your virtual device listed
as an available target device. Choose the virtual device you created earlier and
click OK.
o The emulator will boot up, which may take a few seconds to a few minutes,
depending on your computer’s resources.
o You can now interact with your app on the virtual device. The emulator behaves
like a real Android device, allowing you to test the app’s UI and functionality.
Running your app on a real Android device is essential to test performance and real-world
interactions.
o Ensure that you allow USB debugging on the device if a prompt appears on the
screen (select Allow or OK).
3. Install Device Drivers (if necessary):
o For Windows users, ensure that the correct drivers for your device are installed.
For most popular Android devices, Windows will automatically install the drivers,
but you may need to manually install drivers for some devices.
o You can find the official drivers on the manufacturer's website (e.g., for Samsung,
Google, etc.).
o In the Select Deployment Target window, you should see your connected
physical device listed under Connected Devices.
o Android Studio will build your app and install it on your physical device.
o Once the process is complete, the app will launch on your Android device.
o You can now test the app on the actual device. This allows you to check the app’s
real-world performance, response time, and device-specific features (like GPS,
sensors, etc.).
Troubleshooting Tips
Emulator Not Launching: If the emulator doesn't launch, ensure that your system
has sufficient resources (RAM, CPU) and that Intel HAXM or AMD Hypervisor (for
Windows/Linux) is installed.
Device Not Recognized: Ensure USB debugging is enabled and that the device is
properly connected via USB. Also, make sure the correct drivers are installed.
Running App Too Slow on Emulator: The emulator may run slower than a physical
device. You can increase performance by enabling hardware acceleration (e.g., using
Intel HAXM on Intel processors) or adjusting the emulator settings (such as reducing
the resolution or limiting background processes).
In Android, Activity Navigation refers to the process of managing how users move from one
screen (Activity) to another within an application. An Activity is a single screen in an app
that represents a user interface and handles the interaction between the user and the app.
Managing activity navigation effectively is crucial to providing a smooth, intuitive user
experience.
Android provides several navigation strategies to control the flow of activities and
facilitate user movement between screens. Two common strategies for navigation are:
1. Explicit Navigation
2. Implicit Navigation
1. Explicit Navigation
Explicit Navigation refers to specifying the exact Activity or component to navigate to. This
form of navigation is intent-based and is commonly used when you know exactly which
Activity or component needs to be launched.
How it works:
You specify the exact Activity class that you want to launch.
Example:
startActivity(intent);
In this example:
Use Cases:
Use explicit navigation when you know the destination and want to navigate to a
specific screen.
Commonly used for navigating between app screens, such as from a login screen to a
dashboard.
2. Implicit Navigation
Implicit Navigation doesn't specify the exact Activity to navigate to. Instead, it relies on the
system to find the appropriate component that can handle a certain action or intent filter.
This is more flexible because it can invoke any Activity or app that is capable of performing
the given action, even if the destination Activity is not known in advance.
How it works:
Implicit navigation involves using an Intent with a specific action or category, and the
Android system uses the Intent filters defined in the manifest to determine the
appropriate component to handle the request.
Example:
startActivity(intent);
In this example:
The ACTION_VIEW intent is implicit, as it doesn't specify which app should handle it.
The Android system searches for apps with the proper Intent filter (e.g., web browsers)
and opens the URL in one of those apps.
Use Cases:
Use implicit navigation when you want to perform an action that can be handled by
other apps or when the specific destination is not known at the time of launch.
Besides explicit and implicit navigation, Android offers several navigation strategies to
organize app flow, including:
The Navigation Drawer is a common UI pattern that slides in from the left side of the
screen, providing a menu for users to navigate between different sections of the app. It is
often used for global navigation in apps with multiple sections or categories.
How it works:
A DrawerLayout is used, and the app defines various navigation options inside the
drawer.
Users can tap on the items in the drawer to navigate between Activities or fragments.
Example:
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/navigation_drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</androidx.drawerlayout.widget.DrawerLayout>
2. Bottom Navigation
The Bottom Navigation is a UI element placed at the bottom of the screen that allows quick
navigation between top-level views in the app. It is especially useful for apps with 3-5 top-
level destinations.
How it works:
The app defines items that represent different sections or activities, and users can
switch between these sections by tapping the corresponding icon.
Example:
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu"/>
In this example:
TextView Example:
<TextView
android:id="@+id/myTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Android!"
android:textSize="18sp"
android:textColor="#FF5733"
android:gravity="center"
android:padding="16dp"
android:background="@drawable/rounded_background" />
In this example, the TextView has several XML attributes defined, which are used to style
and customize it. Below are explanations of some of the common attributes used for a
TextView.
1. android:id
o Example: android:id="@+id/myTextView"
o This allows you to reference this TextView in your Java or Kotlin code (e.g.,
findViewById(R.id.myTextView)).
o These attributes determine the size of the TextView based on its content.
wrap_content: The size of the TextView will be just enough to fit the content
(e.g., text).
3. android:text
o This attribute sets the actual text content that will appear in the TextView.
4. android:textSize
o Example: android:textSize="18sp"
o This attribute sets the size of the text in scale-independent pixels (sp), which
ensures that text is scaled appropriately for different screen densities and user
preferences.
5. android:textColor
o Example: android:textColor="#FF5733"
o You can use either a color code (like #FF5733 for a shade of red) or a predefined
color resource (like @android:color/black) to set the text color.
6. android:gravity
o Example: android:gravity="center"
7. android:padding
o Example: android:padding="16dp"
o This attribute adds padding (spacing) on all sides of the text within the TextView.
You can also use more specific padding attributes like android:paddingLeft,
android:paddingRight, etc.
8. android:background
o Example: android:background="@drawable/rounded_background"
o You can set a background color, image, or drawable resource here. In this case, a
drawable resource (rounded_background) is used to set a custom background,
such as a rounded shape.
9. android:maxLines
o Purpose: Defines the maximum number of lines of text that can be displayed.
o Example: android:maxLines="2"
o If the text exceeds the number of lines specified, it will be truncated, and the
extra text will not be shown.
10. android:ellipsize
o Purpose: Controls how to handle text that overflows in a TextView.
o Example: android:ellipsize="end"
o If the text is too long to fit, you can specify that the overflowed part of the text
should be replaced with an ellipsis (...). Other options include start, middle, or
marquee.
1. android:typeface
o Example: android:typeface="monospace"
o Example:
o Example:
android:shadowColor="#66000000"
android:shadowDx="2"
android:shadowDy="2"
android:shadowRadius="4"
<TextView
android:id="@+id/helloTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Welcome to Android!"
android:textSize="20sp"
android:textColor="#FF4081"
android:gravity="center"
android:padding="20dp"
android:background="@drawable/rounded_border"
android:maxLines="3"
android:ellipsize="end"
android:typeface="serif"
android:lineSpacingExtra="4dp"
android:shadowColor="#55000000"
android:shadowDx="2"
android:shadowDy="2"
android:shadowRadius="4" />
Example:
In this example, one EditText is used to input the text. This text is sent to the second activity
when the “Send” button is clicked. For this, Intent will start and the following methods will
run:
putExtra() method is used for sending the data, data in key-value pair key is variable
name and value can be Int, String, Float, etc.
getStringExtra() method is for getting the data(key) that is sent by the above
method. According to the data type of value, there are other methods
like getIntExtra(), getFloatExtra()
How to Create an Android App to Send and Receive the Data between Two Activity
To create a new project in Android Studio please refer to How to Create/Start a New
Project in Android Studio . The code for that has been given in both Java and Kotlin
Programming Language for Android. This will create an XML file and a Java File. Please
refer to the prerequisites to learn more about this step.
Next, go to the activity_main.xml file , which represents the UI of the project. Below is the
code for the activity_main.xml file. Comments are added inside the code to understand the
code in more detail. Open the “activity_first_activity.xml” file and add the following widgets in
a Relative Layout .
Also, Assign the ID to each component along with other attributes as shown in the image and
the code below. The assigned ID on a component helps that component to be easily found
and used in the Java/Kotlin files.
Syntax:
android:id="@+id/id_name"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".first_activity">
<EditText
android:id="@+id/send_text_id"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginTop="20dp"
android:hint="Input"
android:textSize="25dp"
android:textStyle="bold" />
<Button
android:id="@+id/send_button_id"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="150dp"
android:layout_marginTop="150dp"
android:text="send"
android:textStyle="bold" />
</RelativeLayout>
Go to the MainActivity File and refer to the following code. Below is the code for the
MainActivity File. Comments are added inside the code to understand the code in more detail.
Now, after the UI, this step will create the Backend of the App. For this, open the
“first_activity” file and instantiate the components made in the XML file (EditText, send
Button) using findViewById() method. This method binds the created object to the UI
Components with the help of the assigned ID.
Syntax: General
Add the listener to the send button and this button will send the data.
send_button.setOnClickListener(v -> {}
after clicking this button following operation will be performed. Now create the String type
variable to store the value of EditText which is input by the user. Get the value and convert it
to a string.
where getApplicationContext() will fetch the current activity. Put the value in the putExtra
method in the key-value pair then start the activity.
intent.putExtra("message_key", str);
startActivity(intent);
where “str” is the string value and the key is “message_key” this key will use to get the str
value
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
Button send_button;
EditText send_text;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first_activity);
send_button = findViewById(R.id.send_button_id);
send_text = findViewById(R.id.send_text_id);
// add the OnClickListener in sender button after clicked this button following Instruction
will run
send_button.setOnClickListener(v -> {
// get the value which input by user in EditText and convert it to string
// message_key by this key we will receive the value, and put the string
intent.putExtra("message_key", str);
startActivity(intent);
});
android project > File > new > Activity > Empty Activity
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.geeksforgeeks.navedmalik.sendthedata.Second_activity">
<TextView
android:id="@+id/received_value_id"
android:layout_width="300dp"
android:layout_height="50dp"
android:layout_marginLeft="40dp"
android:layout_marginTop="20dp"
android:textSize="40sp"
android:textStyle="bold"
android:layout_marginStart="40dp" />
</RelativeLayout>
Define the TextView variable, use findViewById() to get the TextView as shown above.
The received value set in the TextView object of the second activity XML file
receiver_msg.setText(str);
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
TextView receiver_msg;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second_activity);
receiver_msg = findViewById(R.id.received_value_id);
receiver_msg.setText(str);
Output:
Discuss about Android Application Lifecycle
What Is Android?
Android is a mobile operating system that is based on a modified version of Linux. It was
originally
developed by a startup of the same name, Android, Inc. In 2005, as part of its strategy to
enter the
mobile space, Google purchased Android and took over its development work (as well as its
development
team).
The main advantage of adopting Android is that it offers a unified approach to application
development.
Developers need only develop for Android, and their applications should be able to run on
numerous
different devices, as long as the devices are powered using Android. In the world of
smartphones, applications
are the most important part of the success chain. Device manufacturers therefore see
Android
as their best hope to challenge the onslaught of the iPhone, which already commands a large
base of
applications.
Architecture of Android
In order to understand how Android works, take a look at Figure 1-1, which shows the various
layers
Linux kernel — This is the kernel on which Android is based. This layer contains all the
lowlevel
Libraries — These contain all the code that provides the main features of an Android
OS. For
example, the SQLite library provides database support so that an application can use it for
data storage. The WebKit library provides functionalities for web browsing.
Android runtime — At the same layer as the libraries, the Android runtime provides a
set of core
libraries that enable developers to write Android apps using the Java programming language.
The
Android runtime also includes the Dalvik virtual machine, which enables every Android
application
to run in its own process, with its own instance of the Dalvik virtual machine (Android
applications are compiled into the Dalvik executables). Dalvik is a specialized virtual machine
designed specifically for Android and optimized for battery-powered mobile devices with
limited
Applications — At this top layer, you will find applications that ship with the Android
device
(such as Phone, Contacts, Browser, etc.), as well as applications that you download and
install
from the Android Market. Any applications that you write are located at this layer.
1. If an activity is in the foreground of the screen i.e at the top of the stack, then it is said
to be active or running. This is usually the activity that the user is currently interacting
with.
2. If an activity has lost focus and a non-full-sized or transparent activity has focused on
top of your activity. In such a case either another activity has a higher position in multi-
window mode or the activity itself is not focusable in the current window mode. Such
activity is completely alive.
4. The system can destroy the activity from memory by either asking it to finish or simply
killing its process. When it is displayed again to the user, it must be completely
restarted and restored to its previous state.
For each stage, android provides us with a set of 7 methods that have their own significance
for each stage in the life cycle. The image shows a path of migration whenever an app
switches from one state to another. For a deeper understanding and practical experience of
handling lifecycle events in Kotlin, the Android Mastery with Kotlin: Beginner to
Advanced course provides hands-on projects and in-depth lessons
Detailed introduction on each of the method is stated as follows:
1. onCreate()
It is called when the activity is first created. This is where all the static work is done like
creating views, binding data to lists, etc. This method also provides a Bundle containing its
previous frozen state, if there was one.
Example:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
2. onStart()
It is invoked when the activity is visible to the user. It is followed by onResume() if the activity
is invoked from the background. It is also invoked after onCreate() when the activity is first
started.
Example:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// The content view pointing to the id of layout
3. onRestart()
It is invoked after the activity has been stopped and prior to its starting stage and thus is
always followed by onStart() when any activity is revived from background to on-screen.
Example:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
4. onResume()
It is invoked when the activity starts interacting with the user. At this point, the activity is at
the top of the activity stack, with a user interacting with it. Always followed by onPause()
when the activity goes into the background or is closed by the user.
Example:
JavaKotlin
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.example.share.R;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
5. onPause()
It is invoked when an activity is going into the background but has not yet been killed. It is a
counterpart to onResume(). When an activity is launched in front of another activity, this
callback will be invoked on the top activity (currently on screen). The activity, under the
active activity, will not be created until the active activity’s onPause() returns, so it is
recommended that heavy processing should not be done in this part.
Example:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
protected void onPause() {
6. onStop()
It is invoked when the activity is not visible to the user. It is followed by onRestart() when
the activity is revoked from the background, followed by onDestroy() when the activity is
closed or finished, and nothing when the activity remains on the background only. Note that
this method may never be called, in low memory situations where the system does not have
enough memory to keep the activity’s process running after its onPause() method is called.
Example:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
7. onDestroy()
The final call received before the activity is destroyed. This can happen either because the
activity is finishing (when finish() is invoked) or because the system is temporarily destroying
this instance of the activity to save space. To distinguish between these scenarios, check it
with isFinishing() method.
Example:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
This tutorial will explain you how you can organize your application resources, specify
alternative resources and access them in your applications.
Alternative Resources
Your application should provide alternative resources to support specific device
configurations. For example, you should include alternative drawable resources ( i.e.images )
for different screen resolution and alternative string resources for different languages. At
runtime, Android detects the current device configuration and loads the appropriate
resources for your application.
To specify configuration-specific alternatives for a set of resources, follow the following steps
−
Save the respective alternative resources in this new directory. The resource files must
be named exactly the same as the default resource files as shown in the below
example, but these files will have content specific to the alternative. For example
though image file name will be same but for high resolution screen, its resolution will
be high.
Below is an example which specifies images for a default screen and alternative images for
high resolution screen.
Below is another example which specifies layout for a default language and alternative layout
for Arabic language.
Accessing Resources
During your application development you will need to access defined resources either in your
code, or in your layout XML files. Following section explains how to access your resources in
both the scenarios −
When your Android application is compiled, a R class gets generated, which contains
resource IDs for all the resources available in your res/ directory. You can use R class to
access that resource using sub-directory and resource name or directly resource ID.
Example
To access res/drawable/myimage.png and set an ImageView you will use following code −
Here first line of the code make use of R.id.myimageview to get ImageView defined with
id myimageview in a Layout file. Second line of code makes use of R.drawable.myimage to
get an image with name myimage available in drawable sub-directory under /res.
Example
<resources>
</resources>
Now you can set the text on a TextView object with ID msg using a resource ID as follows −
msgTextView.setText(R.string.hello);
Example
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</LinearLayout>
This application code will load this layout for an Activity, in the onCreate() method as follows
−
setContentView(R.layout.activity_main);
<resources>
<color name="opaque_red">#f00</color>
<string name="hello">Hello!</string>
</resources>
Now you can use these resources in the following layout file to set the text color and text
string as follows −
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@color/opaque_red"
android:text="@string/hello" />
2. Mobile Networks:
o Cellular networks are typically used for internet access and phone calls, while Wi-
Fi is used in local areas for high-speed internet.
3. Mobile Software:
o Mobile software includes the operating system and applications that run on
mobile devices. Popular mobile operating systems include Android and iOS.
4. Cloud Computing:
o Cloud computing provides back-end services that mobile devices rely on for data
storage, processing, and other computational tasks. Mobile devices use cloud
computing to access data, applications, and services remotely, reducing the need
for local storage and processing power.
o Data is transferred wirelessly between mobile devices and servers. Mobile data
management tools allow synchronization and storage of data across devices and
cloud services, enabling access to the most up-to-date information on any device.
1. Data Input:
o Data is input through the device’s interface (touchscreen, voice, sensors). For
example, users might input text or interact with a mobile app using gestures or
voice commands.
2. Data Transmission:
o The device communicates with the network using wireless technologies (Wi-Fi,
4G, 5G, Bluetooth). The data (e.g., requests, commands, or updates) is sent over
the internet or a local network to remote servers or devices.
3. Data Processing:
o The server or cloud platform processes the incoming data. For example, when a
user accesses a mobile app, the app may fetch data from a server, run
computations, or use cloud services to execute tasks.
4. Data Output:
o The output (e.g., responses, content) is sent back to the mobile device. The
mobile device displays the results or provides feedback to the user.
o Platform-specific Development:
o Cross-platform Development:
o Mobile app architecture defines the structure of the app, and it focuses on the
organization of code, components, and data management. Common patterns
include:
Model-View-Controller (MVC)
Model-View-ViewModel (MVVM)
Clean Architecture
o User Interface (UI) refers to the visual design of the app (layouts, colors,
typography), and User Experience (UX) refers to how users interact with the
app and how intuitive the app feels. Designing for mobile involves working within
the limitations of smaller screen sizes, varied device types, and different user
contexts (e.g., one-handed usage, touch gestures).
o Responsive Design: Ensures the app works well on different screen sizes and
orientations (portrait vs. landscape).
4. Performance Optimization:
o Mobile devices have limited resources (CPU, memory, battery). Therefore,
optimizing app performance is crucial for delivering a smooth experience.
Strategies for performance optimization include:
5. Mobile Security:
o Mobile apps handle sensitive data, so ensuring security is critical. Mobile app
security involves protecting user data, securing network communications, and
ensuring the integrity of the app. Key practices include:
o Testing mobile applications involves ensuring that the app works properly across
various devices, screen sizes, and operating system versions. Types of tests
include:
o App Deployment: Mobile apps are distributed via app stores (Google Play Store
for Android and Apple App Store for iOS). Each store has specific guidelines for
app submission, review, and release.
o App Updates and Maintenance: Mobile apps require regular updates to fix
bugs, improve performance, and introduce new features. Maintenance involves
monitoring app performance, user feedback, and staying up-to-date with OS
updates.
1. Device Fragmentation:
o There is a wide variety of devices with different screen sizes, hardware
specifications, and OS versions. Mobile engineers must account for this
fragmentation to ensure the app works across all devices.
2. Battery Consumption:
o Mobile devices have limited battery life, and apps that consume too much power
will negatively affect the user experience.
3. Network Connectivity:
4. Security Risks:
o Mobile apps are often targets for cyber-attacks. Protecting user data and ensuring
secure communications are constant concerns for developers.
o Designing an intuitive and user-friendly experience for small screens and diverse
contexts is a challenge. Apps must be easy to navigate and accessible.
Mobile computing is a critical enabler of the Internet of Things (IoT), as it provides the
infrastructure for mobile devices to interact with IoT devices and systems. IoT typically
involves a network of connected devices, sensors, actuators, and other embedded systems
that collect and exchange data. The use of mobile computing techniques ensures that users
can access, control, and interact with IoT devices from anywhere at any time. Here’s an in-
depth look at the mobile computing techniques applied to IoT:
Overview: Mobile applications serve as the interface between users and IoT devices.
These applications allow users to remotely control and monitor IoT devices, such as
smart home appliances, wearables, industrial machines, and healthcare devices.
Techniques:
o Cloud Integration: Many IoT devices store and process data in the cloud. Mobile
applications use cloud services to fetch, update, and synchronize data. For
example, a user can monitor the data from a smart thermostat or security
camera via a mobile app.
Overview: Mobile devices communicate with IoT devices through different wireless
communication protocols. These protocols ensure reliable and efficient data
transmission between mobile devices and IoT networks.
Techniques:
o Wi-Fi: Mobile devices use Wi-Fi to communicate with IoT devices that are
connected to the same local network. Wi-Fi is more suitable for high-bandwidth
applications, such as streaming data from security cameras or controlling smart
appliances.
o Zigbee and Z-Wave: These protocols are used in home automation for device
communication. While Zigbee is designed for low power consumption and low
data rates, Z-Wave is commonly used in home security and energy monitoring.
o Cellular (LTE/5G): Mobile devices also use cellular networks for communication
with IoT devices, especially for IoT applications that require long-range
communication and constant connectivity, such as fleet management, remote
surveillance, and agriculture monitoring.
o LoRaWAN (Long Range Wide Area Network): LoRaWAN is ideal for low-
power, long-range communication for IoT applications, such as environmental
monitoring, smart agriculture, and asset tracking. Mobile applications can
connect to IoT devices via LoRaWAN gateways.
Example: A smart home app uses BLE to connect to smart locks and Wi-Fi to control air
conditioning systems.
Overview: Edge and fog computing enable data processing closer to the source of
data generation (IoT devices), reducing latency and bandwidth usage. In IoT, mobile
devices can leverage edge and fog computing for faster responses and local decision-
making.
Techniques:
o Edge Computing: IoT devices process data locally on the device or near the
device (in edge nodes) before sending it to the cloud. For example, smart
cameras can analyze video streams locally to detect motion or faces, reducing
the need to send raw video data to the cloud for analysis.
Example: In a smart agriculture system, a mobile app can interact with IoT devices in
the field, but data analysis happens at a local edge server or mobile device to control
irrigation based on local weather data.
Overview: Cloud computing provides scalable storage and processing power for IoT
devices. Mobile devices can access the cloud to retrieve data, manage devices, and
perform analytics in real-time.
Techniques:
o IoT Cloud Platforms: Cloud platforms like AWS IoT, Google Cloud IoT, and
Microsoft Azure IoT offer IoT-specific services to manage devices, process data,
and integrate with mobile applications.
Example: A mobile app that interacts with a smart thermostat can pull data from the
cloud to update settings and display the current temperature in real-time.
Overview: Location-based services enable mobile devices to interact with IoT systems
based on the user’s physical location. Using GPS, Wi-Fi, or Bluetooth, mobile apps can
retrieve location data to trigger actions in IoT devices.
Techniques:
o Indoor Positioning Systems (IPS): IPS technologies like Bluetooth Low Energy
(BLE) beacons enable accurate indoor navigation. Mobile devices can interact
with IoT systems inside buildings for applications like asset tracking, smart retail,
or navigation within large facilities.
Example: A smart door lock could automatically unlock when a user’s mobile device
enters the home geofence, or a mobile app could track a package’s location in a
warehouse using BLE.
Overview: Security is critical in IoT systems as they are prone to hacking, data
breaches, and unauthorized access. Mobile devices often serve as gateways for
interacting with IoT devices, so ensuring secure communication between mobile apps
and IoT devices is essential.
Techniques:
o Encryption: IoT communications between mobile devices and IoT systems can
be secured using encryption protocols such as SSL/TLS, ensuring the
confidentiality of sensitive data during transmission.
Example: A mobile app controlling a home security system might require user
authentication (password or fingerprint) before granting access to arm/disarm the
system.
Overview: Data analytics and machine learning (ML) play a key role in extracting
insights from the massive amounts of data generated by IoT devices. Mobile computing
integrates these techniques to help users make data-driven decisions.
Techniques:
Example: In smart homes, mobile apps can learn user preferences over time and
optimize IoT device behavior based on the collected data (e.g., adjusting heating and
lighting based on usage patterns).
Unit 2
View
A View is defined as the user interface which is used to create interactive UI components
such as TextView, ImageView, EditText, RadioButton, etc., and is responsible for event
handling and drawing. They are Generally Called Widgets.
View
ViewGroup
A ViewGroup act as a base class for layouts and layouts parameters that hold other Views or
ViewGroups and to define the layout properties. They are Generally Called layouts.
ViewGroup
The Android framework will allow us to use UI elements or widgets in two ways:
Android Table Layout: TableLayout is a ViewGroup subclass, used to display the child
View elements in rows and columns.
Android Web View: WebView is a browser that is used to display the web pages in our
activity layout.
Android Grid View: GridView is a ViewGroup that is used to display a scrollable list of
items in a grid view of rows and columns.
Example Diagram:
Syntax:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</LinearLayout>
RelativeLayout
RelativeLayout is a layout in which we can arrange views/widgets according to the position of
other view/widgets. It is independent of horizontal and vertical view and we can arrange it
according to one’s satisfaction.
Example Diagram:
Syntax:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RelativeLayout>
1. LinearLayout
2. RelativeLayout
3. FrameLayout
4. ConstraintLayout
5. GridLayout
6. TableLayout
7. CoordinatorLayout
8. ScrollView
9. DrawerLayout
1. LinearLayout
Use case: If you want all the elements to appear in a single column or row.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First Item"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second Item"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
</LinearLayout>
Orientation: You can set the orientation to vertical or horizontal to control the
direction of the layout.
2. RelativeLayout
In a RelativeLayout, child views are positioned relative to each other or the parent layout.
You can position views based on their relationship with other views (e.g., align one view to
the left of another or center a view in the parent).
Use case: When you need precise control over the positioning of UI elements relative
to others.
Example:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World"
android:layout_centerHorizontal="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
android:layout_below="@id/textView"
android:layout_alignParentRight="true"/>
</RelativeLayout>
3. FrameLayout
A FrameLayout is designed to block out an area on the screen to display a single item. You
can stack views on top of each other, and only the topmost view will be visible unless you
manage the visibility of the others.
Use case: When you need to display a single element or overlay multiple elements on
top of each other.
Example:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/background_image"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Overlay Text"
android:layout_gravity="center"/>
</FrameLayout>
Stacking Views: The ImageView is the background, and the TextView is centered over
it.
4. ConstraintLayout
ConstraintLayout is a flexible layout that allows you to define the position and size of child
views based on constraints (relationships to other views). It is the most powerful and
recommended layout for complex UIs.
Use case: For complex UIs with complex interactions between views. It provides a flat
view hierarchy, making it ideal for performance.
Example:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
app:layout_constraintTop_toBottomOf="@id/textView"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
5. GridLayout
A GridLayout allows you to arrange child views in a grid-like structure with rows and
columns. It is similar to a table.
Use case: When you need to arrange elements in a table format (e.g., buttons in a
calculator or a grid of images).
Example:
<GridLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_column="1"/>
</GridLayout>
Row and Column: android:columnCount specifies the number of columns. Child views
can be assigned specific rows and columns.
6. TableLayout
A TableLayout is used to display UI elements in a grid of rows and columns. Each row can
have one or more columns, and the children are arranged accordingly.
Example:
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First Name"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Last Name"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</TableRow>
</TableLayout>
Table Rows: TableRow is used to define each row in the table. Views in a TableRow are
laid out horizontally.
7. CoordinatorLayout
Use case: For complex user interactions, such as handling scroll events or creating
animations.
Example:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:title="Coordinator Layout"/>
</AppBarLayout>
<RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
8. ScrollView
A ScrollView is used to enable scrolling of a single child view when the content exceeds the
screen size.
Use case: When you have content that doesn’t fit on the screen and needs to be
scrollable.
Example:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</LinearLayout>
</ScrollView>
9. DrawerLayout
Example:
<androidx.drawerlayout.widget.DrawerLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
<!-- Drawer menu -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
DrawerLayout: Defines the sliding menu and the main content area.
Conclusion
Each layout in Android is designed for specific scenarios, and understanding them helps in
choosing the right one based on the requirements of your app's UI. Here's a quick recap of
the main layouts:
Each layout offers unique features and can be combined to create rich, dynamic interfaces.
<fragment> tag is used to insert the fragment in an android activity layout. By dividing the
activity’s layout multiple fragments can be added in it.
Understanding fragment lifecycles is crucial for building dynamic apps. For those looking to
master fragments using Kotlin, the Android Mastery with Kotlin: Beginner to
Advanced course covers everything from lifecycle management to advanced
implementations.
2. List Fragment: This Fragment is used to display a list-view from which the user can
select the desired sub-activity. The menu drawer of apps like Gmail is the best example
of this kind of android fragment.
3. Fragment Transaction: This kind of fragments in android supports the transition from
one fragment in android to another at run time. Users can switch between multiple
fragments like switching tabs.
Android Fragment Lifecycle
Each fragment has it’s own lifecycle but due to the connection with the Activity it belongs to,
the android fragment lifecycle is influenced by the activity’s lifecycle.
Methods Description
onAttach() The very first method to be called when the fragment has been associated
with the activity. This method executes only once during the lifetime of a
fragment.
When we attach fragment(child) to Main(parent) activity then it call first
and then not call this method any time(like you run an app and close and
reopen) simple means that this method call only one time.
onCreate() This method initializes the fragment by adding all the required attributes
and components.
onCreateView System calls this method to create the user interface of the fragment. The
() root of the fragment’s layout is returned as the View component by this
method to draw the UI.
You should inflate your layout in onCreateView but shouldn’t initialize other
views using findViewById in onCreateView.
onViewCreate It indicates that the activity has been created in which the fragment exists.
d() View hierarchy of the fragment also instantiated before this function call.
onStart() The system invokes this method to make the fragment visible on the user’s
device.
onResume() This method is called to make the visible fragment interactive.
onPause() It indicates that the user is leaving the fragment. System call this method
to commit the changes made to the fragment.
onStop() Method to terminate the functioning and visibility of fragment from the
user’s screen.
onDestroyVie System calls this method to clean up all kinds of resources as well as view
w() hierarchy associated with the fragment. It will call when you can attach
new fragment and destroy existing fragment Resoruce
onDestroy() It is called to perform the final clean up of fragment’s state and its lifecycle.
onDetach() The system executes this method to disassociate the fragment from its
host activity.
It will call when your fragment Destroy(app crash or attach new fragment
with existing fragment)
Android Fragment When to call Method
Fragments in android are always embedded in Activities i.e., they are added to the layout of
activity in which they reside. Multiple fragments can be added to one activity. This task can
be carried out in 2 ways:
1. Statically: Explicitly mention the fragment in the XML file of the activity. This type of
fragment can not be replaced during the run time.
Almost all android app uses dynamic addition of fragments as it improves the user
experience. Below is the step-by-step implementation of adding 2 fragments in one activity. A
default fragment will be visible when the activity appears on the screen and the user can
switch between the 2 fragments at the run time.
All the strings which are used in the activity are listed in this file
<resources>
</resources>
Open the activity_main.xml file and add 2 buttons to it which will be used to switch
between the 2 fragments. Further, add the fragment element in the activity layout. It is the
area in which the fragments in android will be displayed.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#168BC34A"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:fontFamily="@font/roboto"
android:text="@string/heading"
android:textAlignment="center"
android:textColor="@android:color/holo_green_light"
android:textSize="24sp"
android:textStyle="bold" />
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="selectFragment"
android:text="@string/fragment1_button"
android:textColor="@android:color/background_light"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="@+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="selectFragment"
android:text="@string/fragment2_button"
android:textColor="@android:color/background_light"
android:textSize="18sp"
android:textStyle="bold" />
<fragment
android:id="@+id/fragment_section"
android:name="com.example.fragments_backup.FragmentOne"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
tools:layout="@layout/fragment_one" />
</LinearLayout>
The android:name tag under the <fragment> element is containing the file name of default
fragment which is to be displayed when activity opens.
These files contain only the onCreateView() method to inflate the UI of the fragment and
returns the root of the fragment layout. If the fragment does not have any UI, it will return
null.
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@Override
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@Override
Create two Layout Resource Files for both the fragments. Fragment displays a text on the
screen and have a background color to differentiate their area in the Activity layout. Below is
the code to implement this layout.
1. fragment_one.xml file:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#5C52CC57"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/fragment1_text1"
android:textAlignment="center"
android:textColor="@android:color/background_light"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
2. fragment_two.xml file:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#5C3473A6"
android:orientation="vertical">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/roboto"
android:gravity="center"
android:text="@string/fragment2_text1"
android:textAlignment="center"
android:textColor="@android:color/background_light"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
Step 6: Working with the MainActivity.java file
Now, the functionality of the button to perform operations on clicking will be defined in the
MainActivity class. Moreover, the code for the replacement of fragments during run time is
also mentioned in this file. Below is the code to implement this step.
import android.os.Bundle;
import android.view.View;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import androidx.appcompat.app.AppCompatActivity;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment fr;
// if button1 is clicked
if(view == findViewById(R.id.button1)) {
fr = new FragmentOne();
else {
fr = new FragmentTwo();
FragmentManager fm = getFragmentManager();
fragmentTransaction.replace(R.id.fragment_section, fr);
fragmentTransaction.commit();
Output:
Video
A checkbox is created using the <CheckBox> widget in XML layout files. Below is an example
of how to define and design checkboxes in an Android XML layout.
xml
Copy code
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginBottom="16dp"/>
<CheckBox
android:id="@+id/appleCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Apple"
android:layout_marginBottom="8dp"/>
<CheckBox
android:id="@+id/bananaCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Banana"
android:layout_marginBottom="8dp"/>
<CheckBox
android:id="@+id/mangoCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mango"
android:layout_marginBottom="8dp"/>
<!-- Submit Button -->
<Button
android:id="@+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:onClick="onSubmit"/>
</LinearLayout>
Explanation:
TextView: Provides the label for the group of checkboxes (e.g., "Choose your favorite
fruits").
CheckBoxes: The checkboxes are created for three options: Apple, Banana, and
Mango. You can change the text of each checkbox to match the options you want to
present to the user.
Button: A submit button that triggers the onSubmit() method when clicked.
In the Activity or Fragment (depending on where you're working), you can define the
onSubmit() method, which will get triggered when the user clicks the submit button.
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize the views
appleCheckBox = findViewById(R.id.appleCheckBox);
bananaCheckBox = findViewById(R.id.bananaCheckBox);
mangoCheckBox = findViewById(R.id.mangoCheckBox);
submitButton = findViewById(R.id.submitButton);
// Check the state of each checkbox and create a list of selected options
if (appleCheckBox.isChecked()) {
selectedFruits.append("Apple ");
if (bananaCheckBox.isChecked()) {
selectedFruits.append("Banana ");
if (mangoCheckBox.isChecked()) {
selectedFruits.append("Mango ");
selectedFruits.append("None");
Explanation:
1. Initialization: The checkboxes (appleCheckBox, bananaCheckBox, and
mangoCheckBox) and the submitButton are initialized in the onCreate() method using
findViewById().
2. onSubmit() Method:
o Toast Message: After collecting all the selected items, you can display the result
to the user using a Toast message or update a TextView.
To add a ToggleButton in your layout, you can define it in the XML layout file like this:
xml
Copy code
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enable Feature"
android:textSize="18sp"
android:layout_marginBottom="16dp"/>
<!-- ToggleButton for enabling/disabling a feature -->
<ToggleButton
android:id="@+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOff="OFF"
android:textOn="ON"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:onClick="onSubmit"/>
</LinearLayout>
Explanation:
ToggleButton:
o You can customize the button's appearance, including the textOn and textOff
attributes.
java
Copy code
public class MainActivity extends AppCompatActivity {
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toggleButton = findViewById(R.id.toggleButton);
submitButton = findViewById(R.id.submitButton);
toggleButton.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener() {
@Override
if (isChecked) {
} else {
});
Initialization:
OnCheckedChangeListener:
o Based on the state, you can perform actions like displaying a Toast message
(e.g., "Feature Enabled" or "Feature Disabled").
onSubmit() Method:
o The onSubmit() method is triggered when the submit button is clicked. It checks
the state of the ToggleButton using toggleButton.isChecked(), which returns true
if the button is ON and false if it’s OFF.
Conclusion
XML Layout: Use the <ToggleButton> element in the layout file and define textOn and
textOff attributes.
Submit Action: Use the isChecked() method in the onSubmit() method to determine
the toggle state when a user submits the form.
Explain how to create Text Input? List out the Attributes for
customizing Textview. Write down the steps for getting the
user's input.
Creating Text Input in Android
In Android, text input is typically done using EditText views. EditText is a type of TextView
that allows users to enter and modify text. It is commonly used for forms, login screens, or
anywhere user input is required.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginBottom="8dp"/>
<EditText
android:id="@+id/editTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name"
android:inputType="text"
android:maxLength="50"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:onClick="onSubmit"/>
</LinearLayout>
Explanation:
TextView: Displays a label above the EditText to prompt the user for input (e.g., "Enter
your name").
EditText:
o android:inputType="text": Specifies that the input type is plain text. You can
customize it to accept different input types like textPassword, number, etc.
Button: A button labeled "Submit" that triggers an action (e.g., collecting user input)
when clicked.
android:gravity: Defines the alignment of the text (e.g., center, left, right).
android:ellipsize: Specifies how the text should be truncated when it overflows (e.g.,
end, middle, marquee).
<EditText
android:id="@+id/editTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:textColor="#000000"
android:textSize="18sp"
android:maxLength="50"
android:padding="12dp"
android:background="@drawable/edit_text_background"
android:importantForAccessibility="yes" />
You first need to get a reference to the EditText in your Java/Kotlin code using the ID you
assigned in the XML layout file.
Java Code:
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextName = findViewById(R.id.editTextName);
submitButton = findViewById(R.id.submitButton);
submitButton.setOnClickListener(new View.OnClickListener() {
@Override
});
Explanation:
findViewById(): You use this method to get references to the EditText (editTextName)
and Button (submitButton) defined in your layout XML file.
Toast: A Toast message is used to display the input for the user. In a real app, you
would probably use the input to perform some action, like saving it to a database,
sending it to a server, etc.
4. Handling Validation and Input Check
Before proceeding with any action (such as submitting the input), it's a good practice to
validate the user's input (e.g., ensuring the field isn't empty).
if (userInput.isEmpty()) {
} else {
o The Options Menu is the primary menu used in Android apps. It is typically
displayed when the user presses the Menu button or in the app bar (toolbar).
2. Context Menu
o This menu provides context-specific options based on the item the user interacts
with.
o It can be used for actions like Delete, Share, or Edit for specific items in a list.
3. Popup Menu
o A Popup Menu is similar to the context menu but is displayed as a floating menu
that can appear anywhere on the screen. It is often triggered by a button or a
view.
o It’s typically used for a list of actions related to a specific item but not tied to
long-clicking on the item (unlike a Context Menu).
o Commonly used in overflow menus or buttons like three dots (⋮) or more
options.
4. Submenu
o For example, you could have a "Settings" option in the main menu, and inside it,
a "Display" submenu with various display-related settings.
The App Bar (or Toolbar) is a common UI component in Android that allows the user to
perform actions such as navigation, or other app-specific actions (like saving data or
refreshing). It also often includes the Options Menu (or Overflow Menu) as part of the app’s
action items.
First, you need to add a Toolbar widget to the app’s XML layout. The Toolbar can act as the
app’s app bar.
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:title="My App"
android:elevation="4dp"/>
In your Activity, you need to set the Toolbar as the Action Bar to enable it to display menus
and actions.
Java:
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
The Options Menu is an Android menu that provides a list of options/actions available in the
current screen. This is usually displayed when the user taps the overflow icon (three dots)
on the toolbar, or when the user presses the menu button on the device (if available).
1. Override onCreateOptionsMenu():
o You must override onCreateOptionsMenu() to define the menu items that should
appear in the options menu.
Java:
@Override
return true;
o Once the menu is inflated, you need to handle item clicks by overriding the
onOptionsItemSelected() method.
Java:
@Override
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.action_search:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Example of menu_main.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_settings"
android:title="Settings"
android:icon="@drawable/ic_settings"
android:showAsAction="ifRoom"/>
<item
android:id="@+id/action_search"
android:title="Search"
android:icon="@drawable/ic_search"
android:showAsAction="ifRoom"/>
</menu>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:title="My App"
android:elevation="4dp"/>
<!-- Other UI elements go here -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_settings"
android:title="Settings"
android:icon="@drawable/ic_settings"
android:showAsAction="ifRoom"/>
<item
android:id="@+id/action_search"
android:title="Search"
android:icon="@drawable/ic_search"
android:showAsAction="ifRoom"/>
</menu>
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
@Override
case R.id.action_settings:
return true;
case R.id.action_search:
return true;
default:
return super.onOptionsItemSelected(item);
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
ActivityInfo.SCREEN_ORIENTATION_USER
ActivityInfo.SCREEN_ORIENTATION_SENSOR
ActivityInfo.SCREEN_ORIENTATION_BEHIND
ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
The initial orientation of the Screen has to be defined in the AndroidManifest.xml file.
AndroidManifest.xml
<activity android:name="package_name.Your_ActivityName"
android:screenOrientation="orientation_type">
</activity>
Example:
android:screenOrientation="orientation_type">
Step-by-Step demonstration:
Creating the activities: There will be two activities and hence two XML files, one for
each activity.
1. activity_main.xml: XML file for first activity consist of constraint layout with
Button and Text View in it. This activity is in Landscape state.
2. activity_next.xml: XML file for second activity consist of constraint layout with
Text View in it. This activity is in Landscape state.
o activity_main.xml
o activity_next.xml
<!--Constraint Layout-->
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.geeksforgeeks.screenorientation.MainActivity">
android:id="@+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Next Activity"
android:layout_marginTop="100dp"
android:onClick="onClick"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintVertical_bias="0.613"
app:layout_constraintHorizontal_bias="0.612"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv1"
/>
<!--TextView -->
<TextView
android:text="Potrait orientation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="124dp"
android:textSize="25dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.502"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Creating the Java file: There will be two activities and hence two Java files, one for
each activity.
o NextActivity.java
package com.geeksforgeeks.screenorientation;
import android.support.v7.app.AppCompatActivity;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
Button button;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.b1);
Intent intent
= new Intent(
MainActivity.this,
NextActivity.class);
startActivity(intent);
o AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.geeksforgeeks.screenorientation">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="com.geeksforgeeks.screenorientation.MainActivity"
android:screenOrientation="portrait">
<intent-filter>
</intent-filter>
</activity>
<activity android:name=".NextActivity"
android:screenOrientation="landscape">
</activity>
</application>
</manifest>
Output:
1. Activity 1:
2. Activity 2:
Event Handlers − When an event happens and we have registered an event listener
for the event, the event listener calls the Event Handlers, which is the method that
actually handles the event.
Example: Toast class provides a simple popup message that is displayed on the current
activity UI screen (e.g. Main Activity).
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
Button btn;
@Override
setContentView(R.layout.activity_main);
btn.setOnClickListener(new View.OnClickListener() {
@Override
});
Output:
A well-designed mobile UI should be intuitive, visually appealing, and optimized for the
unique characteristics of mobile devices, including smaller screen sizes, touch-based
interactions, and varying device capabilities. It should prioritize simplicity, clarity, and ease of
use, ensuring that users can effortlessly navigate and accomplish their desired tasks.
This screen helps the new users to understand the app better.
Home Screen:
Home Screen is the main screen of any app. It is the screen that is opened when an
application is launched.
Login Screen:
Login screens are the pages that helps the users to create their account on the application.
Splash Screen:
Splash Screens are the screens that are displayed when any application is launched.
App Screen:
App Screens are all the screens of an application. They include showing information and
interacts with user.
The basic approach to TTS in Android is simple and involves initializing the TextToSpeech
engine and speaking text. The default settings provide a simple way to convert text into
speech.
Steps:
1. Initialize TextToSpeech.
Example Code:
import android.speech.tts.TextToSpeech;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.widget.Toast;
import java.util.Locale;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
if (status == TextToSpeech.SUCCESS) {
} else {
} else {
@Override
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
super.onDestroy();
Key Points:
Clean-up: It's important to call stop() and shutdown() to release resources in the
onDestroy() method.
Android allows developers to control the speech rate (how fast the speech is) and pitch
(how high or low the voice sounds) using the setSpeechRate() and setPitch() methods. These
settings help in making the speech sound more natural.
Steps:
Example Code:
setSpeechRate(): A value of 1.0f represents normal speed. Values lower than 1.0f
slow down the speech, while values greater than 1.0f make the speech faster.
setPitch(): A value of 1.0f represents the normal pitch. Values below 1.0f lower the
pitch, while values above 1.0f raise the pitch.
SSML is an XML-based language used to provide additional control over speech synthesis.
Android TTS engine supports SSML tags to adjust aspects like pauses, emphasis, and
pronunciation.
Example Code:
"</prosody>" +
"</speak>";
Explanation:
<prosody rate='slow' pitch='high'>: Slows down the speech and increases the
pitch.
SSML provides finer control over speech attributes, including pauses, speech rate,
pitch, emphasis, and more.
Android TTS supports multiple languages, and you can change the language dynamically. If
the device supports multiple languages, you can switch to the desired language (e.g., French,
Spanish) at runtime.
Steps:
Example Code:
Explanation:
If the language is not supported on the device, Android will return a language not
supported error.
In some cases, TTS may fail to initialize properly, particularly when the required language
data is missing or the device does not support TTS. It's essential to handle these failures
gracefully by checking for TextToSpeech.LANG_NOT_SUPPORTED or
TextToSpeech.LANG_MISSING_DATA.
Example Code:
@Override
if (status == TextToSpeech.SUCCESS) {
} else {
} else {
Explanation:
Sometimes you may need to introduce pauses or emphasize certain words for a more
natural-sounding speech. This can be done using SSML tags like <break> for pauses and
<emphasis> for emphasizing specific words.
Example Code:
"</speak>";
Explanation:
After using the TextToSpeech object, always clean up resources to prevent memory leaks.
This is done using stop() and shutdown() methods.
Example Code:
@Override
if (textToSpeech != null) {
super.onDestroy();
Below are the steps to implement Text-to-Speech (TTS) functionality in an Android mobile
app.
1. Add TTS Permission (if required)
2. Initialize TextToSpeech
Android provides a built-in TextToSpeech class that is responsible for converting text into
speech. You must initialize the TextToSpeech object before using it.
In the onCreate() method, initialize the TextToSpeech instance and set the listener to monitor
its initialization status.
Java:
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
if (status == TextToSpeech.SUCCESS) {
if (langResult == TextToSpeech.LANG_MISSING_DATA
|| langResult == TextToSpeech.LANG_NOT_SUPPORTED) {
} else {
// Initialization failed
});
Once the TextToSpeech object is initialized, you can use the speak() method to convert text
into speech.
null: These are for parameters like speech rate, pitch, and any additional settings you
might want to apply.
You can also modify the speech rate and pitch of the voice.
To adjust the speed (rate) and the tone (pitch) of the speech, use the following methods:
Speech Rate: The speed at which the text is spoken. A value of 1.0f is normal speed.
You can adjust it between 0.1f (slow) and 2.0f (fast).
Pitch: The pitch of the voice. A value of 1.0f is normal pitch. You can adjust it to make
the voice higher or lower.
After using the TextToSpeech service, you need to properly shut it down to release resources.
@Override
textToSpeech.stop();
textToSpeech.shutdown();
super.onDestroy();
This ensures that the TTS engine is properly shut down when the activity or app is destroyed.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
android:gravity="center">
<Button
android:id="@+id/btnSpeak"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Speak Text"/>
</LinearLayout>
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize TextToSpeech object
@Override
if (status == TextToSpeech.SUCCESS) {
} else {
} else {
});
btnSpeak = findViewById(R.id.btnSpeak);
btnSpeak.setOnClickListener(v -> {
});
@Override
if (textToSpeech != null) {
textToSpeech.stop();
textToSpeech.shutdown();
super.onDestroy();
In the context of mobile applications, synchronization and replication are two critical
techniques for ensuring data consistency and availability across different devices and
servers. These methods help apps maintain up-to-date data and ensure that the data
remains available even when users are offline or using multiple devices.
Here’s a detailed explanation of how synchronization and replication work in mobile apps,
along with the differences and the process of implementation:
Types of Synchronization:
One-way synchronization: Data flows in only one direction, from the device to the
server or vice versa. For example, syncing local changes to the server.
Synchronization Process:
1. Initial Data Fetch: When the app first starts, it may fetch data from the server to
populate the local database on the device. This process is known as initial
synchronization.
2. Data Change Detection: The app continuously tracks data changes. These could be
changes to local data (such as adding, updating, or deleting items) or changes that
occur remotely on the server.
3. Conflict Resolution: If there are conflicting changes (e.g., changes made both locally
and on the server), the system must resolve the conflict. This can be done using
several strategies:
o User input: The app asks the user to resolve the conflict.
4. Sync Process: After detecting changes, the mobile app sends or fetches data from the
server. The data can be transferred over the internet using APIs or web services (such
as RESTful APIs).
5. Network Management: Mobile apps must handle network changes (e.g., switching
between Wi-Fi and mobile data) and offline scenarios:
o Offline Mode: Data changes are stored locally and synchronized when the
network is available.
super(context, autoInitialize);
@Override
// Perform the data synchronization process here, e.g., pull data from the server
fetchDataFromServer();
In this example, the SyncAdapter is used to manage data synchronization in the background.
Types of Replication:
Master-Slave Replication: In this model, one server acts as the master, and other
servers (or devices) act as slaves. The master server holds the primary copy of the
data, and the slaves hold replicas. Data is replicated from the master to the slaves.
Peer-to-Peer Replication: Here, all devices or servers are treated as equals. Each
device can both send and receive data, allowing for decentralized replication.
Multi-Master Replication: In this model, multiple servers (or devices) can act as
masters and have the ability to read and write data. Changes made on one master
node are replicated to all others.
Replication Process:
1. Data Snapshot: A snapshot of the data is taken at a particular point in time. This
snapshot is replicated to other devices or servers.
2. Replication Mechanism: When data is updated on one device (or server), the change
is replicated to all other copies of the data. This could be done in real-time or
periodically, depending on the application requirements.
3. Conflict Management: Just like with synchronization, replication systems must handle
conflicts. This is typically done by using timestamps, version control, or user
intervention.
4. Data Consistency: Replication must ensure that all copies of the data are eventually
consistent. This means that, over time, all copies of the data should converge to the
same state, even if some copies were temporarily out-of-sync.
Example of Replication:
Consider a mobile application that replicates data between a local SQLite database and a
cloud server. Whenever a change occurs locally (such as adding a new contact), that change
is sent to the cloud, and the cloud server replicates the change to all other devices connected
to the same account.
For instance, if a user adds a new contact to their app while offline, the app will store the
data locally. Once the app goes online, it will send the change to the server, which will
replicate the new contact to other devices.
Data Conflicts: Handling conflicts when two devices or systems make different
changes to the same data at the same time. Proper conflict resolution strategies must
be implemented to ensure data consistency.
Scalability: Replication across multiple devices or servers can become complex as the
number of devices grows. Efficient algorithms are needed to handle large-scale data
replication.
Data Security: When replicating data across devices or servers, ensuring that data is
securely transferred and stored is critical, especially for sensitive data.
Latency: Replicating data in real-time across devices or servers can introduce latency.
Developers must balance consistency with performance, especially for mobile
applications where performance is crucial.
CloudKit (Apple): Apple’s CloudKit service offers data synchronization and replication
features for iOS devices, allowing seamless syncing between local storage and the
cloud.
SQLite Sync Adapter: In Android, using the SyncAdapter with an SQLite database
allows mobile apps to sync data with a remote server.
Unit 3
Intent Objects
An Intent object is created using the Intent class in Android. It specifies the action to be
performed, the data to operate on, and other optional parameters like categories, flags, and
extras (extra data). You can create an Intent in several ways, such as starting a new activity,
invoking services, or broadcasting information.
The basic syntax to create an Intent is:
Intent Fields
An Intent object typically has several fields, which define what actions or components the
intent will interact with. Here are the important fields associated with intents:
o Intent.ACTION_VIEW
o Intent.ACTION_SEND
o Intent.ACTION_MAIN
o Intent.ACTION_PICK
2. Data (URI): A URI (Uniform Resource Identifier) that provides the location of the data
to be used or operated on. For example, an intent to view a specific URL might use
http://www.example.com.
3. Category: Specifies the type of component that should handle the intent. Common
categories include:
o Intent.CATEGORY_DEFAULT
o Intent.CATEGORY_LAUNCHER
o Intent.CATEGORY_ALTERNATIVE
4. Extras: Additional data that is passed along with the intent. Extras are usually key-
value pairs (bundles) containing data like strings, numbers, and objects. The data is
stored in a Bundle.
intent.putExtra("key", value);
5. Flags: Flags provide additional instructions to the Android system about how to treat
the intent. Examples include:
7. Type: The MIME type of the data being passed with the intent, used mainly with implicit
intents to specify the data format (e.g., text/plain, image/jpeg).
Types of Intents
An explicit intent is used when you know the exact component (such as a specific activity
or service) that should handle the intent. You explicitly specify the target class of the
component.
Usage: Primarily used within an app to navigate between activities or start specific
services.
java
Copy code
startActivity(intent);
2. Implicit Intent
An implicit intent does not specify the exact component to handle the request. Instead, it
relies on the Android system to find a suitable component based on the action and data
specified. The system will search for all registered components that can handle the given
action.
Usage: Used when you want to perform a task but don’t know which specific
component should handle it (for example, opening a web page, sending an email, etc.).
startActivity(intent);
In this case, Android will find an appropriate app that can handle the ACTION_VIEW action
with the URL data.
Intent.ACTION_EDIT: Used to allow the user to edit data (like editing a contact).
Intent.ACTION_MAIN: The main entry point for an activity, often used to launch the app.
startActivity(intent);
startActivity(intent);
You can pass additional data with an intent using putExtra() to send key-value pairs.
startActivity(intent);
In the receiving activity, you can retrieve this extra data using getIntent().getStringExtra():
Flags in Intents
Flags control how activities are launched and how the back stack is handled.
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Conclusion
Intent: A messaging object used to request actions from other components (e.g.,
activities, services, and broadcast receivers).
Implicit Intent: Relies on the Android system to find a suitable component to handle
the request.
Understanding explicit and implicit intents, along with how to use actions, categories, and
data, is crucial for navigating and managing components within Android applications.
When sending an implicit intent, the action is specified, but no specific component is defined.
Android uses the action and data to find the most appropriate app that can perform the
requested task.
You need to create an Intent with an action (what you want to do, such as view or send) and,
optionally, data (what the intent is acting on, such as a URL or file).
Data: A URI representing the data (e.g., a URL, file path, or contact).
java
Copy code
startActivity(intent);
The Uri.parse() function is used to specify the data that is being acted upon (a URL in
this case).
java
Copy code
intent.putExtra("extra_key", "extra_value");
startActivity(intent);
Here, "extra_key" and "extra_value" represent additional data passed with the intent.
Once the intent is configured, you send it using the startActivity() method, which lets Android
decide which app or activity should handle the intent based on the action and data provided.
The receiving app (activity, service, or broadcast receiver) must be prepared to handle
implicit intents, which means the component must declare the necessary intent filters in the
AndroidManifest.xml file.
Category: Optional, used to refine what kind of component can handle the intent.
Data: Specifies the data (e.g., URI schemes, file types) that can be handled.
xml
Copy code
<activity android:name=".WebViewActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
This filter tells Android that WebViewActivity can handle VIEW actions with http URIs
that point to www.example.com.
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
// Perform action with the data (e.g., display in WebView or open browser)
if (data != null) {
The getIntent().getData() method retrieves the data passed with the intent, and you
can then act on it.
If there are multiple activities or apps that can handle the same implicit intent, Android will
display a chooser (e.g., a dialog asking the user which app they want to use). If your app is
one of the possibilities, the user can select it.
Let’s break it down into a practical example of sending and receiving a photo using an
implicit intent.
1. Sending an Implicit Intent to Pick a Photo (ACTION_PICK)
startActivityForResult(intent, PICK_IMAGE_REQUEST);
This implicit intent lets the user pick a photo from their gallery (handled by any app
that can access the gallery).
To handle the result of the image selection, override onActivityResult() to retrieve the
selected image URI.
java
Copy code
@Override
2. Data: Specifies the data for the action (e.g., a URI for a web page, a file path for an
image).
4. Chooser Dialog: If multiple apps can handle the same intent, Android shows a chooser
dialog to let the user select which app to use.
Summary
Sending Implicit Intents: Create an Intent with an action and data, then call
startActivity(). Android will search for a matching component.
Extras: You can also add extra data to the intent using putExtra() to pass additional
information along with the request.
This approach allows you to build flexible apps that can interact with other apps in a
seamless way, without knowing in advance which app will handle the action.
Broadcast Receivers allow apps to react to these broadcasts and perform corresponding
actions, such as showing notifications, updating UI elements, or even launching background
services.
Types of Broadcasts
1. Normal Broadcasts:
2. Ordered Broadcasts:
o Each receiver can either abort the broadcast or modify the broadcast’s data
before passing it to the next receiver.
1. Using a Java class: You can create a class that extends BroadcastReceiver and
override the onReceive() method to handle the broadcast.
2. Using an anonymous inner class: You can also define a broadcast receiver without
creating a separate class by using an anonymous inner class.
o Intent intent: The broadcast intent that contains information about the broadcast
event.
Example:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
@Override
In static registration, you define the BroadcastReceiver in the AndroidManifest.xml file. This
way, the receiver listens for specific system broadcasts even when the app is not running. It
is used for global events such as system shutdown, screen state changes, etc.
Steps:
2. Specify the action you want to listen for in the <intent-filter> tag.
Example (AndroidManifest.xml):
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
</intent-filter>
</receiver>
In this example, the receiver listens for two actions: when the device boots up
(BOOT_COMPLETED) and when the power is connected (ACTION_POWER_CONNECTED).
Steps:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create and register the receiver
@Override
};
filter.addAction("com.example.myapp.MY_CUSTOM_BROADCAST");
registerReceiver(myReceiver, filter);
@Override
super.onDestroy();
unregisterReceiver(myReceiver);
In this example, the app registers a receiver for a custom broadcast action
(com.example.myapp.MY_CUSTOM_BROADCAST). The receiver listens for this action while the
activity is active.
2. Sending a Broadcast
Once you have a broadcast receiver set up, you may want to send a broadcast that the
receiver can handle. You can send both normal broadcasts and ordered broadcasts.
Normal Broadcast
intent.setAction("com.example.myapp.MY_CUSTOM_BROADCAST");
sendBroadcast(intent);
Ordered Broadcast
You can send ordered broadcasts where receivers have the opportunity to modify the data or
abort the broadcast.
intent.setAction("com.example.myapp.ORDERED_BROADCAST");
sendOrderedBroadcast(intent, null);
Certain broadcasts require special permissions to listen for or send them. For instance, to
listen for the system broadcast BOOT_COMPLETED, your app must declare the
RECEIVE_BOOT_COMPLETED permission in the manifest:
Example (Manifest):
Once the onReceive() method finishes, the broadcast receiver is destroyed. Unlike
activities, broadcast receivers do not have a persistent lifecycle.
Conclusion
Dynamic Registration: Used in the app code for app-specific broadcasts or when you
want to register/unregister receivers at runtime.
By using Broadcast Receivers, Android apps can efficiently listen to and react to important
system or user-generated events.
How do you make an HTTP connection to connect to internet?
To make an HTTP connection to the internet in Android, you can use several different
methods. The most common approach is to use HttpURLConnection or higher-level libraries
like OkHttp or Retrofit. Here’s a detailed explanation of each method, starting with
HttpURLConnection.
HttpURLConnection is part of Android’s standard library, and it allows you to make HTTP
requests to the internet. Below are the steps to create an HTTP connection in Android:
Before making any HTTP connection, you must ensure that the app has the necessary
permissions to access the internet.
xml
Copy code
If you need to check for network connectivity (whether the device is connected to the
internet), you can also add:
xml
Copy code
Here’s a basic example of how to send an HTTP GET request using HttpURLConnection:
java
Copy code
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.IOException;
connection.setRequestMethod("GET");
// Set the connection timeout and read timeout (optional but recommended)
if (responseCode == HttpURLConnection.HTTP_OK) {
String inputLine;
response.append(inputLine);
in.close();
} else {
return response.toString();
}
In the above code, we create a URL object from a string URL and establish an
HttpURLConnection to it.
We then set the request method to "GET" (you can change it to "POST" for sending
data).
We check if the response code is HTTP_OK (200), meaning the request was successful,
and then read the response data.
You can use AsyncTask or Thread to handle the HTTP request in the background.
java
Copy code
import android.os.AsyncTask;
import android.widget.Toast;
import android.content.Context;
this.context = context;
@Override
try {
return client.makeHttpGetRequest(params[0]);
} catch (IOException e) {
e.printStackTrace();
return "Error: " + e.getMessage();
@Override
java
Copy code
new FetchDataTask(this).execute("https://api.example.com/data");
This way, the HTTP request is handled in the background thread, and the result is passed to
the main UI thread via onPostExecute().
OkHttp is a more modern, flexible, and efficient HTTP client that makes it easier to send HTTP
requests and handle responses. It is commonly used in Android apps for network operations.
To use OkHttp, you first need to add the library dependency in the build.gradle file:
gradle
Copy code
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.9.0")
java
Copy code
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpClientExample {
.url(urlString)
.build();
if (response.isSuccessful()) {
return response.body().string();
} else {
In this code, we use OkHttpClient to send a GET request to the specified URL. The Response
object contains the server's response, which you can handle (e.g., extract the body and
return it).
Retrofit is a powerful library for making HTTP requests in a more structured and object-
oriented way. It abstracts away much of the boilerplate code involved with making HTTP calls.
To use Retrofit, you need to add the dependencies in the build.gradle file:
gradle
Copy code
dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0")
java
Copy code
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.GET;
interface ApiService {
@GET("data")
Call<String> getData();
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
call.enqueue(new Callback<String>() {
@Override
if (response.isSuccessful()) {
System.out.println(responseData);
} else {
@Override
// Handle failure
t.printStackTrace();
});
Retrofit takes care of the network connection and response parsing, making it much
simpler to use than HttpURLConnection or OkHttp in many cases.
Conclusion
1. HttpURLConnection: A standard API for HTTP requests but requires more manual
handling of HTTP connections and responses.
2. OkHttp: A more modern and efficient HTTP client with built-in support for common
features like caching and retries.
3. Retrofit: A high-level library that simplifies working with HTTP APIs by abstracting the
process and automatically converting responses into Java objects.
Each method has its advantages, but OkHttp and Retrofit are highly recommended for their
ease of use and powerful features.
1. Foreground Services:
Services that notify the user about its ongoing operations are termed as Foreground Services.
Users can interact with the service by the notifications provided about the ongoing task. Such
as in downloading a file, the user can keep track of the progress in downloading and can also
pause and resume the process.
2. Background Services:
Background services do not require any user intervention. These services do not notify the
user about ongoing background tasks and users also cannot access them. The process like
schedule syncing of data or storing of data fall under this service.
3. Bound Services:
This type of android service allows the components of the application like activity to bound
themselves with it. Bound services perform their task as long as any application component
is bound to it. More than one component is allowed to bind themselves with a service at a
time. In order to bind an application component with a service bindService() method is
used.
In android, services have 2 possible paths to complete its life cycle namely Started and
Bounded .
By following this path, a service will initiate when an application component calls
the startService() method. Once initiated, the service can run continuously in the
background even if the component is destroyed which was responsible for the start of the
service. Two option are available to stop the execution of service:
2. Bounded Service:
In Android, services are used to perform background tasks. There are two types of services:
Started Services and Bound Services. Both types have different use cases and ways of
interaction with the application components. Below is a detailed explanation of how to
implement each type of service:
1. Started Service
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
@Override
super.onCreate();
// Initialize resources
@Override
@Override
try {
} catch (InterruptedException e) {
e.printStackTrace();
// Task completed
}).start();
return START_STICKY; // Indicates that the service should be restarted if killed
@Override
super.onDestroy();
// Clean up resources
@Override
To start the service from an activity or any other component, you call startService() and
provide an Intent to the service:
startService(serviceIntent);
To stop the service manually, you can call stopService() or stopSelf() within the service itself
after the task is complete:
java
Copy code
Example Usage:
Use Case: A background task that plays music, downloads files, or processes data.
2. Bound Service
A Bound Service is a service that allows components (such as activities or other services) to
interact with it. It provides an interface for communication between the service and the
components that bind to it. A bound service only runs as long as at least one component is
bound to it.
It allows for two-way communication between the service and the component that
binds to it.
In a bound service, you need to override the onBind() method to return an IBinder object,
which will be used for communication between the service and the binding component.
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
@Override
super.onCreate();
@Override
@Override
super.onUnbind(intent);
return MyBoundService.this;
@Override
super.onDestroy();
As with a started service, you need to declare the service in the AndroidManifest.xml:
In the activity, use the bindService() method to bind to the service and access its methods
via the Binder object.
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.Bundle;
import android.widget.Toast;
MyBoundService myBoundService;
@Override
myBoundService = binder.getService();
isBound = true;
@Override
isBound = false;
};
@Override
super.onStart();
@Override
super.onStop();
unbindService(serviceConnection);
isBound = false;
Once bound, the client (activity) can call the public methods of the service directly,
which is enabled by the Binder object. In this case, we access the getService() method
from the LocalBinder.
Use Cases
Started Service: Use when you want to run a background task that doesn’t require
interaction with the activity (e.g., long-running operations like downloading a file or
processing data).
Bound Service: Use when you need to communicate between the service and the
activity or other components. For example, when the service provides real-time
updates, such as when retrieving data from a network or performing calculations.
Notifications could be of various formats and designs depending upon the developer. In
General, one must have witnessed these four types of notifications:
1. Status Bar Notification (appears in the same layout as the current time, and battery
percentage)
3. Heads-Up Notification (appears on the overlay screen, ex: WhatsApp notification, OTP
messages)
To create a new project in Android Studio please refer to How to Create/Start a New Project in
Android Studio. Note that select Kotlin as the programming language.
Go to the activity_main.xml file and refer to the following code. In this step, we are going to
design our layout page. Here, we will use the RelativeLayout to get the Scroll View from the
Kotlin file. Below is the code for the activity_main.xml file.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
</RelativeLayout>
Reference article: How to Create Constructor, Getter/Setter Methods and New Activity in
Android Studio using Shortcuts?
Name the activity as afterNotification. When someone clicks on the notification, this
activity will open up in our app that is the user will be redirected to this page. Below is the
code for the activity_after_notification.xml file.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".afterNotification">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Welcome To GeeksforGeeks"
android:textSize="15sp"
android:textStyle="bold" />
</RelativeLayout>
Note 1: Without configuring Notification Channels, you cannot build notification for
applications with Android API >=26. For them generating a notification channel is mandatory.
Apps with API<26 don’t need notification channels they just need notification builder. Each
channel is supposed to have a particular behavior that will be applicable to all the
notifications which are a part of it. Every channel will, therefore, have a Channel ID which
basically will act as a unique identifier for this Channel which will be useful if the user wants
to differentiate a particular notification channel. In contrast, the Notification builder provides
a convenient way to set the various fields of a Notification and generate content views using
the platform’s notification layout template but is not able to target a particular notification
channel.
Note 2: If you have referred any other documentation or any other blog before this one, you
might have noticed them appealing to implement the following
dependency“com.android.support:support-compat:28.0.0”. What I’ve personally
experienced is that there’s no need to implement it, things go far and good without this also.
Go to the MainActivity.kt file and refer to the following code. Below is the code for
the MainActivity.kt file. Comments are added inside the code to understand the code in
more detail.
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.RemoteViews
import androidx.appcompat.app.AppCompatActivity
// declaring variables
setContentView(R.layout.activity_main)
// accessing button
// This is how you tell the user that something has happened in the
// background.
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as
NotificationManager
btn.setOnClickListener {
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.enableVibration(false)
notificationManager.createNotificationChannel(notificationChannel)
.setContent(contentView)
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(this.resources,
R.drawable.ic_launcher_background))
.setContentIntent(pendingIntent)
} else {
builder = Notification.Builder(this)
.setContent(contentView)
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(this.resources,
R.drawable.ic_launcher_background))
.setContentIntent(pendingIntent)
notificationManager.notify(1234, builder.build())
With this, we have now successfully created a “Notification” for our application. Note that the
parameters listed in the above code are required and the absence of any single parameter
could result in crashing or not starting the application. The content title, content text, small
icon are customizable parameters but are mandatory also. One can change their values
according to the requirement.
Explain the Notification design guidelines.
Notification Design Guidelines in Android
Notifications are an essential part of the user experience in Android apps, allowing apps to
alert users about important events or updates. Android provides a flexible system for creating
and managing notifications. However, there are best practices and design guidelines to
ensure notifications are effective, non-intrusive, and align with Android's UX standards.
1. Notification Types
There are different types of notifications you can create in Android, each suited to different
purposes. Understanding these types helps you decide the most appropriate format for your
app’s notification.
Types of Notifications:
Standard Notifications: These are simple notifications with a title, text, and icon.
They can include additional elements like images or action buttons.
Heads-Up Notifications: These notifications pop up at the top of the screen to grab
attention, typically used for high-priority notifications.
Custom Notifications: These allow for the design of notifications that break the
standard format and include custom layouts or media (e.g., large images, rich text).
Introduced in Android 8.0 (API level 26), Notification Channels allow users to control the
types of notifications they want to receive, giving them more granular control over their
notifications.
Importance: Each channel has an importance level that determines how the
notification is displayed (e.g., sound, vibration, or silent).
java
Copy code
channel.setDescription(description);
notificationManager.createNotificationChannel(channel);
Best Practice: Always create a notification channel for apps targeting Android 8.0 and
above, as notifications will not be displayed without one.
Android provides flexibility in how notifications are structured. The layout of a notification
should be simple, intuitive, and consistent with your app's theme and design language.
Title and Text: Clear, concise titles and descriptive text to inform users.
Icon: A small icon representing your app or the event. It should be recognizable and
simple.
o Low Priority: Appears in the notification tray and may be silently delivered.
Actions: Include buttons for performing actions directly from the notification (e.g.,
Reply, Like, Delete). Keep the number of actions minimal to avoid clutter.
java
Copy code
.build();
Media Style: For media-related notifications (e.g., music playback), use the
MediaStyle to display playback controls (play, pause, skip).
java
Copy code
.setShowActionsInCompactView(0, 1, 2);
Custom Layouts: Use RemoteViews for custom layouts when you want to display
complex or rich content. Custom layouts can contain images, additional text, or buttons
beyond the default styles.
Example of BigPictureStyle:
java
Copy code
.setBigContentTitle("Title")
.setSummaryText("Summary");
Example of BigTextStyle:
java
Copy code
Rate Limit Notifications: Avoid bombarding users with too many notifications at
once. Grouping notifications and limiting their frequency will improve user experience.
Example of Grouping:
java
Copy code
.setContentTitle("New Messages")
.setGroup("message_group")
.setGroupSummary(true)
.build();
Ensure notifications are visible when necessary but not overly intrusive. For example,
use low priority for less important notifications (e.g., updates from an app that is not
critical).
Avoid Overuse of Sound and Vibration: Use sounds and vibrations sparingly.
Consider silent notifications or use custom sound profiles for different notification
types.
Provide useful actions that allow users to interact with notifications directly. This eliminates
the need to open the app and improves efficiency.
Reply: For messaging apps, include a "Reply" button, allowing the user to respond
directly from the notification.
Like or Thumbs Up: For social apps, enable quick actions such as "Like" or "Share"
buttons.
java
Copy code
.build();
Pending Intent:
Action buttons trigger PendingIntent, which allows your app to execute code (such as
opening an activity, starting a service, or sending data) when the user interacts with the
notification.
Notifications should provide clear, relevant, and timely information. Overuse of notifications
can result in user fatigue and uninstallation of the app. Follow these practices:
Use Quiet Time: If the user hasn’t interacted with the app in a while, avoid
overwhelming them with constant notifications.
Opt-in for Notifications: Allow users to opt in or opt out of notifications in the app
settings (via notification channels or in-app settings).
8. User-Centric Design
Contextual Design: Notifications should fit the context and purpose of the app. For
example, music apps should prioritize media controls, while productivity apps can focus
on reminders.
Rich Media Support: If your app uses multimedia, leverage rich media content like
images, audio, or video for a more engaging experience.
Consistency: Follow material design principles for consistency in design (e.g., spacing,
font sizes, button placements).
Conclusion
Key Takeaways:
Use media styles, expandable content, and custom layouts for rich notifications.
Don't overwhelm users with excessive notifications; be mindful of timing and frequency.
By following these guidelines, you can create notifications that are functional, informative,
and user-friendly.
With the introduction of Notification Channels in Android 8.0 (API level 26), Android allows
developers to assign a priority level to notifications. These priorities control the urgency of a
notification and how it behaves in the system.
Notification Priority Levels
Here are the different priority levels in Android, including how they affect the notification
behavior:
Purpose: High-priority notifications are meant to get the user's immediate attention.
Behavior:
o These notifications can make sound, vibrate, and visually interrupt the user.
o Typically used for urgent or important events (e.g., messages, alerts, incoming
calls, etc.).
o Alerting the user of critical events, such as system errors or app crashes.
Implementation:
.setContentTitle("Important Alert")
.setPriority(NotificationCompat.PRIORITY_HIGH)
Purpose: Medium-priority notifications are less urgent but still important for the user
to see. They do not demand immediate attention but should be visible.
Behavior:
o These notifications appear in the notification shade but will not interrupt the user
with a Heads-Up Notification.
o Can use sound and vibration, but may be muted by Do Not Disturb mode.
o Suitable for non-urgent notifications that provide value to the user but are not
time-critical.
o Notifications for new content (e.g., a social media post, a new email).
Implementation:
.setContentTitle("Update Available")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
Purpose: Low-priority notifications are typically used for information that is not
immediately necessary or crucial.
Behavior:
o These notifications appear in the notification shade, but they are silent, and they
do not make any sound or vibration.
o They are less intrusive and allow users to review them when they choose to.
Implementation:
.setContentTitle("Sync Complete")
.setPriority(NotificationCompat.PRIORITY_LOW)
Purpose: Min-priority notifications are used for notifications that are not critical and do
not need to be immediately visible to the user. These are generally background
notifications.
Behavior:
o These notifications are typically only shown in the notification drawer and do not
appear as a heads-up or visually interrupt the user.
o They will be silent and will not use sound or vibration by default.
Implementation:
.setContentTitle("Background Process")
.setPriority(NotificationCompat.PRIORITY_MIN)
When designing notifications, it’s important to choose the right priority based on the context
and urgency of the message:
High Priority: Use when the notification requires immediate user action or attention,
such as messages, reminders, or alerts related to the user’s well-being.
Medium Priority: Use for notifications that are important but do not need immediate
attention. These might be related to updates, new content, or reminders.
Low Priority: Use for notifications that don’t require immediate attention, like
background tasks or routine updates that the user can check later.
Min Priority: Use for background tasks or non-intrusive notifications that the user does
not need to see immediately.
Choosing the right priority helps ensure the notifications fit into the overall user experience
without being too disruptive or missing out on important alerts.
Do Not Disturb (DND) Mode: Users can enable Do Not Disturb mode, which silences
notifications based on their priority level. High-priority notifications can override DND
settings, while low-priority notifications will be silenced.
Consistency: Keep your notification behavior consistent across your app. For example,
use high-priority notifications only for critical events like messages or alarms, while
using lower priority for periodic updates.
It can fetch data asynchronously without blocking the main thread and it manages it's own
lifecycle during onDestroy() and configuration changes.
Loaders in Android is an abstract class implementation of Loader and two default classes,
which are provided by Android, I.E. AsyncTaskLoader, and cursor loaders.
There is only one Loader instance per activity/fragment and is created by Loader
managers. LoaderManager can manage multiple instances of Loaders.
The three arguments that will into init() and restartLoader() function are as follows:
LOADER_ID: Uniq ID given to Loader, if we are initializing Loader, will check if the
Loader ID is present or not. It will call on the callbacks method accordingly, which I wil
explain later.
2. LoaderManager.LoaderCallBacks:
OnLoadFinished(): Called after our data loading is finished. Basically we'll do all the user
interface binding and other things here.
OnLoaderReset(): Every time our Loader gets reset (either activity/ Fragment get
destroyed), we have to clear all the refereces from current Loader in this callback.
3. Loader:
Loader is the abstract class, which serves as a base class for all the Loaders. There are two
implementation given by Android:
CusorLoader: A Loader implementation used to get data from content providers through
content resolvers.
Loaders are primarily used for tasks such as loading data from a database, a network, or a
content provider. They handle lifecycle management automatically, which means they
survive configuration changes (like device rotation) and can handle data loading efficiently.
1. Starting a Loader
To start a loader, you need to call the getLoaderManager().initLoader() method. This method
initializes a loader and starts loading data asynchronously.
java
Copy code
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
if (id == LOADER_ID) {
YourContentProvider.CONTENT_URI,
null,
null,
null,
null);
return null;
}
@Override
@Override
In this example:
The loader is associated with a LoaderCallbacks interface that provides methods for
creating and receiving data from the loader.
2. Restarting a Loader
You might want to restart a loader in cases where the data needs to be reloaded. For
example, if the data source changes or the user requests to reload the data, you can restart
the loader.
1. Call restartLoader(): This is similar to calling initLoader(), but it forces the loader to
be reset and reloaded from scratch.
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
if (id == LOADER_ID) {
YourContentProvider.CONTENT_URI,
null,
null,
null,
null);
return null;
@Override
}
@Override
In this example:
The loader ID remains the same, but the loader will be reset, causing it to re-query the
data source.
Loader Lifecycle: When restarting a loader, it will go through the entire lifecycle of a
loader, including re-creating the loader and invoking the onLoadFinished() callback with
new data.
Data Reset: When restarting the loader, any previous data held by the loader (e.g., a
cursor or dataset) is reset, and fresh data will be loaded.
Efficiency: While restarting the loader can be useful in certain scenarios (e.g., user-
requested refresh or dynamic data changes), it should be done judiciously to avoid
unnecessary data loading and performance overhead.
3. Stopping a Loader
Although not directly related to starting or restarting a loader, it’s good to note that loaders
should also be stopped when they are no longer needed. This is done by calling:
java
Copy code
getLoaderManager().destroyLoader(LOADER_ID);
This ensures that any resources held by the loader (such as memory) are released when the
loader is no longer required.
Summary
Starting a Loader: Use initLoader() to start a loader for the first time or when it's not
previously initialized.
Restarting a Loader: Use restartLoader() to reset and reload the data from scratch.
This can be used when you need to refresh the data (e.g., after a data change or user
request).
These methods help manage background tasks efficiently, improve UI responsiveness, and
handle data loading in a manner that is consistent with the Android lifecycle.
Switch from the Code View to the Design View of the activity_main.xml File
For adding an image from Android Studio, Drag the ImageView widget to the
activity area of the application, a pop-up dialogue box will open choose from the
wide range of drawable resources and click “OK“.
For Adding an Image File other than Android Studio Drawable Resources:
Click on the “Resource Manager” tab on the leftmost panel and select the “Import
Drawables” option.
Select the path of the image file on your computer and click “OK“. After that set, the
“Qualifier type” and “value” of the image file according to your need and click “Next” then
“Import“.
Drag the ImageView class in the activity area, a pop-up dialogue box will appear which
contains your imported image file. Choose your image file and click “OK“, your image will be
added to the activity.
Note: After adding an image set its constraints layout both vertically and horizontally
otherwise it will show an error.
To create a new project in Android Studio please refer to How to Create/Start a New Project in
Android Studio. The code has been given in both Java and Kotlin Programming Language
for Android.
Go to the activity_main.xml File and refer to the following code. Below is the code for
the activity_main.xml File.
Navigate to the app > res > layout > activity_main.xml and add the below code to that
file. Below is the code for the activity_main.xml file.
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/GfG_full_logo"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.078"
app:srcCompat="@drawable/full_logo" />
<ImageView
android:id="@+id/GfG_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/GfG_full_logo"
app:srcCompat="@drawable/logo" />
</androidx.constraintlayout.widget.ConstraintLayout>
Note: All the attributes of the ImageView which are starting with app:layout_constraint are
the vertical and horizontal constraints to fix the image position in the activity. This is very
necessary to add the constraint to the ImageView otherwise, all the images will take the
position (0, 0) of the activity layout.
Go to the MainActivity file and refer to the following code. Below is the code for
the MainActivity file. Since in the activity, only 2 images have been added and nothing else
is being done like touching a button, etc. So, the MainActivity file will simply look like the
below code i.e. no change.
JavaKotlin
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
Output:
1. Tasks
2. Back Stack
Tasks
A task is a collection of activities that users interact with when performing a certain job. In
general an application contains number of activities. Normally when user launch an
application a new task will be created and the first activity instance is called root of the task.
When user launches an app from home icon, it navigates through different screens so
different activities placed on the top of one another. This collection of activities is known as
tasks.
Back Stack
Activities are arranged with the order in which each activity is opened. This maintained stack
called Back Stack. When you start a new activity using startActivity(), it “pushes” a new
activity onto your task, and put the previous Activity in the back stack.
Once you press back button then “pops” the top most activity and remove it from the back
stack and taking you back to the previous activity.
1. standard
2. singleTop
3. singleTask
4. singleInstance
In the AndroidManifest you can use “launchMode” attribute inside the <activity> element to
declare the activity’s launch mode like-
1. standard
This is the default launch mode of an activity (If not specified). It creates a new instance of an
activity in the task from which it was started. Multiple instances of the activity can be created
and multiple instances can be added to the same or different tasks. In other words you can
create the same activity multiple times in the same task as well as in different tasks.
Example:
Suppose you have A, B, C and D activities and your activity B has “launch mode = standard”.
Now you again launching activity B –
2. singleTop
In this launch mode if an instance of activity already exists at the top of the current task, a
new instance will not be created and Android system will route the intent information through
onNewIntent(). If an instance is not present on top of task then new instance will be created.
Using this launch mode you can create multiple instance of the same activity in the same
task or in different tasks only if the same instance does not already exist at the top of stack.
Example:
Case 1:
Suppose you have A, B and C activities and your activity D has “launch mode = singleTop”.
Now you launching activity D -
Case 2:
Suppose you have A, B, C and D activities and your activity D has “launch mode = singleTop”.
Now you again launching activity D -
A -> B -> C -> D (Here old instance gets called and intent data route through onNewIntent()
callback)
3. singleTask
In this launch mode a new task will always be created and a new instance will be pushed to
the task as the root one. If an instance of activity exists on the separate task, a new instance
will not be created and Android system routes the intent information through onNewIntent()
method. At a time only one instance of activity will exist.
Example:
Case 1:
Suppose you have A, B and C activities and your activity D has “launch mode = singleTask”.
Now you launching activity D -
A -> B -> C
Case 2:
Suppose you have A, B, C and D activities and your activity B has “launch mode =
singleTask”. Now you again launching activity B-
A -> B (Here old instance gets called and intent data route through onNewIntent() callback)
4. singleInstance
This is very special launch mode and only used in the applications that has only one activity.
It is similar to singleTask except that no other activities will be created in the same task. Any
other activity started from here will create in a new task.
<activity android:launchMode=”singleInstance” />
Example:
Case 1:
Suppose you have A, B and C activities and your activity D has “launch mode =
singleInstance”. Now you launching activity D -
A -> B -> C
Now if you continue this and start E and D then Stack will look like-
Task2 — D
Case 2:
Suppose you have A, B, C activities in one task and activity D is in another task with “launch
mode = singleInstance”. Now you again launching activity D-
Task2 — D
Task2 — D (Here old instance gets called and intent data route through onNewIntent()
callback)
Intent Flags
Android also provides Activity flags by which you can change the default behavior of Activity
association with Tasks while starting it via startActivity() method. These flags values can be
pass through Intent extra data.
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TASK
This flag will cause any existing task that would be associated with the activity to be cleared
before the activity is started. The activity becomes the new root of an otherwise empty task,
and any old activities are finished.
FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_CLEAR_TOP
If set, and the activity being launched is already running in the current task, then instead of
launching a new instance of that activity, all of the other activities on top of it will be closed
and this Intent will be delivered to the (now on top) old activity as a new Intent.
1. Activities
Activities are said to be the presentation layer of our applications. The UI of our application is
built around one or more extensions of the Activity class. By using Fragments and Views,
activities set the layout and display the output and also respond to the user’s actions. An
activity is implemented as a subclass of class Activity.
JavaKotlin
Also, to fully understand how to structure an app with Kotlin, from basic components to
advanced architecture, the Android Mastery with Kotlin: Beginner to Advanced course
offers a comprehensive guide to Android app development.
2. Services
Services are like invisible workers of our app. These components run at the backend,
updating your data sources and Activities, triggering Notification, and also broadcast Intents.
They also perform some tasks when applications are not active. A service can be used as a
subclass of class Service:
JavaKotlin
3. Content Providers
It is used to manage and persist the application data also typically interacts with the SQL
database. They are also responsible for sharing the data beyond the application boundaries.
The Content Providers of a particular application can be configured to allow access from other
applications, and the Content Providers exposed by other applications can also be
configured.
A content provider should be a sub-class of the class ContentProvider.
JavaKotlin
To read more, refer to the article: Content Providers in Android with Example
4. Broadcast Receivers
They are known to be intent listeners as they enable your application to listen to the Intents
that satisfy the matching criteria specified by us. Broadcast Receivers make our application
react to any received Intent thereby making them perfect for creating event-driven
applications.
To read more, refer to the article: Broadcast Receiver in Android With Example
5. Intents
6. Widgets
These are the small visual application components that you can find on the home screen of
the devices. They are a special variation of Broadcast Receivers that allow us to create
dynamic, interactive application components for users to embed on their Home Screen.
7. Notifications
Notifications are the application alerts that are used to draw the user’s attention to some
particular app event without stealing focus or interrupting the current activity of the user.
They are generally used to grab user’s attention when the application is not visible or active,
particularly from within a Service or Broadcast Receiver. Examples: E-mail popups, Messenger
popups, etc.
Intent Filter
Implicit intent uses the intent filter to serve the user request.
The intent filter specifies the types of intents that an activity, service, or broadcast
receiver can respond.
XML
<intent-filter
android:icon="drawable resource"
android:label="string resource"
android:priority="integer" >
...
</intent-filter>
1. <action>,
2. <category> and
3. <data>.
1. <action>
Syntax:
ACTION_VIEW: Use this action in intent with startActivity() when you have some
information that activity can show to the user like showing an image in a gallery app or
an address to view in a map app
ACTION_SEND: You should use this in intent with startActivity() when you have some
data that the user can share through another app, such as an email app or social
sharing app.
2. <category>
Syntax:
Adds a category name to an intent filter. A string containing additional information about the
kind of component that should handle the intent.
3. <data>
Syntax:
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string" />
Adds a data specification to an intent filter. The specification can be just a data type, just a
URI, or both a data type and a URI.
Android provides several mechanisms for content sharing, including Intents and Content
Providers. These allow apps to securely exchange data between themselves or with the
user.
1. Intents:
o They can be used to share data between apps, such as sending a message,
sharing an image, or opening a website.
o Implicit Intents are commonly used for content sharing, where the system
chooses the appropriate app based on the content type and the available
applications installed on the device.
2. Content Providers:
o Content providers allow apps to share data (e.g., contacts, images, or files) by
exposing it through a standardized API.
o Content providers can be used for both reading and writing data to an app's
private database or for sharing data with other apps securely.
o Intents can be used for sharing different types of content between apps. For
example, you can send text, images, or files using implicit intents to target
specific apps like messaging, email, or social media apps.
o Sharing text: You can share a simple text message with other apps like
WhatsApp, SMS, or email.
o Sharing URLs: You can send a URL to a browser or a social media app.
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
This creates an implicit intent that will allow the user to choose an app (e.g., WhatsApp,
Email, etc.) to send the text to.
2. Sharing Files
o You can share files using intents. Files can be shared via Content URIs to avoid
sharing raw file paths, which may not be accessible by all apps. Android provides
the ContentProvider interface for this purpose.
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
o Examples: Android provides default content providers for handling common data
types like contacts (ContactsProvider), media (e.g., MediaStore for images and
audio), or calendar events.
if (cursor != null) {
while (cursor.moveToNext()) {
String contactName =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
cursor.close();
The ContentResolver allows apps to interact with other apps' content providers securely. For
example, you can query another app's data (like contacts or calendar events) or insert data
into a shared content provider.
o It integrates with the ActionBar or Toolbar to present a sharing option for users
to send data via intents.
ShareActionProvider mShareActionProvider;
shareIntent.setType("text/plain");
mShareActionProvider.setShareIntent(shareIntent);
Threads in Android are typically used to offload tasks from the main thread to avoid freezing
the UI. However, they are part of the same application process and share the same memory
space. In Java and Kotlin, the Thread class and coroutines can be used to create and manage
threads.
JavaKotlin
});
thread.start();
Note: It’s recommended to use coroutines in Kotlin instead of Thread, as they are more
lightweight and easier to manage.
Code Snippet of a function that uses coroutines to perform a network request in the
background, and updates the UI with the result:
There are different types of threads in Android, each with its own use cases:
The main thread, also known as the UI thread, is responsible for handling all UI updates
and user interactions. Any code that updates the UI or interacts with the user should be
run on the main thread.
Worker threads are used for background tasks that should not block the main thread,
such as network requests, database operations, and image processing.
AsyncTask is a helper class that allows you to perform background tasks and update
the UI from the same thread. However, it has some limitations and it’s recommended to
use coroutines or other libraries for more complex tasks.
Services are used for tasks that should continue running even when the app is not
visible, such as playing music or downloading files.
In addition to the above, there are other types of threading mechanisms available in
android such as IntentService, JobIntentService, Service, JobScheduler, and
AlarmManager.
It’s important to choose the right threading mechanism for your task to ensure optimal
performance and avoid threading issues. It’s also important to test your app thoroughly on
different devices and configurations to ensure that it behaves correctly and does not crash
due to threading issues.
Step-by-Step Implementation
The code for that has been given in both Java and Kotlin Programming Language for
Android.
Next, go to the activity_main.xml file, which represents the UI of the project. Below is the
code for the activity_main.xml file. Comments are added inside the code to understand the
code in more detail.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/result_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp" />
<Button
android:id="@+id/start_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
</LinearLayout>
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultTextView = findViewById(R.id.result_text_view);
@Override
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
@Override
resultTextView.setText(result);
Output:
1. Content URI:
o Each Content Provider has a Content URI that specifies the location of the
data. The URI usually follows the format content://<authority>/<path>, where
<authority> is a unique identifier of the provider and <path> specifies the
specific dataset.
Example:
2. Content Resolver:
To access contacts from the system's Contacts Provider, you can use the ContentResolver
to query the ContactsContract content provider.
java
Copy code
contactsUri, // URI
null, // Projection (null means all columns)
null, // Selection
if (cursor != null) {
while (cursor.moveToNext()) {
String contactName =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
cursor.close();
The query() method is used to perform a query on the content provider. It returns a
Cursor object which contains the result set.
You can iterate through the Cursor and extract data using column indexes (e.g.,
ContactsContract.Contacts.DISPLAY_NAME).
You can use the ContentResolver to insert new data into a content provider.
java
Copy code
ContentValues is used to store key-value pairs that represent the data to be inserted.
The insert() method returns the URI of the newly inserted data.
Building a Content Provider involves creating a class that extends ContentProvider and
implementing its methods to handle data operations. Below are the steps involved in building
a Content Provider:
1. Create a Content Provider Class: The class must extend ContentProvider and
override essential methods such as onCreate(), query(), insert(), update(), and delete().
2. Define a URI: A URI is used to uniquely identify the content provider. It is used by
clients (other apps) to access the data.
4. Handle CRUD Operations: Implement logic to query, insert, update, and delete data.
This typically involves interacting with a database or some other data storage
mechanism.
@Override
return true;
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
@Override
SQLiteDatabase db = dbHelper.getWritableDatabase();
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
@Override
SQLiteDatabase db = dbHelper.getWritableDatabase();
@Override
return "vnd.android.cursor.dir/vnd.com.example.myapp.items";
2. Empty Results:
o In cases where data cannot be fetched due to lack of connectivity, the content
provider might return empty data, or a null or empty Cursor for a query
operation, indicating that no data was available from the network.
3. Error Handling:
o Fallback: If the content provider has a local cache (e.g., a database), it can fall
back to returning the cached data if the network is unavailable.
You can check for network availability before making a network request inside the
ContentProvider.
ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
You could use this method to ensure that network requests are only made when the network
is available, or you could implement an offline caching mechanism that allows the app to
continue functioning when the network is not available.
1. Property Animation
2. View Animation
3. Drawable Animation
Animations add a dynamic touch to Android apps, improving user experience. If you’re
looking to master animations and bring your Kotlin-based apps to life with advanced
techniques, the Android Mastery with Kotlin: Beginner to Advanced course offers in-depth
tutorials on creating engaging animations in Android
1. Property Animation
Property Animation is one of the robust frameworks which allows animation almost
everything. This is one of the powerful and flexible animations which was introduced in
Android 3.0. Property animation can be used to add any animation in
the CheckBox, RadioButtons, and widgets other than any view.
2. View Animation
View Animation can be used to add animation to a specific view to perform tweened
animation on views. Tweened animation calculates animation information such as size,
rotation, start point, and endpoint. These animations are slower and less flexible. An example
of View animation can be used if we want to expand a specific layout in that place we can use
View Animation. The example of View Animation can be seen in Expandable RecyclerView.
3. Drawable Animation
Drawable Animation is used if you want to animate one image over another. The simple way
to understand is to animate drawable is to load the series of drawable one after another to
create an animation. A simple example of drawable animation can be seen in many apps
Splash screen on apps logo animation.
Methods Description
startAnimation() This method will start the animation.
clearAnimation() This method will clear the animation running on a
specific view.
Example of Implementation Android Animation
Now we will see the Simple Example to add animations to ImageView. Note that we are going
to implement this project using the Java language.
To create a new project in Android Studio please refer to How to Create/Start a New Project in
Android Studio. Note that select Java as the programming language.
Strings.xml can be found from the app > res > values > strings.xml.
Below is the snippet for the strings.xml file.
<resources>
<string name="blink">BLINK</string>
<string name="clockwise">ROTATE</string>
<string name="fade">FADE</string>
<string name="move">MOVE</string>
<string name="slide">SLIDE</string>
<string name="zoom">ZOOM</string>
</resources>
Create ImageView in the activity_main.xml along with buttons that will add animation to
the view. Navigate to the app > res > layout > activity_main.xml.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageview"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:contentDescription="@string/app_name"
android:src="@drawable/gfgimage" />
<LinearLayout
android:id="@+id/linear1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/imageview"
android:layout_marginTop="30dp"
android:orientation="horizontal"
android:weightSum="3">
<Button
android:id="@+id/BTNblink"
style="@style/TextAppearance.AppCompat.Widget.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:padding="3dp"
android:text="@string/blink"
android:textColor="@color/white" />
<Button
android:id="@+id/BTNrotate"
style="@style/TextAppearance.AppCompat.Widget.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:padding="3dp"
android:text="@string/clockwise"
android:textColor="@color/white" />
<Button
android:id="@+id/BTNfade"
style="@style/TextAppearance.AppCompat.Widget.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:padding="3dp"
android:text="@string/fade"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:id="@+id/linear2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/linear1"
android:layout_marginTop="30dp"
android:orientation="horizontal"
android:weightSum="3">
<Button
android:id="@+id/BTNmove"
style="@style/TextAppearance.AppCompat.Widget.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:padding="3dp"
android:text="@string/move"
android:textColor="@color/white" />
<Button
android:id="@+id/BTNslide"
style="@style/TextAppearance.AppCompat.Widget.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:padding="3dp"
android:text="@string/slide"
android:textColor="@color/white" />
<Button
android:id="@+id/BTNzoom"
style="@style/TextAppearance.AppCompat.Widget.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:padding="3dp"
android:text="@string/zoom"
android:textColor="@color/white" />
</LinearLayout>
<Button
android:id="@+id/BTNstop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/linear2"
android:layout_marginLeft="30dp"
android:layout_marginTop="30dp"
android:layout_marginRight="30dp"
android:text="@string/stop_animation" />
</RelativeLayout>
To create new animations we have to create a new directory for storing all our animations.
Navigate to the app > res > Right-Click on res >> New >> Directory >> Name your
directory as “anim”. Inside this directory, we will create our animations. For creating a new
anim right click on the anim directory >> Animation Resource file and give the name to your
file. Below is the code snippet for 6 different animations.
1. Blink Animation
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="500"
android:repeatMode="reverse"
android:repeatCount="infinite"/>
</set>
2. Fade Animation
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<alpha
android:duration="1000"
android:fromAlpha="0"
android:toAlpha="1" />
<alpha
android:duration="1000"
android:fromAlpha="1"
android:startOffset="2000"
android:toAlpha="0" />
</set>
3. Move Animation
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:fillAfter="true">
<translate
android:fromXDelta="0%p"
android:toXDelta="75%p"
android:duration="700" />
</set>
4. Rotate Animation
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="6000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
<rotate
android:duration="6000"
android:fromDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="5000"
android:toDegrees="0" />
</set>
5. Slide Animation
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/linear_interpolator"
android:toXScale="1.0"
android:toYScale="0.0" />
</set>
6. Zoom Animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<scale
android:interpolator="@android:anim/linear_interpolator"
android:duration = "1000"
android:fromXScal = "1"
android:fromYScale = "1"
android:pivotX = "50%"
android:pivotY = "50%"
android:toXScale = "2"
android:toYScale = "2"/>
</set>
Add animation to the ImageView by clicking a specific Button. Navigate to the app > java >
your apps package name >> MainActivity.java.
MainActivity.javaMainActivity.kt
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageview);
blinkBTN = findViewById(R.id.BTNblink);
rotateBTN = findViewById(R.id.BTNrotate);
fadeBTN = findViewById(R.id.BTNfade);
moveBTN = findViewById(R.id.BTNmove);
slideBTN = findViewById(R.id.BTNslide);
zoomBTN = findViewById(R.id.BTNzoom);
stopBTN = findViewById(R.id.BTNstop);
blinkBTN.setOnClickListener(new View.OnClickListener() {
@Override
, R.anim.blink_animation);
imageView.startAnimation(animation);
});
@Override
, R.anim.rotate_animation);
imageView.startAnimation(animation);
});
fadeBTN.setOnClickListener(new View.OnClickListener() {
@Override
, R.anim.fade_animation);
imageView.startAnimation(animation);
});
moveBTN.setOnClickListener(new View.OnClickListener() {
@Override
, R.anim.move_animation);
imageView.startAnimation(animation);
});
slideBTN.setOnClickListener(new View.OnClickListener() {
@Override
, R.anim.slide_animation);
imageView.startAnimation(animation);
});
zoomBTN.setOnClickListener(new View.OnClickListener() {
@Override
, R.anim.zoom_animation);
imageView.startAnimation(animation);
});
// Set up click listener for stop button to clear any ongoing animation
stopBTN.setOnClickListener(new View.OnClickListener() {
@Override
imageView.clearAnimation();
});
Note: Drawables and strings can be found in the drawable folder and strings.xml file.
Drawables can be found from the app > res > drawable.
Output:
Discuss Wireless Communications in Modern Mobile
Technologies?
Wireless Communications in Modern Mobile Technologies
Wireless communication is a cornerstone of modern mobile technologies, enabling the
exchange of data between devices without the need for physical connections. Over the past
few decades, mobile wireless communication has evolved significantly, supporting higher
data speeds, lower latency, and greater connectivity. Today, wireless communications are
central to everyday activities, from mobile phone usage and internet access to IoT devices
and connected services. Below is a discussion on the various wireless communication
technologies in modern mobile systems.
Key Features:
Speed: Up to 64 kbps.
Key Features:
Key Features:
o High-speed internet with support for HD video streaming and mobile gaming.
o Improved data rates, reduced latency, and better efficiency compared to previous
generations.
o Wide adoption of smartphones and mobile applications.
Key Features:
o Network slicing, allowing the creation of virtual networks optimized for specific
uses (e.g., smart cities, IoT, autonomous vehicles).
o Massive IoT connectivity: Supports a wide array of IoT devices with ultra-low
power consumption.
Use Cases: AR/VR, smart cities, autonomous vehicles, real-time remote healthcare.
Key Features:
Key Features:
o Can connect mobile devices to the internet without using cellular data.
o Multiple versions of Wi-Fi, including Wi-Fi 5 (802.11ac) and Wi-Fi 6
(802.11ax), offering higher data rates and reduced latency.
2.2. Bluetooth
Key Features:
o Low energy consumption with the Bluetooth Low Energy (BLE) standard.
o Primarily used for device pairing and data transfer, such as for headphones,
wearables, and IoT devices.
o Newer versions like Bluetooth 5.0 provide enhanced range and data speed.
Use Cases: Wearables, wireless peripherals, IoT devices, and car connectivity.
Key Features:
o Enables quick and secure data transfer (e.g., contactless payments, file sharing,
and authentication).
Use Cases: Mobile payments (e.g., Google Pay, Apple Pay), ticketing, access control.
2.4. Zigbee
Technology: Zigbee is based on the IEEE 802.15.4 standard and is designed for low-
power, low-data-rate wireless communication.
Key Features:
The Internet of Things (IoT) revolution has ushered in a wave of innovation across industries,
from smart homes to industrial automation and healthcare. One of the key components
driving this revolution is the communication protocols that allow IoT devices (or nodes) to
share data and interact with each other or centralized systems (cloud, edge, or local
networks). As IoT applications evolve, so too do the communication protocols used, in terms
of both technology and standardization. Below are the most recent trends in communication
protocols for IoT nodes.
LPWAN protocols are gaining traction for IoT applications due to their ability to provide long-
range communication with minimal power consumption. These networks are particularly
useful for battery-powered IoT devices deployed in remote or rural areas.
o Trend: LoRaWAN has become a dominant protocol in IoT for long-range, low-
power communication, especially in smart agriculture, environmental monitoring,
and logistics.
o Key Features:
o Key Features:
o Use Cases: Smart cities, industrial IoT, smart grids, health monitoring.
Sigfox:
Bluetooth Low Energy (BLE) is one of the most widely used communication protocols for
short-range IoT applications due to its ultra-low power consumption. BLE is being enhanced
to meet the increasing demands of modern IoT use cases.
o Trend: Bluetooth 5.0, and its subsequent versions, offer enhanced speed, range,
and broadcast capacity.
o Key Features:
Zigbee and Thread are communication protocols based on the IEEE 802.15.4 standard,
offering low-power, reliable, and secure wireless communication.
Zigbee:
o Trend: Zigbee remains popular for home automation and industrial applications
because of its low power, mesh networking capabilities, and strong industry
support.
o Key Features:
Thread:
o Key Features:
o Use Cases: Home automation, smart lighting, smart appliances, and healthcare.
With the introduction of 5G, the evolution of communication protocols for IoT is taking a
massive leap forward. 5G promises ultra-fast data speeds, low latency, and the ability to
connect a massive number of devices simultaneously, making it ideal for demanding IoT
applications.
Recent 5G Trends:
Use Cases: Autonomous vehicles, smart cities, industrial IoT, real-time remote
monitoring.
IoT communication often involves the exchange of small amounts of data between devices.
To facilitate this, lightweight messaging protocols such as MQTT and CoAP have gained
popularity.
o Use Cases: Smart home, industrial IoT, agriculture, and remote monitoring
systems.
o Trend: CoAP is designed for simple, low-power devices that often operate in
constrained environments.
o Key Features:
o Use Cases: Smart grids, smart meters, environmental monitoring, and sensors in
resource-constrained environments.
Wi-Fi 6 and Wi-Fi HaLow are emerging trends in Wi-Fi communication that are optimized for
IoT devices.
Wi-Fi 6:
Key Features:
Wi-Fi HaLow:
Trend: Wi-Fi HaLow (802.11ah) is designed for low-power, long-range IoT devices.
Key Features:
o Optimized for low-power, long-range IoT devices, ideal for smart homes and
industrial IoT.
Conclusion
The communication protocols for IoT nodes continue to evolve to meet the increasing
demand for faster, more reliable, and more energy-efficient connectivity. Recent trends
indicate a shift towards:
Bluetooth 5.0 and Wi-Fi 6 offering faster, more efficient connections for personal and
home automation devices.
Lightweight messaging protocols like MQTT and CoAP, designed to handle small
amounts of data with low overhead in constrained environments.
These trends reflect the growing complexity of IoT systems, their need for diverse and
adaptive communication protocols, and the shift toward more scalable and energy-efficient
IoT networks. As IoT applications continue to expand, these protocols will play a critical role in
enabling a fully connected and intelligent world.
For an Earthquake Update Service that needs to fetch the latest earthquake data from a
remote server and update the UI, using an IntentService can significantly simplify the
implementation, as it automatically manages the worker thread and executes tasks
sequentially in the background.
The goal of the Earthquake Update Service is to periodically fetch earthquake data (e.g.,
from a REST API), process the information, and update the UI or notify the user of new
earthquake events. The IntentService can manage this background operation in a simplified
manner by handling all the tasks in the background without the need for complex threading.
This service will handle the task of fetching earthquake data from an API and processing it.
// Constructor - must call the super constructor with a name for the worker thread
public EarthquakeUpdateIntentService() {
super("EarthquakeUpdateIntentService");
@Override
updateUI(earthquakes);
return "{...}"; // This would be the JSON response from the API
updateIntent.putParcelableArrayListExtra("earthquake_list", new
ArrayList<>(earthquakes));
sendBroadcast(updateIntent);
startService(intent);
This will initiate the service, which will then start fetching earthquake data in the background.
After the data has been fetched and processed, you’ll likely need to notify the user. This can
be done in several ways, such as through:
@Override
}
}
EventBus: Using an event bus (like EventBus) to post events for easy communication
between the service and the UI.
LiveData: For modern apps using architecture components, LiveData or ViewModel can
be used to communicate with the UI.
registerReceiver(receiver, filter);
In real-world applications, network connectivity issues are common. You should handle these
gracefully by checking the network state before attempting to fetch data. If the device is
offline, you can show an error message or retry the operation later.
ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
if (!isNetworkAvailable()) {
return null; // Handle the lack of network, maybe return cached data or error message
Unit 4
o The app allows managers to assign tasks to field agents in real-time, optimizing
routes and schedules.
o Dispatchers can track job statuses and ensure that technicians reach their
appointments on time.
o Field workers can access detailed work orders, including customer information,
service history, and issue reports, directly on their Android device.
o Technicians can update the status of tasks (e.g., completed, in progress, delayed)
and log any issues encountered.
o It can track inventory levels and notify managers when items need to be
restocked.
o The app may include features for collecting customer feedback or signatures to
confirm service completion.
6. Offline Functionality:
o Many Android Field Service Apps are designed to work offline, allowing field
workers to continue their tasks even when there is no internet connection.
o The app integrates with mapping and GPS features to help technicians navigate
to their destinations efficiently.
o It can optimize travel routes, minimizing fuel costs and time spent on the road.
o Managers can track the progress of field agents and receive status updates.
o The app may include features for logging work hours, which helps in accurate
billing and payroll calculations.
o It can also generate invoices for services rendered, making billing more seamless
and faster.
Benefits:
Improved Efficiency: Automating task scheduling and route optimization saves time,
which leads to more jobs completed in a day.
Better Customer Experience: Timely updates and efficient service delivery increase
customer satisfaction.
Reduced Operational Costs: Optimized routes and efficient use of resources reduce
fuel consumption and unnecessary delays.
Data Accuracy: Real-time data entry ensures fewer errors and better reporting.
In summary, an Android Field Service App provides a centralized solution for businesses that
rely on mobile workers. By streamlining operations and improving efficiency, it allows
businesses to offer better service, optimize resources, and ultimately drive growth.
Explain about Mobile agents and peer-to-peer architecture
Mobile Agents in Mobile Computing
In Mobile Computing, Mobile Agents are the composition of computer software and data that
can autonomously move from one computer to another computer and continue its execution
on the destination computer.
In other words, you can say that An Mobile Agent is an autonomous program that is capable
of moving from host to host in a network and interact with resources and other agents. In this
process, the chance of data loss is scarce because the state of the running program is saved
and then transported to the new host. It allows the program to continue execution from
where it left off before migration. The most significant advantage of mobile agents is the
possibility of moving complex processing functions to the location where you have enormous
amounts of data and that have to be processed.
Mobile Agents are also called as transportable agents. They are classified into two types:
o Mobile Agents with pre-defined path: They have a static migration path.
o Mobile Agents with undefined path i.e., Roamer: They have dynamic migration
paths. The mobile agents choose their path according to the present network condition.
The mobile agents are autonomous with intelligence, social ability, learning, and the most
important feature is their mobility. They are independent in nature, self-driven and do not
require a corresponding node for communication. They can work efficiently even after the
user gets disconnected from the network.
1. Intelligence
Mobile Agents are capable of learning and searching for knowledge about their domain.
That's why they are called intelligent agents because they possess a degree of domain
knowledge. They can also transport their state from one environment to another without
disturbing the previous holding data and be capable of performing appropriately in the new
environment.
2. Autonomous
The Mobile Agents are Autonomous. It means the agents are not only motivated by the
outside actions initiated by the users or system but also they have internal events that
decided their performance and behavior. The mobile agents can also take an autonomous
decision while selecting a node.
3. Mobility
Mobile Agents contain some degree of mobility. The agent is not limited to its home node
only. They can migrate from one node to another and can carry out tasks along with them.
This feature distributes the processing and balancing of the load. Another benefit of this
capability is that when the user goes offline, the agents will still keep functioning.
4. Communicative
Mobile Agents can communicate effectively with other agents, users and systems. The mobile
agents use a communication language for inter-agent communication.
o They are capable of switching among the positions of one node to another.
The following are some advantages of mobile agents over conventional agents:
o They are Fault-tolerant. It means they are able to operate without an active connection
between client and server.
o They provide dynamic adaptation in which their actions are dependent on the state of
the host environment.
o The most significant disadvantage of mobile agents is their security. They are less
secured
o Mobile Agents are applied in a wide range of domains such as E-commerce, traffic
control, network management, robotics, data-intensive applications etc.
o They are also used in grid computing, parallel computing, distributed computing and
mobile computing etc.
What is a Peer-to-Peer (P2P) architecture?
Peer-to-peer (P2P) architecture is a distributed computing model where nodes in the network
behave as equals, communicating and sharing resources directly with each other. Unlike
client-server architectures that rely on centralized servers to facilitate communication and
resource sharing, P2P networks use the collective power of individual nodes to
achieve scalability, fault tolerance, and resilience.
Fault tolerance: P2P networks are resilient to node failure because the absence of a
central server means that the network can continue to function even if some nodes
become unavailable.
Resource sharing: P2P network participants can share files, data, and computing
resources directly with each other.
Autonomy: Each node in a P2P network has autonomy over its own resources and
decisions, which contributes to the overall resilience and flexibility of the network.
Also known as decentralized or true P2P networks, pure P2P networks operate without any
central authority or dedicated infrastructure.
Peers in these networks have equal privileges and responsibilities, and they directly
communicate and share resources with each other.
Hybrid P2P networks combine elements of both decentralized and centralized architectures.
They typically include some central servers or super peers that coordinate network
activities, manage resources, or provide additional services.
Hybrid P2P networks aim to achieve a balance between decentralization and efficiency.
Examples include Skype and eDonkey.
Overlay P2P networks create a virtual network on top of an existing infrastructure, such as
the internet.
Peers in these networks establish direct connections with each other, forming an
overlay structure that facilitates resource sharing and communication.
Overlay P2P networks often employ distributed hash tables (DHTs) or other routing
mechanisms to locate and retrieve resources efficiently. Examples include Chord and
Kademlia.
4. Structured P2P Networks
Structured P2P networks organize peers into a specific topology or structure, such as a ring,
tree, or mesh.
Peers maintain routing tables or other data structures to facilitate efficient resource
lookup and data retrieval.
Structured P2P networks offer predictable performance and scalability but may require
additional overhead for maintenance. Examples include CAN (Content Addressable
Network) and Pastry.
In contrast to structured P2P networks, unstructured P2P networks do not impose any specific
topology or organization on peers.
Peers in these networks typically rely on flooding or random search algorithms to locate
resources, resulting in lower efficiency but greater flexibility and simplicity.
Peer Nodes: Individual participants in a P2P network, each acting as both a client and
a server.
Overlay Network: A virtual network topology that connects peer nodes and facilitates
communication and resource sharing.
The bootstrapping process in P2P networks involves discovering and initializing new nodes.
This typically includes mechanisms for node discovery, network configuration, and
connection protocols. Common bootstrap techniques include centralized bootstrap servers,
distributed hash tables (DHTs), and peer exchange protocols.
Data management in Peer-to-Peer (P2P) networks involves the storage, retrieval, replication,
and consistency maintenance of data distributed across multiple peers.
Decentralized Storage:
Data Retrieval:
o Peers in a P2P network need to locate specific data items dispersed across other
peers.
Replication:
o To improve data availability and fault tolerance, shared data is often replicated
across multiple peers.
o Replication ensures that even if some peers become unavailable, the data
remains accessible from other replicas.
Consistency Management:
Routing algorithms in P2P networks determine how data packets are routed between nodes.
Common routing algorithms include flooding, random walks, and greedy routing. The goal of
these algorithms is to balance efficiency, scalability, and resilience in decentralized networks.
Flooding:
o This simple algorithm involves a peer forwarding a query to all its neighbors.
Each neighbor repeats this process until the query reaches its destination or
expires.
Random Walks:
o Peers select random neighbors to forward queries, repeating this process until
the target is found.
o Random walks are decentralized but may be inefficient for large networks and
can take longer to locate resources.
o DHTs are structured routing algorithms that use a distributed hash table to map
keys to peers responsible for storing corresponding data.
o Examples include Chord, Kademlia, and Pastry. DHTs organize peers into a
structured overlay network, providing efficient and scalable routing with
logarithmic time complexity for resource location.
Small-World Networks:
o These algorithms combine local and global knowledge to efficiently route queries
in a decentralized manner.
Cost Reduction: P2P networks can significantly reduce costs associated with
infrastructure, maintenance, and bandwidth, as they rely on resources contributed by
peers rather than centralized servers.
Scalability: P2P networks face scalability challenges as they grow in size. Managing a
large number of peers and ensuring efficient communication between them becomes
increasingly complex.
Content Availability and Quality: The availability and quality of content can vary
widely in P2P networks due to factors like peer churn, network dynamics, and
heterogeneous resources. Maintaining consistent access to high-quality content across
the network poses a challenge.
Secure Hash Algorithms: Employ algorithms like SHA-256 to generate unique hash
values for data. These hashes act as digital fingerprints, verifying the integrity of
transmitted data and detecting any tampering.
Digital Signatures: Use digital signatures to validate the authenticity and integrity of
messages. Signatures, created with the sender's private key, can be decrypted with the
sender's public key to verify origin and ensure data integrity.
File sharing: Platforms like BitTorrent and eDonkey use P2P networks for efficient and
decentralized file sharing.
Distributed Computing: P2P computing platforms use distributed resources for tasks
such as scientific computing, data analysis, and cryptocurrency mining.
This page shows you how to use the SharedPreferences APIs to store and retrieve simple
values.
Caution: DataStore is a modern data storage solution that you should use instead
of SharedPreferences. It builds on Kotlin coroutines and Flow, and overcomes many of the
drawbacks of SharedPreferences.
The SharedPreferences APIs are for reading and writing key-value pairs, and you shouldn't
confuse them with the Preference APIs, which help you build a user interface for your app
settings (although they also use SharedPreferences to save the user's settings). For
information about the Preference APIs, see the Settings developer guide.
Get a handle to shared preferences
You can create a new shared preference file or access an existing one by calling one of these
methods:
getPreferences(): Use this from an Activity if you need to use only one shared
preference file for the activity. Because this retrieves a default shared preference file
that belongs to the activity, you don't need to supply a name.
For example, the following code accesses the shared preferences file that's identified by the
resource string R.string.preference_file_key and opens it using the private mode so the file is
accessible by only your app:
getString(R.string.preference_file_key), Context.MODE_PRIVATE)
When naming your shared preference files, you should use a name that's uniquely
identifiable to your app. A good way to do this is prefix the file name with your application ID.
For example: "com.example.myapp.PREFERENCE_FILE_KEY"
Alternatively, if you need just one shared preference file for your activity, you can use
the getPreferences() method:
Starting with Android 7.0 (API level 24), Android throws a SecurityException if you use
them. If your app needs to share private files with other apps, it may use a FileProvider with
the FLAG_GRANT_READ_URI_PERMISSION. For more information, also see Sharing Files.
If you're using the SharedPreferences API to save app settings, you should instead
use getDefaultSharedPreferences() to get the default shared preference file for your entire
app. For more information, see the Settings developer guide.
Pass the keys and values you want to write with methods such as: putInt() andputString().
Then call apply() or commit() to save the changes. For example:
with (sharedPref.edit()) {
putInt(getString(R.string.saved_high_score_key), newHighScore)
apply()
apply() changes the in-memory SharedPreferences object immediately but writes the updates
to disk asynchronously. Alternatively, you can use commit() to write the data to disk
synchronously. But because commit() is synchronous, you should avoid calling it from your
main thread because it could pause your UI rendering.
App-Specific storage: Store data files within internal volume directories or external.
These data files are meant only for the app’s use. It uses internal storage directories to
save sensitive information such as a username and password that other app should not
access.
Shared Storage: Store data files such as images, audio, video, documents, etc. that
the app may need to share with other apps.
Shared Preferences: Store primitive data type such as integer, float, boolean, string,
long in key-value pairs.
Developers are advised to use the options available to store data depending upon the space
required, reliable data access, and privacy of data. The data files saved over external
storage devices are publicly accessible on shared external storage using USB mass storage
transfer. Data files stored over external storage using a FileOutputStream object and can
be read using a FileInputStream object.
In order to avoid crashing the app first, we need to check storage SD Card is available for
reading and write operations. The method getExternalStorageState() is used to determine
the state of mounted storage media such as SD Card is missing, read-only or readable, and
writable. Below is the code snippet which we will use to check the availability of external
storage. If you’re developing an app that needs external storage and want to implement it
using Kotlin, the Android Mastery with Kotlin: Beginner to Advanced course guides
you through implementing storage features efficiently
if(Environment.MEDIA_MOUNTED.equals(state)) {
isAvailable= true;
isWritable= true;
isReadable= true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
isAvailable= true;
isWritable= false;
isReadable= true;
} else {
isAvailable = false;
isWritable= false;
isReadable= false;
getExternalFilesDir(String type): This method is used to store private data that are
specific to the app only. And data are removed as we uninstall the app.
Example
In this example, we would store text data into the external storage and fetch to see that data.
A sample GIF is given below to get an idea about what we are going to do in this article. Note
that we are going to implement this project using the Java language.
Step by Step Implementation
To create a new project in Android Studio please refer to How to Create/Start a New Project in
Android Studio. Note that select Java as the programming language.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
</activity>
</application>
</manifest>
Step 3: Before creating the layout and corresponding java files let’s add a few
string attributes which we are using in our layout files
Go to app > res > values > string.xml and insert the following code snippet
<resources>
...
</resources>
Now go to app > res > values > colors.xml and change the color attributes as following in
order to make App Bar more attractive.
<resources>
<color name="colorPrimary">#0F9D58</color>
<color name="colorPrimaryDark">#16E37F</color>
<color name="colorAccent">#03DAC5</color>
<color name="buttonColor">#0F9D58</color>
<color name="textColor">#FFFFFF</color>
</resources>
Again go to app > res > drawable and create a new Drawable Resource File and name it
as button_layout. In this, we are modifying our button style for a better UX/UI.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="25dp"
android:bottomRightRadius="25dp"
android:radius="50dp"
android:topLeftRadius="25dp"
android:topRightRadius="25dp" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
<size
android:width="64dp"
android:height="16dp" />
<solid android:color="@color/buttonColor" />
</shape>
Go to res > layout > activity_main.xml and write down the following code. In this layout
file, we are creating a multiline EditText View for getting the data from users and Buttons to
save that data over internal and external storage media.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/saveButton_public"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="@+id/editText_data"
android:layout_marginEnd="48dp"
android:layout_marginTop="8dp"
android:background="@drawable/button_layout"
android:onClick="savePublicly"
android:padding="8dp"
android:text="@string/save_button_public"
android:textAllCaps="false"
android:textColor="@color/textColor" />
<Button
android:id="@+id/saveButton_private"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/editText_data"
android:layout_marginStart="48dp"
android:layout_marginTop="8dp"
android:layout_toEndOf="@+id/saveButton_public"
android:background="@drawable/button_layout"
android:onClick="savePrivately"
android:padding="8dp"
android:text="@string/save_button_private"
android:textAllCaps="false"
android:textColor="@color/textColor" />
<Button
android:id="@+id/viewButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/saveButton_public"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:background="@drawable/button_layout"
android:onClick="viewInformation"
android:padding="8dp"
android:text="@string/view_button"
android:textAllCaps="false"
android:textColor="@color/textColor" />
<EditText
android:id="@+id/editText_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textView_data"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:autofillHints=""
android:hint="@string/edit_text_data"
android:inputType="textMultiLine" />
<TextView
android:id="@+id/textView_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:text="@string/text_view_data"
android:textAllCaps="true"
android:textStyle="bold" />
</RelativeLayout>
In MainActivity we define the functions that handled the onClick behavior of the buttons. And
fetch the data from the EditText and save it in external storage publicly and privately. We also
display a Toast message of the path where the data is stored.
import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
// After API 23 the permission request for accessing external storage is changed
// Before API 23 permission request is asked by the user during installation of app
EditText editText;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EXTERNAL_STORAGE_PERMISSION_CODE);
File folder =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
writeTextData(file, editTextData);
editText.setText("");
}
writeTextData(file, editTextData);
editText.setText("");
startActivity(intent);
// writeTextData() method save the data into the file in byte format
try {
fileOutputStream.write(data.getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
We will create a new activity and name it ViewInformationActivity. We use this activity to
display the saved data from the external storage. So, first, we create a layout for this activity
similar to the MainActivity layout. activity_view_information.xml layout code snippet:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ViewInformationActivity">
<Button
android:id="@+id/showButton_public"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="@+id/textView_get_saved_data"
android:layout_marginEnd="48dp"
android:layout_marginTop="8dp"
android:background="@drawable/button_layout"
android:onClick="showPublicData"
android:padding="8dp"
android:text="@string/show_button_public"
android:textAllCaps="false"
android:textColor="@color/textColor" />
<Button
android:id="@+id/showButton_private"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/textView_get_saved_data"
android:layout_marginStart="48dp"
android:layout_marginTop="8dp"
android:layout_toEndOf="@+id/showButton_public"
android:background="@drawable/button_layout"
android:onClick="showPrivateData"
android:padding="8dp"
android:text="@string/show_button_private"
android:textAllCaps="false"
android:textColor="@color/textColor" />
<Button
android:id="@+id/goBackButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/showButton_public"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:background="@drawable/button_layout"
android:onClick="back"
android:padding="8dp"
android:text="@string/back_button"
android:textAllCaps="false"
android:textColor="@color/textColor" />
<TextView
android:id="@+id/textView_get_saved_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textView_saved_data"
android:layout_marginTop="8dp"
android:gravity="center"
android:hint="@string/saved_information" />
<TextView
android:id="@+id/textView_saved_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="@string/text_view_saved_data"
android:textAllCaps="true"
android:textStyle="bold" />
</RelativeLayout>
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
TextView textView;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_information);
File folder =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
if (data != null) {
textView.setText(data);
} else {
if (data != null) {
textView.setText(data);
} else {
startActivity(intent);
try {
int i = -1;
buffer.append((char) i);
return buffer.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
In your res/layout/activity_main.xml, define the EditText fields for user input (like name and
email), a RadioButton for gender selection, and a Button to submit the form.
xml
Copy code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName" />
<EditText
android:id="@+id/etEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your email"
android:inputType="textEmailAddress" />
<RadioGroup
android:id="@+id/radioGroupGender"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/radioMale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Male" />
<RadioButton
android:id="@+id/radioFemale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Female" />
</RadioGroup>
<Button
android:id="@+id/btnSubmit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Register" />
</LinearLayout>
java
Copy code
package com.example.registrationform;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize UI components
etName = findViewById(R.id.etName);
etEmail = findViewById(R.id.etEmail);
radioGroupGender = findViewById(R.id.radioGroupGender);
radioMale = findViewById(R.id.radioMale);
radioFemale = findViewById(R.id.radioFemale);
btnSubmit = findViewById(R.id.btnSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
if (radioMale.isChecked()) {
gender = "Male";
} else if (radioFemale.isChecked()) {
gender = "Female";
editor.putString("name", name);
editor.putString("email", email);
editor.putString("gender", gender);
} else {
}
}
});
Explanation:
1. UI Components:
o Button: When clicked, the app collects all the values entered and stores them in
SharedPreferences.
2. SharedPreferences:
o We use SharedPreferences to store the data entered by the user (name, email,
gender). This data is saved persistently and can be retrieved even if the app is
closed and reopened.
4. Toast Message:
To retrieve the stored data from SharedPreferences, you can use the following code
(perhaps in another activity or for displaying the data):
This code fetches the values from SharedPreferences and displays them in a Toast
message.
Conclusion:
In this example, we created a simple Registration Form using EditText, RadioButton, and
SharedPreferences. The user inputs their details, and upon submitting the form, the data is
saved in SharedPreferences. You can later retrieve the saved data as needed.
Internal Storage:
o Location: Internal storage is a part of the device's built-in storage (e.g., the
phone's internal flash memory).
o Access: It is private to the app and can only be accessed by the app itself and
system processes. Other apps cannot access the data in internal storage unless
explicitly allowed.
o Usage: Used for storing sensitive app data (e.g., databases, preferences, and
application-specific files).
External Storage:
o Access: It is public and can be accessed by any app on the device, given that the
app has the necessary permissions.
o Usage: Used for storing user files (e.g., photos, music, and video) that need to be
shared with other apps or need larger storage.
Internal Storage:
o Security: Data stored in internal storage is private to the app. Other apps cannot
read the data unless they have the proper permissions.
o Encryption: Internal storage can be encrypted, making it more secure for storing
sensitive data.
External Storage:
o Security: Data on external storage is less secure. It can be accessed by any app
with the necessary permissions, and if the storage device is removed, the data is
exposed.
o Encryption: External storage is generally not encrypted by default, and the data
may be more susceptible to unauthorized access.
3. Storage Capacity
Internal Storage:
o Capacity: The size of internal storage is typically fixed and much smaller
compared to external storage. It's often used for system files, installed apps, and
app data.
o Limitations: When internal storage is full, the user cannot install more apps or
save additional data.
External Storage:
o Capacity: The capacity of external storage can vary based on the external
storage device (e.g., SD card), and it is typically larger than internal storage.
4. Performance
Internal Storage:
o Performance: Internal storage generally provides faster read and write speeds
compared to external storage because it is integrated into the device's hardware
(e.g., NAND flash memory).
o Use Case: Ideal for storing app data, system files, and caches, which need fast
access.
External Storage:
o Use Case: Best suited for media files (photos, music, videos), which don't require
high-speed access.
Internal Storage:
External Storage:
Internal Storage:
o Unmounting: It cannot be unmounted (it is always available for access while the
device is on).
External Storage:
o Unmounting: The user can unmount external storage (e.g., SD card) safely
through the device settings to avoid data corruption.
Internal Storage:
o Example:
java
Copy code
fos.write(data.getBytes());
fos.close();
External Storage:
o Used for media files like photos, videos, and audio, which need to be accessible
to the user and shared across apps.
o Example:
java
Copy code
fos.write(data.getBytes());
fos.close();
Internal Storage:
o Internal storage is always mounted and available as long as the device is on.
External Storage:
Summary Table:
External Storage is better for storing large files like images, videos, and audio that
need to be shared between apps and can be expanded with additional storage media
(e.g., SD cards). However, it is less secure and can be prone to performance and
durability issues.
One of the main benefits of using SQLite is that it is very easy to get started with. To
create a new database in SQLite, you simply need to create a new file on your
filesystem and connect to it using the SQLite3 API.
1. Create a Database Helper Class: This class will extend SQLiteOpenHelper and
manage database creation, version management, and upgrading.
2. Define the Database Schema: You will define the database structure (tables,
columns) in this class.
4. Performing CRUD Operations: You can insert, update, delete, and query data from
the database using SQLite queries or ContentValues.
First, create a class that extends SQLiteOpenHelper. This class will help in creating and
managing the database.
package com.example.mydatabaseapp;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
// Constructor
@Override
db.execSQL(CREATE_TABLE_USERS);
@Override
onCreate(db);
To perform operations on the database, you will need to create an instance of the
DatabaseHelper class and get a readable or writable database object.
For instance, inside an activity or service, you can open the database:
a. Insert Data
To insert data into the database, you will typically use SQLiteDatabase.insert() method or
ContentValues to insert key-value pairs.
values.put(DatabaseHelper.COLUMN_EMAIL, "[email protected]");
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (rowId != -1) {
b. Query Data
You can query data using SQLiteDatabase.query() or using raw SQL queries with
SQLiteDatabase.rawQuery().
SQLiteDatabase db = dbHelper.getReadableDatabase();
if (cursor != null) {
while (cursor.moveToNext()) {
String name =
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_NAME));
String email =
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_EMAIL));
cursor.close();
}
c. Update Data
values.put(DatabaseHelper.COLUMN_EMAIL, "[email protected]");
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (rowsUpdated > 0) {
d. Delete Data
SQLiteDatabase db = dbHelper.getWritableDatabase();
if (rowsDeleted > 0) {
Don't forget to close the database when you are done with it to avoid memory leaks:
Here is the complete example that demonstrates how to use SQLiteOpenHelper to manage
database connections and perform CRUD operations.
DatabaseHelper.java
package com.example.mydatabaseapp;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.content.ContentValues;
import android.database.Cursor;
@Override
db.execSQL(CREATE_TABLE_USERS);
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db);
values.put(COLUMN_NAME, name);
values.put(COLUMN_EMAIL, email);
SQLiteDatabase db = getWritableDatabase();
db.close();
SQLiteDatabase db = getReadableDatabase();
MainActivity.java
package com.example.mydatabaseapp;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
DatabaseHelper dbHelper;
TextView textView;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
btnAddUser.setOnClickListener(new View.OnClickListener() {
@Override
});
btnShowUsers.setOnClickListener(new View.OnClickListener() {
@Override
while (cursor.moveToNext()) {
String name =
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_NAME));
String email =
cursor.getString(cursor.getColumnIndex(DatabaseHelper.COLUMN_EMAIL));
textView.setText(stringBuilder.toString());
cursor.close();
}
});
Conclusion
You can perform various operations such as inserting, reading, updating, and
deleting data.
With this approach, you can easily integrate SQLite database operations in your Android app
for local data storage.
1. Create a Database Helper Class: This class will help you create and manage the
SQLite database.
2. Create Registration and Login Screens: UI to collect the user’s information and
authenticate the user.
3. Store User Data: Use SQLite to store user information during registration.
4. Authenticate Users: During login, authenticate the entered credentials against the
database.
First, we need to create a helper class to manage database creation and operations.
DatabaseHelper.java
java
Copy code
package com.example.loginregisterapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
@Override
db.execSQL(CREATE_TABLE_USERS);
@Override
onCreate(db);
SQLiteDatabase db = this.getWritableDatabase();
contentValues.put(COLUMN_USERNAME, username);
contentValues.put(COLUMN_PASSWORD, password);
db.close();
SQLiteDatabase db = this.getReadableDatabase();
cursor.close();
return exists;
2. Registration Activity
This activity will allow the user to register by entering a username and password, which will
be stored in the SQLite database.
RegisterActivity.java
java
Copy code
package com.example.loginregisterapp;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
Button registerButton;
DatabaseHelper dbHelper;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
usernameInput = findViewById(R.id.usernameInput);
passwordInput = findViewById(R.id.passwordInput);
registerButton = findViewById(R.id.registerButton);
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
if (username.isEmpty() || password.isEmpty()) {
} else {
if (isInserted) {
} else {
});
3. Login Activity
This activity will authenticate the user by checking their credentials against the database.
LoginActivity.java
java
Copy code
package com.example.loginregisterapp;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class LoginActivity extends AppCompatActivity {
DatabaseHelper dbHelper;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
usernameInput = findViewById(R.id.usernameInput);
passwordInput = findViewById(R.id.passwordInput);
loginButton = findViewById(R.id.loginButton);
registerButton = findViewById(R.id.registerButton);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
// Validate input
if (username.isEmpty() || password.isEmpty()) {
} else {
if (isUserValid) {
} else {
});
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
});
activity_login.xml
xml
Copy code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/usernameInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username" />
<EditText
android:id="@+id/passwordInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword" />
<Button
android:id="@+id/loginButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login" />
<Button
android:id="@+id/registerButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Register" />
</LinearLayout>
activity_register.xml
xml
Copy code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/usernameInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username" />
<EditText
android:id="@+id/passwordInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:inputType="textPassword" />
<Button
android:id="@+id/registerButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Register" />
</LinearLayout>
5. MainActivity (Optional)
You may create a MainActivity that will be launched after successful login. For simplicity, we
won’t dive into it here.
6. AndroidManifest.xml
xml
Copy code
Conclusion
1. Database Helper handles the creation, management, and operations (add, check) of
the SQLite database.
2. Registration stores the user data, while Login authenticates the user.
3. You can enhance this basic app with more features, such as password hashing,
validation checks, and UI improvements.
This simple app demonstrates SQLite-based login and registration functionalities in Android.
How to Store and Retrieve all contacts from the Table Using
Database Programmatically. Explain?
Covered above
Once a cursor has been returned from a database query, an app needs to iterate over the
result set and read the column data from the cursor. Internally, the cursor stores the rows of
data returned by the query along with a position that points to the current row of data in the
result set. When a cursor is returned from a query() method, its position points to the
spot before the first row of data. This means that before any rows of data can be read from
the cursor, the position must be moved to point to a valid row of data.
The Cursor class provides the following methods to manipulate its internal position:
boolean Cursor.moveToNext(): Moves the cursor to the next row relative to the current
position
Cursor.moveToPrevious(): Moves the cursor to the previous row relative to the current
position
Each move() method returns a boolean to indicate whether the operation was successful or
not. This flag is useful for iterating over the rows in a cursor.
Listing 5.10 shows the code to read data from a cursor containing all the data from
the people table.
SQLiteDatabase db = getDatabase();
"last_name",
"id"};
columns,
null,
null,
null,
null,
null);
while(cursor.moveToNext()) {
int index;
index = cursor.getColumnIndexOrThrow("first_name");
index = cursor.getColumnIndexOrThrow("last_name");
index = cursor.getColumnIndexOrThrow("id");
long id = cursor.getLong(index);
The code in Listing 5.10 uses a while loop to iterate over the rows in the cursor returned from
the query() method. This pattern is useful if the code performing the iteration “controls” the
cursor and has sole access to it. If other code can access the cursor (for example, if the
cursor is passed into a method as a parameter), the cursor should also be set to a known
position as the current position may not be the position ahead of the first row.
Once the cursor’s position is pointing to a valid row, the columns of the row can be read from
the cursor. To read the data, the code in Listing 5.10 uses two methods from the cursor
class: Cursor.getColumnIndexOrThrow() and one of the type get() methods from
the Cursor class.
Once the column index is known, it can be passed to one of the cursor’s get() methods to
return the typed data of the row. The get() methods return the data from the column in the
row which can then be used by the app. The Cursor class contains the following methods for
retrieving data from a row:
The internals of a cursor can contain a lot of resources such as all the data returned from the
query along with a connection to the database. Because of this, it is important to handle a
cursor appropriately and tell it to clean up when it is no longer in use to prevent memory
leaks. To perform the cleanup, the Cursor class contains the Cursor.close() method, which
needs to be called when an activity or fragment no longer needs the cursor.
In versions of Android before 3.0, cursor maintenance was left to developers. They either had
to handle the closing of the cursor themselves or had to make sure they informed an activity
that it was using a cursor so the activity would close the cursor at an appropriate time.
Android 3.0 introduced the loader framework that takes care of managing cursors for
activities/fragments. To support older versions of Android, the loader framework has also
been backported and added to the support library. When using the loader framework, apps
no longer need to worry about calling Cursor.close() or informing an activity/fragment of a
cursor that it needs to manage.
Content URI
content:// – Mandatory part of the URI as it represents that the given URI is a Content
URI.
authority – Signifies the name of the content provider like contacts, browser, etc. This
part must be unique for every content provider.
For a deeper understanding of how to implement Content Providers and other critical Android
components using Kotlin, consider enrolling in the Android Development with Kotlin
course . This course is designed to equip you with the skills necessary to build advanced
Android applications, leveraging Kotlin’s features to enhance your development process.
Following are the steps which are essential to follow in order to create a Content Provider:
Create a class in the same directory where the that MainActivity file resides and this
class must extend the ContentProvider base class.
Following are the six abstract methods and their description which are essential to
override as the part of ContenProvider class:
Abstract Description
Method
query() A method that accepts arguments and fetches the data
from the
desired table. Data is retired as a cursor object.
insert() To insert a new row in the database of the content
provider.
It returns the content URI of the inserted row.
update() This method is used to update the fields of an existing
row.
It returns the number of rows updated.
delete() This method is used to delete the existing rows.
It returns the number of rows deleted.
getType() This method returns the Multipurpose Internet Mail
Extension(MIME)
type of data to the given Content URI.
onCreate() As the content provider is created, the android system
calls
this method immediately to initialise the provider.
Example
The prime purpose of a content provider is to serve as a central repository of data where
users can store and can fetch the data. The access of this repository is given to other
applications also but in a safe manner in order to serve the different requirements of the
user. The following are the steps involved in implementing a content provider. In this content
provider, the user can store the name of persons and can fetch the stored data. Moreover,
another application can also access the stored data and can display the data.
<resources>
<string name="app_name">Content_Provider_In_Android</string>
</resources>
package com.example.contentprovidersinandroid;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import java.util.HashMap;
public MyContentProvider() {
static {
// of the table
@Override
switch (uriMatcher.match(uri)) {
case uriCode:
return "vnd.android.cursor.dir/users";
default:
@Override
db = dbHelper.getWritableDatabase();
if (db != null) {
return true;
return false;
}
@Override
qb.setTables(TABLE_NAME);
switch (uriMatcher.match(uri)) {
case uriCode:
qb.setProjectionMap(values);
break;
default:
sortOrder = id;
null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
@Override
if (rowID > 0) {
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
@Override
String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
break;
default:
getContext().getContentResolver().notifyChange(uri, null);
return count;
@Override
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
break;
default:
getContext().getContentResolver().notifyChange(uri, null);
return count;
// to perform query
// creating a database
// defining a constructor
DatabaseHelper(Context context) {
@Override
db.execSQL(CREATE_DB_TABLE);
@Override
One Textview , EditText field, two Buttons , and a Textview to display the stored
data will be added in the activity using the below code.
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#168BC34A"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.13"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="70dp"
android:fontFamily="@font/roboto"
android:text="@string/heading"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="@android:color/holo_green_dark"
android:textSize="36sp"
android:textStyle="bold" />
<EditText
android:id="@+id/textName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="40dp"
android:fontFamily="@font/roboto"
android:hint="@string/hintText" />
<Button
android:id="@+id/insertButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickAddDetails"
android:text="@string/insertButtontext"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<Button
android:id="@+id/loadButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickShowDetails"
android:text="@string/loadButtonText"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<TextView
android:id="@+id/res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:clickable="false"
android:ems="10"
android:fontFamily="@font/roboto"
android:textColor="@android:color/holo_green_dark"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/banner" />
</androidx.constraintlayout.widget.ConstraintLayout>
Button functionalities will be defined in this file. Moreover, the query to be performed while
inserting and fetching the data is mentioned here. Below is the complete code.
JavaKotlin
package com.example.contentprovidersinandroid;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
InputMethodManager imm =
(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
values.put(MyContentProvider.name, ((EditText)
findViewById(R.id.textName)).getText().toString());
getContentResolver().insert(MyContentProvider.CONTENT_URI, values);
// content URI
Cursor cursor =
getContentResolver().query(Uri.parse("content://com.demo.user.provider/users"), null, null,
null, null);
if(cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
strBuild.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+
cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
resultView.setText(strBuild);
else {
The AndroidManifest file must contain the content provider name, authorities, and
permissions which enable the content provider to be accessed by other applications.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.content_provider_in_android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="com.example.contentprovidersinandroid.MyContentProvider"
android:authorities="com.demo.user.provider"
android:enabled="true"
android:exported="true"></provider>
<activity android:name=".MainActivity">
<intent-filter>
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>
All the strings used in the activity are stored in this file.
<resources>
<string name="app_name">Accessing_Content_Provider</string>
</resources>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#168BC34A"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.13"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="70dp"
android:fontFamily="@font/roboto"
android:text="@string/heading"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="@android:color/holo_green_dark"
android:textSize="36sp"
android:textStyle="bold" />
<Button
android:id="@+id/loadButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickShowDetails"
android:text="@string/loadButtonText"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<TextView
android:id="@+id/res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:clickable="false"
android:ems="10"
android:fontFamily="@font/roboto"
android:textColor="@android:color/holo_green_dark"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/banner" />
</androidx.constraintlayout.widget.ConstraintLayout>
The ContentURI of the previous application is mentioned here and the same functions which
were used in the previous app to display the records will also be used here. Below is the
complete code:
JavaKotlin
package com.example.accessingcontentprovider;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// content URI
Cursor cursor =
getContentResolver().query(Uri.parse("content://com.demo.user.provider/users"), null, null,
null, null);
if(cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
strBuild.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+
cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
resultView.setText(strBuild);
else {
Video Player
Step 5: Modify the AndroidManifest.xml file
<queries>
<package android:name="com.example.contentprovidersinandroid"/>
</queries>
<application>
</application>
Before packaging your app, ensure it is ready for production and follows all necessary
guidelines for a smooth deployment.
Test Thoroughly: Ensure your app works well on various devices and screen sizes.
Test functionality, usability, and performance.
Remove Debugging Code: Ensure that debugging logs (e.g., Log.d() statements) and
any test code are removed from your app.
Optimize Your App: This involves optimizing the app's size and performance (e.g.,
optimizing images, using ProGuard to shrink code, etc.).
Check App Permissions: Verify that your app requests only the necessary
permissions and that they are clearly stated in the app's manifest.
Update the Version Number: Update the version code and version name in the
build.gradle file.
android {
defaultConfig {
You need to sign your app to prove its authenticity and ownership before you can submit it to
the Play Store. The APK or AAB file will be signed using a private key.
If you don't have a keystore file, you need to create one. You can do this using the keytool
command or through Android Studio.
3. Enter your key store path, key alias, and key password. These should be kept
secure.
4. After completing the required fields, Android Studio will create a keystore for
you.
Once you have the keystore, you can generate a signed APK or AAB.
In Android Studio:
3. Choose your keystore file and enter the credentials (password, alias).
Note: The App Bundle (.aab) format is preferred by Google as it is more efficient in terms of
size and optimization, and it supports the Play Store's dynamic delivery.
If you don’t already have a Google Developer account, you need to sign up. This involves:
Completing your account setup with required details (business info, tax info, etc.).
You’ll need to provide several details and assets for your app’s Play Store listing.
App Title: The name of your app (this will appear in the store).
Screenshots: At least 2-3 high-quality screenshots that show your app in action.
App Icon: A high-quality 512x512 px icon (in PNG format) for your app.
Video URL (optional): A YouTube video URL showing how your app works (optional
but recommended).
Privacy Policy URL: If your app uses sensitive data, you must provide a privacy policy
URL.
Now you can upload the signed APK or AAB file to the Google Play Console:
4. Go to the Release section (under the "Release Management" or "App Releases" tab).
5. Select the track you want to publish on: Production, Beta, or Alpha.
8. Review all details and make sure your app is ready for release.
Pricing: You can choose whether your app is Free or Paid. Note that once you set your
app to free, you can't change it to paid later.
Countries: Select the countries or regions where your app will be available.
Content Rating: Complete the questionnaire for content rating to ensure your app is
categorized correctly (e.g., E for everyone, T for teens).
Target Audience: Declare the target audience of your app (e.g., children, adults).
Privacy Policy: If your app collects sensitive information, you’ll need a privacy policy.
You must provide a link to it in the Play Store listing and your app’s settings page.
Once you’ve filled out all the necessary information and uploaded your APK/AAB, submit
your app for review. Google Play will perform an automatic review, which may take a few
hours to several days depending on the complexity of your app.
Google Play checks for compliance with their policies (e.g., app content, privacy
requirements, malware checks).
You will be notified by email once the review is complete, and your app will either be
approved or rejected.
9. Post-Launch Activities
After your app is approved and live on the Play Store, here are some post-launch activities:
Monitor Performance: Use Google Play Console to track app downloads, crashes,
reviews, and other performance metrics.
User Feedback: Regularly monitor and respond to user reviews, addressing any
concerns or feedback.
Updates: When you release updates, always update the version number, provide new
features, and improve the app based on user feedback. Re-submit the new APK/AAB for
review.
The Media Server creates the corresponding media service to the multimedia application. The
communication between the media server and Libmedia forms a client-server model. The PV
player processes the media data stream by demuxing the media data to separate the
video/audio data stream, decode video/audio data, sync video, and audio time, and send the
decoded data out.
The Android Multimedia framework is a set of APIs for developers which enables them to
create a multimedia application on an android platform. This framework provides support for
audio, video, and images, which provides a range of features such as media playback,
recording, editing, streaming, etc.
Looking to become an expert in Android App Development? Whether you're a student or a
professional aiming to advance your career in mobile app development, our course,
"Android App Development with Kotlin," available exclusively on GeeksforGeeks, is the
perfect fit for you.
1. Media Codec
It provides low-level access to hardware and software codecs for encoding and decoding
audio and video data. Format of media codec/format, container, and network protocol
supported by the android platform-
Container: It is used to store audio file format on a system, where data can be
manipulated to reduce the size or change the quality of audio.
Audio Format: Any format or codec can be used including the ones provided by android
devices. However, it is recommended to use the specified file formats as per devices.
Network Protocol: Protocols supported in audio and video playback are RTSP,
HTTP/HTTPS progressive streaming, and live streaming draft protocol.
H.264: Widely used video codec format that provides high-quality compression and is
supported by most modern devices and software.
AAC: Popular audio codec format that provides high-quality compression and is widely
supported by devices and software.
MP3: Well-known audio codec format that provides good compression and is supported
by most devices and software.
VP9: Video codec format that provides high-quality compression and is supported by
some modern devices and software.
JPEG: Image codec format that provides good compression and is widely supported by
devices and software.
PNG: Image codec format That provides lossless compression which is supported by
devices and software.
2. Media Player
It is a component in the multimedia framework that provides high-level access to the media
playback functionality of Android that enables developers to play audio/video files and
stream. It is also a core component of the Android multimedia framework that enables
developers to play audio and video files in their applications and provides a simple and
flexible API for playing media files from different sources. The sources are local files, network
streams, and content providers. Media player supports a wide range of audio and video
formats which includes MP3, AAC, WAV, MPEG-4, H.264, etc.
Playback control: This helps in controlling media files by providing a range of methods
such as start(), pause(), stop(), and seekTo().
Playback State: This feature informs the developer about the playback state by
providing functions that are onPrepared(), onCompletion(), and onError().
Audio Focus: This feature comes into the picture when multiple audio sources are
playing simultaneously and the developer has to manage all of it.
Media Streaming: The media player supports streaming media from various sources
such as HTTP, RTSP, and RTP so to handle the streaming media developers use
setDataSourse() method to set the source for streaming media and use the
prepareAsync() method to prepare the media player for asynchronous playback.
Media Playback with the surface: To set the surface on which the video should be
rendered setSurface() is used.
3. Media Recorder
Provides high-level access to the media recording functionality of Android which allows
developers to capture audio/video data from a device’s microphone and camera. It provides a
simple and flexible API for recording media from different sources such as the device’s
microphone or camera. Features of the media recorder are:
Recording control: This feature provides methods like start(), stop(), and reset() for
controlling the recording of media files.
Recording state: This feature enables the user to notify about the state of recording by
using methods onInfo() and onError().
Audio and Video Sources: This feature provides two methods setAudioSource and
setVideoSource() which enable developers to select appropriate audio and video
sources for their recordings.
Audio and Video Encoding: For video formatting, this feature contains methods such as
setOutputFormat() method. setAudioEncoder() and setVideoEncoder() methods are
used to select appropriate encoding for audio and video.
4. Surface View
The surface provides a facility to play video content on android devices. It is a subclass of the
view class and provides a dedicated drawing surface for applications that need to display
video or graphics which are more complicated than simple views. Feature of Surface View:
Efficient rendering: This is used when developers when designing efficient rendering is
needed and provides better performance compared to other View classes when
rendering large images or video frames.
Compatibility with Android Graphics Framework: It is compatible with OpenGL ES, which
is a 3D graphics library that can be used to create advanced multimedia applications.
5. Audio Manager
Controls the overall audio settings such as volume and routing. It allows developers to
manage audio settings and control audio playback for various applications and devices.
Functions of Audio Manager:
6. Image Reader
Provides access to raw image data from a device’s camera or image sensors. It is a part of
the android Camera2 API and is available in Android API level 19 and higher. Function that
ImageReader class include:
Android Agents:
In the context of Android development, Android agents generally refer to specialized
software or components that perform specific tasks on an Android device, often running in
the background or being used for monitoring, automation, or network communication
purposes. These agents can either be applications or services that perform tasks
autonomously on behalf of a user, a system, or a developer. Below are some key aspects of
Android agents:
Automation Agents: These agents are designed to automate tasks or perform certain
actions at specific times or based on conditions. For example, Tasker is an Android
automation tool that can act as an agent to automate actions like turning on Wi-Fi,
adjusting the volume, or sending messages based on user triggers.
Network Agents: These agents work in the background to handle network operations
such as synchronizing data with a server, updating content, or ensuring secure
connections. They are crucial in apps that require continuous data syncing or cloud-
based operations, like email clients, social media apps, and messaging apps.
Security Agents: These agents can monitor or enforce security policies on an Android
device. Examples of this are mobile device management (MDM) solutions, antivirus
agents, or privacy-focused apps that scan for threats, block malicious content, and
provide encryption services.
App Monitoring Agents: Some developers use agents to monitor app performance,
track crashes, log system events, or collect crash reports. Libraries like Firebase
Crashlytics or Bugfender provide agents that work seamlessly in the background to
collect critical crash data for analysis.
Android agents are commonly used in enterprise environments to enforce security policies
on Android devices. These include:
Antivirus and Anti-malware Agents: Android security agents are employed to scan
for viruses, malware, and potential threats. Security apps like Norton Mobile
Security, McAfee Mobile Security, and Avast Mobile Security act as agents that
regularly check for malicious activity and offer real-time protection.
Broadcast Receivers: Android agents often use broadcast receivers to listen for
system events like screen unlock, Wi-Fi connection, or charging status. For example, an
agent that changes phone settings based on location can listen for the device's location
change through broadcast receivers.
Job Scheduler: Some Android agents use the JobScheduler API or WorkManager to
schedule tasks that need to be performed periodically or under specific conditions. This
is particularly useful for tasks like syncing data or fetching updates.
Battery Optimizers: Apps like Greenify act as agents to automatically manage and
optimize battery usage by hibernating apps running in the background when not in use,
helping to extend battery life.
Security Monitoring: Apps like Cerberus act as a security agent to track and lock the
device if stolen, remotely wiping sensitive data or taking photos of the thief using the
front camera.
Geolocation Services: Apps such as Google Maps or Uber use location tracking
agents to determine the user's current position for providing location-based services,
without requiring the user to manually input location data.
Health and Fitness Apps: Google Fit or Samsung Health use agents to track
physical activity, sleep, and other health metrics by running background services that
use sensors such as accelerometers or GPS.
Efficiency: Android agents can help automate tasks, such as backing up data,
checking for updates, or adjusting settings based on conditions like location or battery
life.
User Convenience: These agents enable smooth and seamless background tasks
without requiring the user to interact with them directly. For example, background sync
ensures that data is always up to date.
Resource Management: By automating and offloading specific tasks, agents can help
optimize resource usage, such as saving battery or reducing network data usage.
Battery Drain: Some agents, especially those that track location, consume significant
battery power. Developers must ensure that agents are designed efficiently to avoid
excessive battery drain.
Privacy Concerns: Since some agents collect sensitive data (like location, usage
statistics, or personal information), it is crucial for developers to ensure that user data
is handled securely and in compliance with privacy regulations (like GDPR).
App Approval: Apps using agents for background tasks (especially if the tasks are
perceived as intrusive or data-collecting) might face approval issues on the Google Play
Store due to privacy and security concerns.
Use getLastKnownLocation(): If your app can tolerate some stale data, use
getLastKnownLocation() to retrieve the last available location. This reduces battery
consumption since it doesn't require continuous location tracking.
o GPS: High accuracy but heavy on battery usage and performance. Use for
precise navigation or location-based actions.
o Network: Uses Wi-Fi and cell towers, less accurate but more power-efficient.
Great for general location-based services when high precision isn't required.
FusedLocationProviderClient: This is a part of the Google Play Services API, which
offers more power-efficient location updates by intelligently switching between different
providers.
o High Accuracy: Use for navigation or critical tasks (GPS, high battery
consumption).
o Balanced Accuracy: Use for background tasks (e.g., using Wi-Fi and cell towers
for better battery efficiency).
o Low Power: Use when accuracy is not crucial (e.g., occasional updates,
background monitoring).
Use the setFastestInterval(): If your app only needs rapid location updates for a
short time (e.g., during a user’s activity), use setFastestInterval() to get updates faster
but still control the max interval for updates.
Background Location Restrictions: Android 10 (API level 29) and later require apps
to request the ACCESS_BACKGROUND_LOCATION permission to access location data
while the app is in the background. To comply with best practices:
o Provide clear use cases for accessing background location (especially in the app's
UI and privacy policy).
5. Use Geofencing
Always check for appropriate permissions before trying to access location data
(ACCESS_FINE_LOCATION for precise location and ACCESS_COARSE_LOCATION for
approximate location).
Be transparent with users about why you need their location and provide an easy way
to revoke the permissions.
Use BatteryOptimizations and Doze Mode: Make sure your app is optimized for
Android’s battery-saving features like Doze mode. Background tasks should be
designed to pause when the device is idle.
Use proximity alerts when you need to monitor whether the device enters a
region: These are a more efficient solution than continuous location tracking if your
use case revolves around detecting presence within a predefined area.
Test your app on a variety of devices and network conditions (e.g., weak GPS signals,
Wi-Fi, etc.). This helps in identifying performance bottlenecks and adapting to real-
world usage patterns.
Simulate poor GPS signals to test how your app behaves when location data is noisy or
unavailable.
Use Foreground Services: For apps that require location tracking while in the
background (such as fitness apps), use a foreground service with a notification. This
ensures that the system knows the app is actively using location data and can manage
resources accordingly.
1. Battery Consumption
2. Network Dependency
Weak GPS Signal: GPS location services can be inaccurate or unavailable in areas
with poor satellite visibility, such as indoors, under dense tree cover, or in urban
canyons with tall buildings. Users may experience poor location accuracy or delays in
getting updated coordinates.
Poor Network Connectivity: If the app relies on network-based location (such as cell
towers or Wi-Fi), weak or unavailable network signals will result in degraded accuracy
or no location updates. This is especially problematic in rural areas or places with
limited cellular/Wi-Fi coverage.
Latency: Network delays or high latency can result in delays in receiving updated
location information. This is particularly important for real-time applications like
navigation or ride-hailing apps.
3. Location Accuracy
Inaccurate GPS Coordinates: GPS can have varying degrees of accuracy depending
on the environment and the device. In areas with poor GPS reception, the accuracy can
degrade significantly, leading to erroneous location data.
Entry/Exit Delays: When using geofencing for detecting when a user enters or exits a
particular region, the system may have delays in detecting these events, especially in
areas with poor GPS or network connectivity. This can lead to missed or delayed
triggers for geofencing actions.
Location Data Privacy Concerns: Collecting and storing users’ location data raises
privacy concerns. Users may be hesitant to share their real-time location, and
mishandling this data could lead to security breaches or violate privacy laws (e.g.,
GDPR, CCPA). Apps must be transparent about location data collection and provide
adequate security measures.
Compliance with Privacy Laws: In many regions, there are strict regulations about
how location data can be used and stored (e.g., the EU’s General Data Protection
Regulation (GDPR), California Consumer Privacy Act (CCPA)). Developers need to ensure
compliance with these laws by implementing consent management systems and
transparent data usage policies.
Accuracy Expectations vs. Reality: Users may have expectations of perfect, real-
time location accuracy. However, due to environmental factors (e.g., GPS interference,
weather conditions, device limitations), the actual accuracy may not meet
expectations, leading to dissatisfaction.
Lack of Contextual Awareness: Apps may struggle to adapt to the user’s context.
For example, location updates may not consider whether the user is driving, walking, or
stationary, which may affect how the app responds to those updates.
Storing and Processing Location Data: Constantly tracking and storing location
data for every user can create storage and processing challenges, especially if the app
operates at scale. Handling large amounts of data can lead to increased database size
and more complex query and data processing operations, potentially slowing down the
app.
9. Device-Specific Variability
Differences in GPS Hardware: Different devices may have varying quality of GPS
hardware, leading to inconsistencies in location accuracy and update frequency across
devices. Older or budget devices may have less accurate GPS chips, which can affect
app performance.
OS and API Changes: Android updates can introduce changes to location APIs and
permissions, causing compatibility issues with existing apps. For instance, new
restrictions around background location access (introduced in Android 10 and later) can
break apps that previously accessed location in the background without additional
permissions.
App Fragmentation: Android devices run different versions of the operating system,
so apps need to ensure compatibility with a wide range of devices, screen sizes, and
configurations. Handling these variations while maintaining consistent location
functionality can be challenging.
Location Caching: Use cached or last-known location data when high accuracy is not
required to reduce network and GPS dependency.
Adaptive Geofencing: Use adaptive geofencing that considers device speed and
environment to adjust when and how geofencing events are triggered.
In other words, you can say that An Mobile Agent is an autonomous program that is capable
of moving from host to host in a network and interact with resources and other agents. In this
process, the chance of data loss is scarce because the state of the running program is saved
and then transported to the new host. It allows the program to continue execution from
where it left off before migration. The most significant advantage of mobile agents is the
possibility of moving complex processing functions to the location where you have enormous
amounts of data and that have to be processed.
Mobile Agents are also called as transportable agents. They are classified into two types:
o Mobile Agents with pre-defined path: They have a static migration path.
o Mobile Agents with undefined path i.e., Roamer: They have dynamic migration
paths. The mobile agents choose their path according to the present network condition.
The mobile agents are autonomous with intelligence, social ability, learning, and the most
important feature is their mobility. They are independent in nature, self-driven and do not
require a corresponding node for communication. They can work efficiently even after the
user gets disconnected from the network.
Intelligence
Mobile Agents are capable of learning and searching for knowledge about their domain.
That's why they are called intelligent agents because they possess a degree of domain
knowledge. They can also transport their state from one environment to another
without disturbing the previous holding data and be capable of performing
appropriately in the new environment.
Autonomous
The Mobile Agents are Autonomous. It means the agents are not only motivated by the
outside actions initiated by the users or system but also they have internal events that
decided their performance and behavior. The mobile agents can also take an
autonomous decision while selecting a node.
Mobility
Mobile Agents contain some degree of mobility. The agent is not limited to its home
node only. They can migrate from one node to another and can carry out tasks along
with them. This feature distributes the processing and balancing of the load. Another
benefit of this capability is that when the user goes offline, the agents will still keep
functioning.
Communicative
Mobile Agents can communicate effectively with other agents, users and systems. The
mobile agents use a communication language for inter-agent communication.
o They can adapt to the environment. For example, either home or foreign environment.
o They are capable of switching among the positions of one node to another.
The following are some advantages of mobile agents over conventional agents:
o They are Fault-tolerant. It means they are able to operate without an active connection
between client and server.
o They provide dynamic adaptation in which their actions are dependent on the state of
the host environment.
o The most significant disadvantage of mobile agents is their security. They are less
secured
o Mobile Agents are applied in a wide range of domains such as E-commerce, traffic
control, network management, robotics, data-intensive applications etc.
o They are also used in grid computing, parallel computing, distributed computing and
mobile computing etc.
The FusedLocationProviderClient is part of the Google Play Services API and is the
recommended method for accessing location data in Android. It intelligently combines
multiple sources of location data (GPS, Wi-Fi, and cellular data) to deliver the most accurate
location while optimizing power consumption.
Advantages:
Easy to implement: Provides simplified methods for getting current location, location
updates, and handling background location tracking.
Key Features:
Usage:
FusedLocationProviderClient fusedLocationClient =
LocationServices.getFusedLocationProviderClient(context);
fusedLocationClient.getLastLocation()
.addOnSuccessListener(location -> {
});
GPS is one of the most accurate location tracking methods, as it uses satellite signals to
determine the user's position. It is commonly used when high accuracy is necessary, such as
in navigation apps or location-based gaming.
Advantages:
Ideal for real-time navigation and location-based services in open outdoor areas.
Limitations:
Android can estimate a device's location using nearby Wi-Fi networks and cell towers
when GPS is not available or accurate. This method is less precise than GPS but more power-
efficient.
Advantages:
Limitations:
4. Geofencing
Geofencing is a location-based service that allows an app to define geographical boundaries
(virtual "fences") around certain areas. When the device enters or exits this area, an event is
triggered (such as sending a notification).
Applications:
Key APIs:
GeofencingClient: Used to add and remove geofences, and to receive geofence events.
Geofence: Defines a boundary, including its radius, center, and transition type (enter,
exit).
Usage:
.setRequestId("1")
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
Activity Recognition and Location History allow apps to understand a user’s activity
(walking, running, biking, driving, etc.) or track their past locations.
Activity Recognition: Can detect the user's current activity in real-time, such as
walking, running, or in a vehicle.
Location History: Tracks the user's movements over time to provide context about
their typical routes and places.
APIs:
The Google Maps SDK for Android offers location-based features such as displaying maps,
adding markers, and drawing routes. It also integrates with location services for real-time
navigation, tracking, and location-based visualizations.
Features:
Usage:
map.setMyLocationEnabled(true);
7. Location Permissions
Android requires apps to request location permissions at runtime for accessing location
data. Depending on the level of accuracy needed, apps must request either
ACCESS_COARSE_LOCATION (approximate location) or ACCESS_FINE_LOCATION (precise
GPS location). From Android 6.0 (API level 23) onward, location permissions must be
requested dynamically.
Permissions:
Usage:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
// Permission granted
} else {
8. Background Location
Android’s background location permission is required if your app needs to access location
data while running in the background. This is important for use cases such as fitness trackers,
ride-sharing apps, or security apps.
Starting from Android 10 (API 29), accessing background location requires a separate
permission (ACCESS_BACKGROUND_LOCATION), which must be granted by the user.
Usage:
Android’s Doze mode (introduced in Android 6.0) can limit location updates when the device
is idle or in a low-power state. Apps should be aware of Doze mode to avoid interruptions to
background location updates.
Best Practices:
Use WorkManager or JobScheduler for periodic background tasks that need location
updates.
1. Battery Efficiency: Always balance the accuracy of the location with the power
consumption. Use Fused Location Provider, which intelligently switches between GPS,
Wi-Fi, and cellular signals based on your needs.
2. User Privacy: Ensure you handle location data responsibly by requesting permission,
explaining the need for location access, and using encryption for sensitive data.
Answer: Fused Location Provider because it optimizes the device’s use of battery power.
For those looking to master advanced Android development techniques like location-based
services, consider enrolling in the Android Development with Kotlin course from
GeeksforGeeks. This course covers essential features such as handling location data,
enabling you to build sophisticated apps with Kotlin.
Before moving any of the above methods we will have to take location permission.
Looking to become an expert in Android App Development? Whether you're a student or a
professional aiming to advance your career in mobile app development, our course,
"Android App Development with Kotlin," available exclusively on GeeksforGeeks, is the
perfect fit for you.
Step 1: Define uses permissions for location access in the manifest file
<!– To request foreground location access, declare one of these permissions. –>
<!– Required only when requesting background location access on Android 10 (API level 29) –
>
Note:
If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then you need to request
only the ACCESS_FINE_LOCATION permission, because it includes permission for both
providers. Permission for ACCESS_COARSE_LOCATION allows access only to
NETWORK_PROVIDER.
Step 2: Define uses permission for internet access because we are going to use Internet
Provider.
<uses-permission android:name=”android.permission.INTERNET”/>
Step 3: Write a function for checking that location permission is granted or not. If permission
is not granted then ask for the permissions in run time.
return if (ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_COARSE_LOCATION
this,
android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
){
ActivityCompat.requestPermissions(
this,
arrayOf(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION
),
requestcode
false
} else {
true
Now after handling location permissions, we are going to learn how can we get the location in
android.
We assume that the user has been granted Location Permission. If not then ask first.
Step 2: Check that if the GPS and Network are available or not and if both are available then
we use one with greater accuracy.
//------------------------------------------------------//
val hasNetwork =
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
Step 3: Creating an instance of LocationListener (package: android.location) for both(GPS
and Network).
locationByGps= location
//------------------------------------------------------//
locationByNetwork= location
Step 4: If any of the GPS or Network providers is enabled then we will request a current
location update from the LocationManager with LocationListener.
if (hasGps) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
5000,
0F,
gpsLocationListener
//------------------------------------------------------//
if (hasNetwork) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
5000,
0F,
networkLocationListener
Step 5: Now we check which provider has given us the more accurate location and then we
will use that location as per our requirement.
val lastKnownLocationByGps =
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
lastKnownLocationByGps?.let {
locationByGps = lastKnownLocationByGps
//------------------------------------------------------//
val lastKnownLocationByNetwork =
locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
lastKnownLocationByNetwork?.let {
locationByNetwork = lastKnownLocationByNetwork
//------------------------------------------------------//
currentLocation = locationByGps
latitude = currentLocation.latitude
longitude = currentLocation.longitude
} else {
currentLocation = locationByNetwork
latitude = currentLocation.latitude
longitude = currentLocation.longitude
}
Now after learning how can we get the location in android by Location Manager API, we are
moving to the second method Fused Location Provider (Google Play Services Location
APIs).
We assume that the user has been granted Location Permission. If not then ask first. Fused
Location Provider is the Google Play services location APIs. It provides a simple API for getting
locations with high, medium, and low accuracy. It also optimizes the device’s use of battery
power. So we should prefer this method.
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
locationRequest = LocationRequest().apply {
interval = TimeUnit.SECONDS.toMillis(60)
fastestInterval = TimeUnit.SECONDS.toMillis(30)
// Sets the maximum time when batched location
maxWaitTime = TimeUnit.MINUTES.toMillis(2)
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
super.onLocationResult(locationResult)
locationResult?.lastLocation?.let {
currentLocation = locationByGps
latitude = currentLocation.latitude
longitude = currentLocation.longitude
} ?: {
Step 5: Now that you initialized everything, you need to let the FusedLocationProviderClient
know that you want to receive updates. So Subscribe to location changes.
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback,
Looper.myLooper())
Step 6: When the app no longer needs access to location information, it’s important to
unsubscribe from location updates.
if (task.isSuccessful) {
} else {
}
}
Now one more important point to give support for Android 10 and Android R. So
Let’s talk about it…
android {
compileSdkVersion 29
buildToolsVersion “29.0.3”
defaultConfig {
applicationId “com.example.android.location”
minSdkVersion 26
targetSdkVersion 29
versionCode 1
versionName “1.0”
android:foregroundServiceType=”location”
<application>
<service
android:name=”com.example.android.location.ForegroundOnlyLocationService”
android:enabled=”true”
android:exported=”false”
android:foregroundServiceType=”location” />
</application>
Support for Android 11 or Android R
Great news, you don’t need to make changes to any files except for the build.gradle file!
Make these changes:
1. compileSdkVersion to “android-R”
2. targetSdkVersion to “R”
android {
compileSdkVersion “android-R”
buildToolsVersion “29.0.2”
defaultConfig {
applicationId “com.example.android.location”
minSdkVersion 26
targetSdkVersion “R”
versionCode 1
versionName “1.0”
Now in this tutorial we will display and place marker at the user current location. For doing
this we need to generate Google Map API key. The process of generating Google Map API is
described in tutorial Android Google Map.
To display the user current location we need to implements some interfaces and there
callbacks methods.
Let's see an example of Google Map which displays the current location of device.
activity_maps.xml
1. <fragment xmlns:android="http://schemas.android.com/apk/res/android"
2. xmlns:map="http://schemas.android.com/apk/res-auto"
3. xmlns:tools="http://schemas.android.com/tools"
4. android:id="@+id/map"
5. android:name="com.google.android.gms.maps.SupportMapFragment"
6. android:layout_width="match_parent"
7. android:layout_height="match_parent"
8. tools:context="example.com.mapexample.MapsActivity" />
build.gradel
1. dependencies {
3. implementation 'com.android.support:appcompat-v7:26.1.0'
4. implementation 'com.google.android.gms:play-services-maps:11.8.0'
5. compile 'com.google.android.gms:play-services-location:11.8.0'
6. testImplementation 'junit:junit:4.12'
7. androidTestImplementation 'com.android.support.test:runner:1.0.1'
8. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
9.
10. }
MapsActivity.java
Add the following code in MapsActivity.java file.
1. package example.com.mapexample;
2.
3.
4. import android.os.Build;
5. import android.support.v4.app.FragmentActivity;
6. import android.os.Bundle;
7.
8. import com.google.android.gms.common.api.GoogleApiClient;
9. import com.google.android.gms.maps.CameraUpdateFactory;
18.
26.
27.
29. LocationListener,GoogleApiClient.ConnectionCallbacks,
30. GoogleApiClient.OnConnectionFailedListener{
31.
37.
38. @Override
40. super.onCreate(savedInstanceState);
41. setContentView(R.layout.activity_maps);
42. // Obtain the SupportMapFragment and get notified when the map is ready t
o be used.
44. .findFragmentById(R.id.map);
45. mapFragment.getMapAsync(this);
46.
47. }
48.
49. @Override
52.
54. if (ContextCompat.checkSelfPermission(this,
55. Manifest.permission.ACCESS_FINE_LOCATION)
56. == PackageManager.PERMISSION_GRANTED) {
57. buildGoogleApiClient();
58. mMap.setMyLocationEnabled(true);
59. }
60. }
61. else {
62. buildGoogleApiClient();
63. mMap.setMyLocationEnabled(true);
64. }
65.
66. }
69. .addConnectionCallbacks(this)
70. .addOnConnectionFailedListener(this)
71. .addApi(LocationServices.API).build();
72. mGoogleApiClient.connect();
73. }
74.
75. @Override
77.
79. mLocationRequest.setInterval(1000);
80. mLocationRequest.setFastestInterval(1000);
81. mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER
_ACCURACY);
82. if (ContextCompat.checkSelfPermission(this,
83. Manifest.permission.ACCESS_FINE_LOCATION)
84. == PackageManager.PERMISSION_GRANTED) {
85. LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiC
lient, mLocationRequest, this);
86. }
87.
88. }
89.
90. @Override
92.
93. }
94.
95. @Override
100. mCurrLocationMarker.remove();
101. }
105. markerOptions.position(latLng);
107. markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescripto
rFactory.HUE_GREEN));
109.
111. mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
112. mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
113.
116. LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiC
lient, this);
117. }
118.
119. }
120.
121. @Override
123.
124. }
125.
126. }
AndroidManifest.xml
2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3. package="example.com.mapexample">
4. <!--
6. Google Maps Android API v2, but you must specify either coarse or fine
8. -->
12.
13.
14. <application
15. android:allowBackup="true"
16. android:icon="@mipmap/ic_launcher"
17. android:label="@string/app_name"
18. android:roundIcon="@mipmap/ic_launcher_round"
19. android:supportsRtl="true"
20. android:theme="@style/AppTheme">
21. <!--
22. The API key for Google Maps-based APIs is defined as a string resource.
23. (See the file "res/values/google_maps_api.xml").
24. Note that the API key is linked to the encryption key used to sign the APK.
25. You need a different API key for each encryption key, including the releas
e key that is used to
27. You can define the keys for the debug and release targets in src/debug/ a
nd src/release/.
28. -->
29. <meta-data
30. android:name="com.google.android.geo.API_KEY"
32.
33. <activity
34. android:name=".MapsActivity"
35. android:label="@string/title_activity_maps">
36. <intent-filter>
38.
40. </intent-filter>
41. </activity>
42. </application>
43.
44. </manifest>
Output
Write a Program to how to update the Current Location in the
Map?
The android project contains different types of app modules, source code files, and resource
files. We will explore all the folders and files in the android app.
1. Manifests Folder
2. Java Folder
Drawable Folder
Layout Folder
Mipmap Folder
Values Folder
4. Gradle Scripts
Manifests Folder
Manifests folder contains AndroidManifest.xml for creating our android application. This file
contains information about our application such as the Android version, metadata, states
package for Kotlin file, and other application components. It acts as an intermediator
between android OS and our application.
AndroidManifest.xml
package="com.geeksforgeeks.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
</intent-filter>
</activity>
</application>
</manifest>
Java folder
The Java folder contains all the java and Kotlin source code (.java) files that we create during
the app development, including other Test files. If we create any new project using Kotlin, by
default the class file MainActivity.kt file will create automatically under the package name
“com.geeksforgeeks.myfirstkotlinapp” as shown below.
package com.geeksforgeeks.myapplication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
The resource folder is the most important folder because it contains all the non-code sources
like images, XML layouts, and UI strings for our android application.
res/drawable folder
It contains the different types of images used for the development of the application. We
need to add all the images in a drawable folder for the application development.
res/layout folder
The layout folder contains all XML layout files which we used to define the user interface of
our application. It contains the activity_main.xml file.
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http:// schemas.android.com/apk/res/android"
xmlns:app="http:// schemas.android.com/apk/res-auto"
xmlns:tools="http:// schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
res/mipmap folder
This folder contains launcher.xml files to define icons that are used to show on the home
screen. It contains different density types of icons depending upon the size of the device such
as hdpi, mdpi, xhdpi.
res/values folder
Values folder contains a number of XML files like strings, dimensions, colors, and style
definitions. One of the most important files is the strings.xml file which contains the
resources.
<resources>
<string name="app_name">NameOfTheApplication</string>
<string name="checked">Checked</string>
<string name="unchecked">Unchecked</string>
</resources>
Gradle means automated build system and it contains a number of files that are used to
define a build configuration that can be applied to all modules in our application. In
build.gradle (Project) there are buildscripts and in build.gradle (Module) plugins and
implementations are used to build configurations that can be applied to all our application
modules.
Unit 5
Here’s a step-by-step guide on how to create, set, and cancel alarms in an Android app.
1. Creating an Alarm
To create an alarm, you need to interact with the AlarmManager system service. The alarm
can trigger a BroadcastReceiver, Service, or Activity to perform a certain action when the
alarm goes off.
Steps:
2. Create an Intent that specifies the action to take when the alarm goes off.
Example Code:
// Step 1: Get an instance of AlarmManager
Breakdown:
SystemClock.elapsedRealtime() provides the system time since the device was booted,
which is often used for setting alarms relative to the device's uptime.
Sometimes, you need the alarm to repeat at regular intervals (e.g., every 30 minutes). You
can set repeating alarms using the setRepeating() method or setInexactRepeating() for less
precision.
Key Points:
Interval is the duration between consecutive alarms (e.g., 1 hour in the example).
To handle the alarm when it goes off, you need to create a BroadcastReceiver. The receiver
is triggered by the alarm and performs a task, such as displaying a notification or starting a
service.
Example of BroadcastReceiver:
public class AlarmReceiver extends BroadcastReceiver {
@Override
// Perform the action when the alarm goes off (e.g., display a notification)
You need to register this receiver in the AndroidManifest.xml or dynamically within the
app.
Example of Registering in AndroidManifest.xml:
4. Cancelling an Alarm
If you want to cancel a previously set alarm, you need to call AlarmManager.cancel() with the
same PendingIntent used when setting the alarm. This will cancel the alarm and prevent it
from being triggered.
// Step 2: Create an Intent and PendingIntent as done when setting the alarm
alarmManager.cancel(pendingIntent);
For modern Android apps, it's recommended to use WorkManager for scheduling
background tasks, including alarms, because it automatically handles scenarios like the app
being closed or the device going to sleep. WorkManager also ensures tasks are run even if
the app is not in the foreground.
.build();
WorkManager.getInstance(context).enqueue(alarmWorkRequest);
In this example, MyWorker is a class that extends Worker and contains the logic to be
performed when the alarm triggers.
Best Practices
Avoid using setRepeating() for exact intervals as it can have an impact on battery
life. For precise repeating tasks, use JobScheduler or WorkManager instead.
Use WakeLocks cautiously. Android handles Doze Mode and App Standby
automatically, so make sure alarms are set in a way that respects power consumption.
Always make sure you’re using the correct permissions in your app. For example, to
wake up the device from sleep, your app may need to request WAKE_LOCK
permission.
Caution: A service runs in the main thread of its hosting process; the service
does not create its own thread and does not run in a separate process unless you specify
otherwise. You should run any blocking operations on a separate thread within the service to
avoid Application Not Responding (ANR) errors.
Types of Services
Foreground
A foreground service performs some operation that is noticeable to the user. For example, an
audio app would use a foreground service to play an audio track. Foreground services must
display a Notification. Foreground services continue running even when the user isn't
interacting with the app.
When you use a foreground service, you must display a notification so that users are actively
aware that the service is running. This notification cannot be dismissed unless the service is
either stopped or removed from the foreground.
Note: The WorkManager API offers a flexible way of scheduling tasks, and is able to run these
jobs as foreground services if needed. In many cases, using WorkManager is preferable to
using foreground services directly.
Background
A background service performs an operation that isn't directly noticed by the user. For
example, if an app used a service to compact its storage, that would usually be a background
service.
Note: If your app targets API level 26 or higher, the system imposes restrictions on running
background services when the app itself isn't in the foreground. In most situations, for
example, you shouldn't access location information from the background. Instead, schedule
tasks using WorkManager.
Bound
A service is bound when an application component binds to it by calling bindService(). A
bound service offers a client-server interface that allows components to interact with the
service, send requests, receive results, and even do so across processes with interprocess
communication (IPC). A bound service runs only as long as another application component is
bound to it. Multiple components can bind to the service at once, but when all of them
unbind, the service is destroyed.
Although this documentation generally discusses started and bound services separately, your
service can work both ways—it can be started (to run indefinitely) and also allow binding. It's
simply a matter of whether you implement a couple of callback
methods: onStartCommand() to allow components to start it and onBind() to allow binding.
Regardless of whether your service is started, bound, or both, any application component can
use the service (even from a separate application) in the same way that any component can
use an activity—by starting it with an Intent. However, you can declare the service
as private in the manifest file and block access from other applications. This is discussed
more in the section about Declaring the service in the manifest.
A service is simply a component that can run in the background, even when the user is not
interacting with your application, so you should create a service only if that is what you need.
If you must perform work outside of your main thread, but only while the user is interacting
with your application, you should instead create a new thread in the context of another
application component. For example, if you want to play some music, but only while your
activity is running, you might create a thread in onCreate(), start running it in onStart(), and
stop it in onStop(). Also consider using thread pools and executors from
the java.util.concurrent package or Kotlin coroutines instead of the traditional Thread class.
See the Threading on Android document for more information about moving execution to
background threads.
Remember that if you do use a service, it still runs in your application's main thread by
default, so you should still create a new thread within the service if it performs intensive or
blocking operations.
The basics
To create a service, you must create a subclass of Service or use one of its existing
subclasses. In your implementation, you must override some callback methods that handle
key aspects of the service lifecycle and provide a mechanism that allows the components to
bind to the service, if appropriate. These are the most important callback methods that you
should override:
onStartCommand()
The system invokes this method by calling startService() when another component (such as
an activity) requests that the service be started. When this method executes, the service is
started and can run in the background indefinitely. If you implement this, it is your
responsibility to stop the service when its work is complete by
calling stopSelf() or stopService(). If you only want to provide binding, you don't need to
implement this method.
onBind()
The system invokes this method by calling bindService() when another component wants to
bind with the service (such as to perform RPC). In your implementation of this method, you
must provide an interface that clients use to communicate with the service by returning
an IBinder. You must always implement this method; however, if you don't want to allow
binding, you should return null.
onCreate()
The system invokes this method to perform one-time setup procedures when the service is
initially created (before it calls either onStartCommand() or onBind()). If the service is already
running, this method is not called.
onDestroy()
The system invokes this method when the service is no longer used and is being destroyed.
Your service should implement this to clean up any resources such as threads, registered
listeners, or receivers. This is the last call that the service receives.
If a component calls bindService() to create the service and onStartCommand() is not called,
the service runs only as long as the component is bound to it. After the service is unbound
from all of its clients, the system destroys it.
The Android system stops a service only when memory is low and it must recover system
resources for the activity that has user focus. If the service is bound to an activity that has
user focus, it's less likely to be killed; if the service is declared to run in the foreground, it's
rarely killed. If the service is started and is long-running, the system lowers its position in the
list of background tasks over time, and the service becomes highly susceptible to killing—if
your service is started, you must design it to gracefully handle restarts by the system. If the
system kills your service, it restarts it as soon as resources become available, but this also
depends on the value that you return from onStartCommand(). For more information about
when the system might destroy a service, see the Processes and Threading document.
You must declare all services in your application's manifest file, just as you do for activities
and other components.
To declare your service, add a <service> element as a child of the <application> element.
Here is an example:
...
...
</application>
</manifest>
See the <service> element reference for more information about declaring your service in
the manifest.
There are other attributes that you can include in the <service> element to define properties
such as the permissions that are required to start the service and the process in which the
service should run. The android:name attribute is the only required attribute—it specifies the
class name of the service. After you publish your application, leave this name unchanged to
avoid the risk of breaking code due to dependence on explicit intents to start or bind the
service (read the blog post, Things That Cannot Change).
Caution: To ensure that your app is secure, always use an explicit intent when starting
a Service and don't declare intent filters for your services. Using an implicit intent to start a
service is a security hazard because you cannot be certain of the service that responds to the
intent, and the user cannot see which service starts. Beginning with Android 5.0 (API level
21), the system throws an exception if you call bindService() with an implicit intent.
You can ensure that your service is available to only your app by including
the android:exported attribute and setting it to false. This effectively stops other apps from
starting your service, even when using an explicit intent.
Note: Users can see what services are running on their device. If they see a service that they
don't recognize or trust, they can stop the service. In order to avoid having your service
stopped accidentally by users, you need to add the android:description attribute to
the <service> element in your app manifest. In the description, provide a short sentence
explaining what the service does and what benefits it provides.
A started service is one that another component starts by calling startService(), which results
in a call to the service's onStartCommand() method.
When a service is started, it has a lifecycle that's independent of the component that started
it. The service can run in the background indefinitely, even if the component that started it is
destroyed. As such, the service should stop itself when its job is complete by
calling stopSelf(), or another component can stop it by calling stopService().
For instance, suppose an activity needs to save some data to an online database. The activity
can start a companion service and deliver it the data to save by passing an intent
to startService(). The service receives the intent in onStartCommand(), connects to the
Internet, and performs the database transaction. When the transaction is complete, the
service stops itself and is destroyed.
Caution: A service runs in the same process as the application in which it is declared and in
the main thread of that application by default. If your service performs intensive or blocking
operations while the user interacts with an activity from the same application, the service
slows down activity performance. To avoid impacting application performance, start a new
thread inside the service.
The Service class is the base class for all services. When you extend this class, it's important
to create a new thread in which the service can complete all of its work; the service uses your
application's main thread by default, which can slow the performance of any activity that
your application is running.
The Android framework also provides the IntentService subclass of Service that uses a worker
thread to handle all of the start requests, one at a time. Using this class is not
recommended for new apps as it will not work well starting with Android 8 Oreo, due to the
introduction of Background execution limits. Moreover, it's deprecated starting with Android
11. You can use JobIntentService as a replacement for IntentService that is compatible with
newer versions of Android.
The following sections describe how you can implement your own custom service, however
you should strongly consider using WorkManager instead for most use cases. Consult
the guide to background processing on Android to see if there is a solution that fits your
needs.
You can extend the Service class to handle each incoming intent. Here's how a basic
implementation might look:
KotlinJava
try {
Thread.sleep(5000)
Thread.currentThread().interrupt()
stopSelf(msg.arg1)
}
HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND).apply {
start()
serviceLooper = looper
serviceHandler = ServiceHandler(looper)
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
msg.arg1 = startId
serviceHandler?.sendMessage(msg)
return START_STICKY
The example code handles all incoming calls in onStartCommand() and posts the work to
a Handler running on a background thread. It works just like an IntentService and processes
all requests serially, one after another. You could change the code to run the work on a thread
pool, for example, if you'd like to run multiple requests simultaneously.
Notice that the onStartCommand() method must return an integer. The integer is a value that
describes how the system should continue the service in the event that the system kills it.
The return value from onStartCommand() must be one of the following constants:
START_NOT_STICKY
If the system kills the service after onStartCommand() returns, do not recreate the service
unless there are pending intents to deliver. This is the safest option to avoid running your
service when not necessary and when your application can simply restart any unfinished
jobs.
START_STICKY
If the system kills the service after onStartCommand() returns, recreate the service and
call onStartCommand(), but do not redeliver the last intent. Instead, the system
calls onStartCommand() with a null intent unless there are pending intents to start the
service. In that case, those intents are delivered. This is suitable for media players (or similar
services) that are not executing commands but are running indefinitely and waiting for a job.
START_REDELIVER_INTENT
If the system kills the service after onStartCommand() returns, recreate the service and
call onStartCommand() with the last intent that was delivered to the service. Any pending
intents are delivered in turn. This is suitable for services that are actively performing a job
that should be immediately resumed, such as downloading a file.
For more details about these return values, see the linked reference documentation for each
constant.
Starting a service
You can start a service from an activity or other application component by passing
an Intent to startService() or startForegroundService(). The Android system calls the
service's onStartCommand() method and passes it the Intent, which specifies which service
to start.
Note: If your app targets API level 26 or higher, the system imposes restrictions on using or
creating background services unless the app itself is in the foreground. If an app needs to
create a foreground service, the app should call startForegroundService(). That method
creates a background service, but the method signals to the system that the service will
promote itself to the foreground. Once the service has been created, the service must call
its startForeground() method within five seconds.
For example, an activity can start the example service in the previous section (HelloService)
using an explicit intent with startService(), as shown here:
KotlinJava
startService(Intent(this, HelloService::class.java))
The startService() method returns immediately, and the Android system calls the
service's onStartCommand() method. If the service isn't already running, the system first
calls onCreate(), and then it calls onStartCommand().
If the service doesn't also provide binding, the intent that is delivered with startService() is
the only mode of communication between the application component and the service.
However, if you want the service to send a result back, the client that starts the service can
create a PendingIntent for a broadcast (with getBroadcast()) and deliver it to the service in
the Intent that starts the service. The service can then use the broadcast to deliver a result.
Multiple requests to start the service result in multiple corresponding calls to the
service's onStartCommand(). However, only one request to stop the service
(with stopSelf() or stopService()) is required to stop it.
Stopping a service
A started service must manage its own lifecycle. That is, the system doesn't stop or destroy
the service unless it must recover system memory and the service continues to run
after onStartCommand() returns. The service must stop itself by calling stopSelf(), or another
component can stop it by calling stopService().
Once requested to stop with stopSelf() or stopService(), the system destroys the service as
soon as possible.
Caution: To avoid wasting system resources and consuming battery power, ensure that your
application stops its services when it's done working. If necessary, other components can
stop the service by calling stopService(). Even if you enable binding for the service, you
must always stop the service yourself if it ever receives a call to onStartCommand().
For more information about the lifecycle of a service, see the section below about Managing
the Lifecycle of a Service.
To create a bound service, implement the onBind() callback method to return an IBinder that
defines the interface for communication with the service. Other application components can
then call bindService() to retrieve the interface and begin calling methods on the service. The
service lives only to serve the application component that is bound to it, so when there are
no components bound to the service, the system destroys it. You do not need to stop a bound
service in the same way that you must when the service is started
through onStartCommand().
To create a bound service, you must define the interface that specifies how a client can
communicate with the service. This interface between the service and a client must be an
implementation of IBinder and is what your service must return from the onBind() callback
method. After the client receives the IBinder, it can begin interacting with the service through
that interface.
Multiple clients can bind to the service simultaneously. When a client is done interacting with
the service, it calls unbindService() to unbind. When there are no clients bound to the
service, the system destroys the service.
There are multiple ways to implement a bound service, and the implementation is more
complicated than a started service. For these reasons, the bound service discussion appears
in a separate document about Bound Services.
When a service is running, it can notify the user of events using snackbar
notifications or status bar notifications.
A snackbar notification is a message that appears on the surface of the current window for
only a moment before disappearing. A status bar notification provides an icon in the status
bar with a message, which the user can select in order to take an action (such as start an
activity).
Usually, a status bar notification is the best technique to use when background work such as
a file download has completed, and the user can now act on it. When the user selects the
notification from the expanded view, the notification can start an activity (such as to display
the downloaded file).
The lifecycle of a service is much simpler than that of an activity. However, it's even more
important that you pay close attention to how your service is created and destroyed because
a service can run in the background without the user being aware.
The service lifecycle—from when it's created to when it's destroyed—can follow either of
these two paths:
A started service
The service is created when another component calls startService(). The service then
runs indefinitely and must stop itself by calling stopSelf(). Another component can also
stop the service by calling stopService(). When the service is stopped, the system
destroys it.
A bound service
The service is created when another component (a client) calls bindService(). The client
then communicates with the service through an IBinder interface. The client can close
the connection by calling unbindService(). Multiple clients can bind to the same service
and when all of them unbind, the system destroys the service. The service
does not need to stop itself.
These two paths aren't entirely separate. You can bind to a service that is already started
with startService(). For example, you can start a background music service by
calling startService() with an Intent that identifies the music to play. Later, possibly when the
user wants to exercise some control over the player or get information about the current
song, an activity can bind to the service by calling bindService(). In cases such as
this, stopService() or stopSelf() doesn't actually stop the service until all of the clients unbind.
Like an activity, a service has lifecycle callback methods that you can implement to monitor
changes in the service's state and perform work at the appropriate times. The following
skeleton service demonstrates each of the lifecycle methods:
KotlinJava
private var startMode: Int = 0 // indicates how to behave if the service is killed
private var binder: IBinder? = null // interface for clients that bind
private var allowRebind: Boolean = false // indicates whether onRebind should be used
return startMode
return binder
return allowRebind
Note: Unlike the activity lifecycle callback methods, you are not required to call the
superclass implementation of these callback methods.
Figure 2. The service lifecycle. The diagram on the left shows the lifecycle when the service
is created with startService() and the diagram on the right shows the lifecycle when the
service is created with bindService().
Figure 2 illustrates the typical callback methods for a service. Although the figure separates
services that are created by startService() from those created by bindService(), keep in mind
that any service, no matter how it's started, can potentially allow clients to bind to it. A
service that was initially started with onStartCommand() (by a client calling startService())
can still receive a call to onBind() (when a client calls bindService()).
By implementing these methods, you can monitor these two nested loops of the service's
lifecycle:
The entire lifetime of a service occurs between the time that onCreate() is called and
the time that onDestroy() returns. Like an activity, a service does its initial setup
in onCreate() and releases all remaining resources in onDestroy(). For example, a music
playback service can create the thread where the music is played in onCreate(), and
then it can stop the thread in onDestroy().
Note: The onCreate() and onDestroy() methods are called for all services, whether they're
created by startService() or bindService().
If the service is started, the active lifetime ends at the same time that the entire lifetime
ends (the service is still active even after onStartCommand() returns). If the service is bound,
the active lifetime ends when onUnbind() returns.
For more information about creating a service that provides binding, see the Bound
Services document, which includes more information about the onRebind() callback method
in the section about Managing the lifecycle of a bound service.
Google announced a support library along with the introduction of ActionBar. This library is
a part of AppCompat and its purpose is to provide backward compatibility for older versions
of Android and to support tabbed interfaces. All applications that use the default theme
provided by the Android(Theme.AppCompat.Light.DarkActionBar), contains an ActionBar by
default. However, developers can customize it in several ways depending upon their needs.
Components included in the ActionBar are:
View Controls: Section that displays the name of the application or current activity.
Developers can also include spinner or tabbed navigation for switching between views.
Action Button: Contains some important actions/elements of the app that may be
required to the users frequently.
The following example demonstrates the steps involved in creating a custom ActionBar for
the MainActivity of an application. All important aspects of visual elements like icon, title,
subtitle, action buttons, and overflow menu will be covered.
As mentioned earlier, every android app contains an ActionBar by default. This pre-included
ActionBar display title for the current activity that is managed by
the AncdroidManifest.xml file. The string value of the application’s title is provided
by @string/app_name resource present under the application nodes.
<application
…..
…..
android:label=”@string/app_name”
…..
</application>
Output:
To code the elements of ActionBar, create a new directory in the resource folder of the
application project files. Right-click on the res folder and selects New -> Directory. Give the
name “menu” to the new directory.
Further, create a new Menu Resource File by right click on the menu directory. As the
ActionBar is being created for the main Activity, type the name as “main” to the Menu
Resource File. With this, a new file named “main.xml” must be created under the menu
directory. In this file, one can declare the items which will be displayed as the action
buttons of the ActionBar.
For every menu items, the following attributes are needed to be configured:
android:title: Its value contains the title of the menu item that will be displayed when
a user clicks and holds that item in the app.
android:id: A unique ID for the menu item that will be used to access it anywhere in
the whole application files.
app:showAsAction: This attribute defines how the item is going to be present in the
action bar. There are four possible flags to choose from:
o c. never: With this flag, the item will be not be displayed as an icon in ActionBar,
but will be present in the overflow menu.
o d. withText: To represent an item as both icon and the title, one can append this
flag with the always or ifRoom flag(always|withText or ifRoom|withText).
In order to provide an icon to an item, right-click on the res folder, select new, and
then Image Asset. A dialog box will appear, choose the Icon Type as Action Bar and Tab
Icons. Choose assets type as “Clip Art” and select an image from the clip art collection.
Provide a desired name to the icon. Click on Next, then Finish. This icon will now get loaded in
the drawable directory of the res folder. The name provided by the developers to these icons
will now be used to reference the item’s icon resource.
Below is the code to place a search icon, refresh icon, and an overflow menu in the ActionBar.
XML
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="search"
android:id="@+id/search"
android:orderInCategory="100"
app:showAsAction="ifRoom"
android:icon="@drawable/search_icon"/>
<item android:title="refresh"
android:id="@+id/refresh"
android:orderInCategory="100"
app:showAsAction="ifRoom"
android:icon="@drawable/refresh_icon"/>
<item android:title="copy"
android:id="@+id/copy"
android:orderInCategory="100"
app:showAsAction="never"
android:icon="@drawable/copy_icon"/>
</menu>
Output:
The items of an ActionBar is designed with a purpose to perform some operations. Those
operations/actions of the items are declared in that Activity file for which the ActionBar has
been designed. In this example, the target activity is the MainActivity file. Further, the
custom title, subtitle, and application logo are also defined in this file. Below is the proper
code to design all mentioned items and to display a toast message when a user clicks on the
items of ActionBar.
Java
Kotlin
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
@Override
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actionBar.setIcon(R.drawable.app_logo);
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
Head over to style.xml file located in the values directory of the res folder. To change
the default color of the ActionBar, one has to change the colorPrimary resource. Below is
the code to make the ActionBar color ‘green’.
XML
<resources>
<item name="colorPrimary">#0F9D58</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
Output:
This file defines the layout of the activity. In this example, the prime focus is on ActionBar,
thus the activity will contain only a simple TextView. Below is the code.
XML
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#168BC34A"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello Geek!!"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Output:
Video Player
00:00
00:23
Advantages of ActionBar
Specify the location of the user in the app by displaying the title of the current Activity.
Support tabs and a drop-down list for view switching and navigation.
Disadvantages of ActionBar
All features of the ActionaBar are not introduced at once but were introduced with the
release of different API levels such as API 15, 17, and 19.
In this explanation, I’ll first clarify how download management works on Android, and then
explain how a mobile app could implement features similar to Internet Download Manager
(IDM) for handling downloads, including acceleration, pause/resume, and file management.
2. Pause and Resume: It allows you to pause downloads and resume them later, even
after closing the application or restarting the computer.
4. Batch Downloads: IDM can download multiple files at once and organize them
efficiently.
5. Integration with Browsers: IDM integrates with web browsers (like Chrome, Firefox)
to capture download links directly from the browser.
6. Error Recovery and Resume: IDM can recover from network errors and continue
from where it left off.
Although IDM itself isn't available natively on Android, its core concepts can be replicated on
the platform using tools provided by the Android SDK or third-party libraries.
Android provides its own DownloadManager class to handle downloads. This system service
provides a simple interface for managing downloads in Android apps. It handles tasks like
download queue management, file saving, pause, resume, and retries on network failure,
making it ideal for implementing IDM-like features.
Error Recovery: It can automatically retry failed downloads due to network issues.
Access to System Download History: Users can see the status of their downloads in
the system's notification shade.
request.setTitle("Downloading File");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMP
LETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
"file_to_download.zip");
This code will start downloading the file and show a notification to the user. The
DownloadManager class automatically handles the downloading process, including retries
and progress tracking.
To achieve this, you can use libraries such as OkHttp or Retrofit to manage custom HTTP
requests, splitting a file into parts (usually based on byte ranges) and then downloading
those parts concurrently. Once all parts are downloaded, you can merge them into the final
file.
Split the file into several chunks (e.g., based on byte ranges).
Example (Conceptual):
// Pseudo-code to demonstrate parallel downloading
In this example, downloadPart is a function that downloads a specific chunk of the file. Once
all parts are downloaded, they can be merged to form the complete file.
Android’s DownloadManager allows you to pause and resume downloads, but it doesn't
allow direct control for pausing and resuming by the app itself, since it is handled at the
system level.
If you want more control, like when to pause and resume based on app-specific logic (e.g.,
user-initiated actions), you could implement a custom solution using background services and
manual control over HTTP requests. You can use libraries like OkHttp to download files and
pause/resume downloads by managing the download state yourself.
Example (Conceptual):
if (isPaused) {
} else {
4. Scheduling Downloads
WorkManager.getInstance(context).enqueue(downloadWorkRequest);
WorkManager is recommended because it respects Doze Mode and App Standby, ensuring
that your app behaves well in low-power situations.
To replicate IDM-like notifications (like showing download progress or completion), you can
use NotificationManager to show notifications for your download tasks.
.setContentTitle("Downloading File")
.setContentText("Downloading...")
.setSmallIcon(R.drawable.ic_download)
.setProgress(100, 0, false);
notificationManager.notify(notificationId, notificationBuilder.build());
If you want to download multiple files simultaneously, you can enqueue multiple requests
using DownloadManager or manage the downloads manually by keeping track of each
download's status.
Create a queue or batch system where the next file begins downloading only after the
current download completes.
Important: From August 2021, new apps are required to publish with the Android App
Bundle on Google Play. New apps larger than 200 MB are now supported by either Play
Feature Delivery or Play Asset Delivery. From June 2023, new and existing TV apps are
required to be published as App Bundles.
Publishing is the general process that makes your Android app available to users. When you
publish an Android app, you do the following:
During the preparation step, you build a release version of your app.
During the release step, you publicize, sell, and distribute the release version of your
app, which users can download and install on their Android-powered devices.
This page provides an overview of the process for preparing to publish your app. If you plan
to publish on Google Play, read Release with confidence.
If you use a Continuous Integration server, you can configure it to automate the steps
outlined here. You can also configure it to push builds to your internal test distribution
channel.
Preparing your app for release is a multistep process involving the following tasks:
At a minimum, you need to make sure that logging is disabled and removed and that
your release variant has debuggable false for Groovy or isDebuggable = false for Kotlin
script set. You should also set your app's version information.
You can use the Gradle build files with the release build type to build and sign a release
version of your app. For more information, see Build and run your app.
Before you distribute your app, you should thoroughly test the release version on at
least one target handset device and one target tablet device. Firebase Test Lab is useful
for testing across a variety of devices and configurations.
Make sure that all app resources, such as multimedia files and graphics, are updated
and included with your app or staged on the proper production servers.
Prepare remote servers and services that your app depends on.
If your app depends on external servers or services, make sure they are secure and
production ready.
You might need to perform several other tasks as part of the preparation process. For
example, you need to create an account on the app marketplace you want to use, if you don't
already have one. You also need to create an icon for your app, and you might want to
prepare an End User License Agreement (EULA) to protect yourself, your organization, and
your intellectual property.
To learn how to prepare your app for release, see Prepare for release for step-by-step
instructions for configuring and building a release version of your app.
When you are finished preparing your app for release, you have a signed APK file that you
can distribute to users.
You can release your Android apps several ways. Typically, you release apps through an app
marketplace such as Google Play. You can also release apps on your own website or by
sending an app directly to a user.
If you want to distribute your apps to the broadest possible audience, release them through
an app marketplace.
Google Play is the premier marketplace for Android apps and is particularly useful if you want
to distribute your apps to a large global audience. However, you can distribute your apps
through any app marketplace, and you can use multiple marketplaces.
Google Play is a robust publishing platform that helps you publicize, sell, and distribute your
Android apps to users around the world. When you release your apps through Google Play,
you have access to a suite of developer tools that let you analyze your sales, identify market
trends, and control who your apps are being distributed to.
Google Play also gives you access to several revenue-enhancing features such as in-app
billing and app licensing. The rich array of tools and features, coupled with numerous end-
user community features, makes Google Play the premier marketplace for selling and buying
Android apps.
Releasing your app on Google Play is a simple process that involves three basic steps:
To fully leverage the marketing and publicity capabilities of Google Play, you need to
create promotional materials for your app such as screenshots, videos, graphics, and
promotional text.
Google Play lets you target your app to a worldwide pool of users and devices. By
configuring various Google Play settings, you can choose the countries you want to
reach, the listing languages you want to use, and the price you want to charge in each
country.
You can also configure listing details such as the app type, category, and content
rating. When you are done configuring options, you can upload your promotional
materials and your app as a draft app.
If you are satisfied that your publishing settings are correctly configured and your
uploaded app is ready to be released to the public, click Publish. Once it has passed
Google Play review, your app will be live and available for download around the world.
When users browse to the download link from their Android-powered devices, the file is
downloaded and the Android system automatically starts installing it on the device.
Note: The installation process will start automatically only if the user has configured their
settings to allow the installation of apps from unknown sources.
Although it is relatively easy to release your app on your own website, it can be inefficient.
For example, if you want to monetize your app, you need to process and track all financial
transactions yourself, and you can't use Google Play's in-app billing service to sell in-app
products. You also can't use app licensing to help prevent unauthorized installation and use of
your app.
Android protects users from inadvertent download and installation of apps from locations
other than a trusted, first-party app store, such as Google Play. Android blocks such installs
until the user opts into allowing the installation of apps from other sources. The opt-in
process depends on the version of Android running on the user's device:
Figure 1. The Install unknown apps system settings screen, where users grant permission
for a particular source to install unknown apps.
On devices running Android 8.0 (API level 26) and higher, users must navigate to
the Install unknown apps system settings screen to enable app installations from a
particular source.
On devices running Android 7.1.1 (API level 25) and lower, users must either enable
the Unknown sources system setting or allow a single installation of an unknown app.
On devices running Android 8.0 (API level 26) and higher, users must grant permission to
install apps from a source that isn't a first-party app store. To do so, they must enable
the Allow app installs setting for that source within the Install unknown apps system
settings screen, shown in figure 1.
Note: Users can change this setting for a particular source at any time. Therefore, a source
that installs unknown apps should always call canRequestPackageInstalls() to check
whether the user has granted that source permission to install unknown apps. If this method
returns false, the source should prompt the user to re-enable the Allow app installs setting
for that source.
Unknown sources
Figure 2. The Unknown sources setting determines whether users can install apps that
aren't downloaded from Google Play.
To permit the installation of apps from non-first-party sources on devices running Android
7.1.1 (API level 25) and lower, users enable the Unknown sources setting
in Settings > Security, as shown in Figure 2.
When users attempt to install an unknown app on a device running Android 7.1.1 (API level
25) or lower, the system sometimes shows a dialog that asks the user whether they want to
allow only one particular unknown app to be installed. In most cases, it is recommended that
users allow only one unknown app installation at a time, if the option is available.
In either case, users need to make this configuration change before they can download and
install unknown apps onto their devices.
In 2024, the expectations for Android developers have increased, requiring a diverse
set of technical and non-technical skills and adherence to best practices. From mastering
modern programming languages to creating scalable, secure, and efficient
applications, Android developers must stay updated with the latest trends and
technologies to deliver high-quality applications.
Android development refers to the process of creating applications that can be installed on
devices that run the Android Operating System. Android, an operating
system developed by Google, is a widely used mobile operating system across the
world, powering millions of smartphones, tablets, smartwatches, and other devices. Android
developers can use languages Java or Kotlin to develop Android applications, which further
has steps like coding, testing, and deployment of apps. The Android development
ecosystem is rich and large and offers features and libraries, that allow developers to create
seamless quality Android applications.
Top 10 Skills For Android Developers in 2024
1. Android Foundations
Android development's core is based on the programming languages Kotlin and Java. Java is
the traditional language for Android apps, while Kotlin offers a simpler, more modern
alternative. Developers should grasp key concepts like syntax, collections, concurrency, and
functional programming. User interfaces are designed using XML, which is linked to
Kotlin/Java files containing the app's logic. Android Studio, the primary development
environment, uses Gradle to manage builds and dependencies. Understanding Gradle's role
in the build process is essential for efficient app development.
Key Points:
2. Android Interactivity
User interaction in Android apps revolves around Activities, which are screens where users
interact with the app. Developers must handle events like gestures, keyboard input, and
screen orientation changes to enhance user experience. Each Activity can exist in portrait or
landscape mode, and maintaining stability during orientation changes is crucial.
Key Points:
3. Android UI
Creating a modern UI involves using layouts and widgets effectively. Developers should follow
Material Design guidelines and use tools like RecyclerView for lists, ConstraintLayout for
complex designs, and animations to enhance user experience. Adapting layouts for different
devices, like tablets and smartphones, is essential, and custom components may be needed
for unique requirements.
Key Points:
4. Implementing Navigation
Effective navigation helps users move through the app seamlessly. Key elements include the
app bar (Toolbar), navigation drawer, and BottomNavigationView. These elements enable
users to switch between screens and access additional features. Intents, both explicit and
implicit, allow for launching new Activities or sharing data between apps.
Key Points:
5. Notifications
Notifications are a powerful tool for boosting user engagement. They are messages that
appear outside your app’s interface to provide reminders, updates, or important information.
Users can tap notifications to open your app or perform actions directly from the notification
itself. To make the most of notifications, you should create and customize them, add
actionable elements, and group multiple notifications using notification channels.
Key Points:
6. Jetpack Compose
Jetpack Compose, is a modern UI toolkit for building native Android applications developed by
Google. Jetpack Compose uses a declarative approach to create user interfaces and
also allows developers to describe UI states and their behavior without worrying
about their complexities. By starting working with Jetpack Compose, developers can
streamline UI development, leverage its powerful features such as state management, and
deliver a seamless experience to users. To leverage its features developers are switching
from the Imperative approach to the Declarative approach.Knowing Jetpack Compose deeper
can help developers to keep themself walk with modern trends.
Key Features
State management
Understanding of Recomposition
Composable lifecycle
Gestures handling
Navigation handling
Managing callbacks
7. MVVM Architecture
Model: The Model is independent of UI and does not interact directly with View or
VireModel.Typically it consists of data classes, data entities, and network API calls.
View: The View component is responsible for displaying the user interface and handles
user interactions. The view can be Activyty, Fragments, or XML layouts.
ViewModel: It contains the business logic, and acts as a messenger between View and
Model. It has its own lifecycle like Fragment and Activity.
8. Jetpack Components
Jetpack components are a collection of libraries, tools, and guidance offered by Google to
facilitate Android developers to build high-quality applications more easily and
efficiently. Jetpack components were introduced to mainly address the issues that
Android developers face in general such as navigation issues, lifecycle-related
issues, simplifying data persistence, and integration of platform API. All these
components are backward compatible, so they can work with a wide range of Android
operating systems. All components are modular which allows developers to adopt only
needed components.
LiveData: Live data is an observable lifecycle-aware data holder class that respects
the lifecycle of other components such as Fragments and Activities. It helps to avoid
memory leaks and crashes that happen due to stale data. LiveData ensures UI
components will update when they are in the activity’s lifecycle.
Navigation: Navigation components simplify the complex navigation flow and ensure
consistence navigation experience across the app. It allows developers to design
navigation graphs to manage navigation within the Android app.
Pagging: Pagging components help in loading and displaying large data sets from local
storage or network APIs in the form of pagination. It loads data in chunks and handles
fetching more data on user scrolls by ensuring a smooth UI experience.
Work Manager: The WorkManager library is used to manage background tasks in the
Android app such as network calls, DB operations, or periodic tasks. WorkManager
guarantees the execution of tasks whether the app exists or not.
9. Dependency Injections
10. Firebase
Authentication
Real-time database
FireStore database
FileStorage
Remote config
Analytics
Dynamic Links
Crash reporting
AdMob Integration
The architecture of Windows Phone is built to be tightly integrated with both hardware and
software, ensuring optimal performance, security, and usability. Let's break down the key
components of the Windows Phone architecture and its workings.
1. Application Layer:
o This layer contains the Native apps (written using C#, XAML, Silverlight or
Windows Runtime) and Web apps (built with HTML, CSS, and JavaScript).
o Apps interact with the system through the Windows Phone Runtime APIs,
using a managed environment provided by the OS.
o The runtime provides APIs for app development, such as file access, networking,
sensors, and multimedia.
o The UI is based on the Metro UI, which is minimalist and tile-based. The Start
screen uses Live Tiles to show dynamic content such as notifications,
messages, and updates.
o This layer also handles the hardware buttons like the Back, Search, and Start
buttons.
5. Security Layer:
o Ensures app sandboxing (isolating apps for security), device encryption, and
secure boot mechanisms, which prevent unauthorized access and malware.
o The core of the system, providing low-level services like memory management,
process scheduling, and hardware abstraction (via the HAL).
7. Hardware Layer:
o Includes the physical components of the device, such as the CPU, GPU,
memory, camera, display, and other sensors.
Boot Process:
When a user powers on a Windows Phone device, the following steps occur:
1. Power On and Bootloader: The device performs the initial hardware checks and
hands control over to the bootloader, which loads the OS from storage.
3. User Interface Loading: After the kernel and system services are initialized, the UI
layer (Metro UI) is loaded, presenting the Start screen with Live Tiles.
4. App Launch: The user interacts with the device, launching apps through the UI. The
app is loaded from storage, and the operating system provides the necessary system
resources (e.g., memory, networking, sensors) for the app to function.
App Execution:
When you launch an app, it interacts with the system in the following way:
1. App Sandbox: The app is isolated within its own sandbox environment. It can only
access resources and data that are specifically allowed by the OS.
2. App API Access: Apps communicate with the OS through Windows Phone Runtime
APIs. These APIs allow access to hardware (like the camera, GPS), networking, sensors,
etc.
4. Notifications and Background Tasks: Apps can send notifications (e.g., incoming
messages or reminders) via the Notification Service. Background tasks allow apps to
periodically perform actions, like syncing data, even when they’re not actively running
on the screen.
Apps are installed from the Windows Phone Store. After the user selects an app, the
following happens:
1. Store API Access: The app is downloaded and installed via the Windows Phone
Store APIs.
2. Installation: The app is placed in the app folder, and required system resources are
allocated (e.g., storage space, permissions).
3. App Lifecycle: Once installed, the app can be launched via the Start screen. The app’s
lifecycle (from launch, execution, to background and termination) is managed by the
operating system.
Windows Phone uses a lightweight multitasking system. While apps can run in the
background, only apps that have permission to run tasks in the background can perform
operations like syncing, location tracking, or playing music.
o App Store Submission: For Android and iOS apps, the primary method of
delivery is through the Google Play Store and Apple App Store. Developers
must ensure that the app complies with the platform’s guidelines, undergoes
rigorous testing, and meets the technical and design standards required for
approval.
o App Distribution Mechanisms: Delivery can also take place via Enterprise
app stores or through Direct APK installations (Android) or enterprise
distribution programs (iOS). These methods are often used for internal or
private apps within organizations.
o Just like Search Engine Optimization (SEO) for websites, App Store
Optimization (ASO) plays a key role in improving the visibility of a mobile
application. ASO involves optimizing the app’s metadata (name, description,
keywords, screenshots, etc.) to increase discoverability in app stores.
o ASO ensures that an app reaches the maximum number of potential users. It
affects rankings in the app stores and plays a crucial role in improving
downloads.
3. App Compatibility
o Device Compatibility: Delivery of mobile apps must account for different types
of mobile devices. Apps should be compatible across a wide range of screen
sizes, hardware configurations, and OS versions.
o Before the app is delivered to the user, it must go through rigorous quality
assurance (QA) testing to ensure that it is bug-free, reliable, and offers a
seamless user experience.
o Automated testing, unit testing, UI testing, and load testing are critical
steps that ensure the app works well in all situations, handles crashes gracefully,
and performs well under varying network conditions.
o Beta Testing: Beta testing allows a select group of users to test the app before
full release. This phase helps identify potential issues and gives insights into user
preferences and the overall performance of the app.
o As mobile apps handle sensitive user data (such as personal, financial, and
location data), ensuring security during the delivery process is of utmost
importance.
o App delivery also requires developers to stay current with security updates and
ensure timely patches for vulnerabilities that could compromise user data.
o The user experience is one of the most crucial factors determining an app’s
success. App delivery involves ensuring that the app is intuitive, user-friendly,
and well-optimized for different device types.
o Performance optimization during the delivery phase ensures that the app loads
quickly, functions smoothly, and uses system resources efficiently (memory,
battery, and CPU). It should also work effectively in low network conditions or
with limited resources.
o The launch of the mobile app is the point at which the app is officially delivered to
the users. The launch should be accompanied by a marketing strategy to
generate buzz and attract downloads.
o Post-launch monitoring is crucial for tracking user feedback, bug reports, app
crashes, and performance issues. Tools like Crashlytics, Google Analytics, and
Firebase help track and measure the app’s success and user engagement.
o Regular app updates improve the app's functionality, fix bugs, and add new
features. Versioning and managing backward compatibility are important to
ensure users receive timely and efficient updates.
o A/B testing and user feedback allow developers to fine-tune the app and
introduce enhancements based on real-world data.
Why Delivery is Important
1. User Adoption and Experience:
o The speed and reliability of the delivery process directly affect the user
adoption rate and their overall experience with the app.
2. Market Visibility:
o The app store ranking and visibility play a key role in app success. Apps that
are delivered well, optimized for the app stores, and promoted effectively tend to
rank higher in search results, leading to more downloads and better market
positioning.
o App Store Optimization (ASO) ensures better visibility, but the delivery process
(timing, launch, marketing, etc.) also significantly impacts how users discover
and engage with the app.
3. Revenue Generation:
o Ensuring the app complies with security and privacy regulations ensures that
users can trust your app and feel comfortable providing personal information.
5. Brand Reputation:
o A well-executed delivery process builds trust in your app and your brand. A poorly
delivered app with glitches, performance issues, or security problems can harm
the brand’s reputation and discourage future users from trying your apps.
o Regular updates and attention to user feedback show that the developer cares
about the app’s ongoing improvement.
Before accessing the GPS, you need to ensure that the application has the appropriate
permissions to use the device's location services.
Android
o Runtime Permission: For Android 6.0 (API level 23) and higher, you need to
request permission at runtime.
xml
Copy code
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
java
Copy code
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
iOS
In iOS, you need to add the appropriate keys to your app's Info.plist file. The keys
explain to the user why the app needs access to their location.
xml
Copy code
<key>NSLocationWhenInUseUsageDescription</key>
<key>NSLocationAlwaysUsageDescription</key>
Once permissions are granted, you can access the GPS functionality and obtain the device's
location using native APIs for both Android and iOS.
Android (Using Google Play Services)
Google Location Services API is used to obtain the device's location in Android. This
provides more accurate and efficient location updates compared to the standard
Android Location Manager API.
To integrate Google Play services, add the dependency in your build.gradle file:
gradle
Copy code
implementation 'com.google.android.gms:play-services-location:18.0.0'
java
Copy code
FusedLocationProviderClient fusedLocationClient =
LocationServices.getFusedLocationProviderClient(this);
fusedLocationClient.getLastLocation()
@Override
if (location != null) {
});
Core Location is the framework used in iOS for location-based services. To start
receiving location updates, you need to use CLLocationManager.
swift
Copy code
import CoreLocation
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
To get the most accurate location information, configure the desired location accuracy in your
app. Mobile devices provide different accuracy levels, and you can specify whether you want
high accuracy (for navigation apps) or a lower accuracy (for battery savings).
Android
java
Copy code
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // or
PRIORITY_BALANCED_POWER_ACCURACY
iOS
swift
Copy code
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters // or
kCLLocationAccuracyBest
Once the location services are set up, you can begin receiving location updates. You can
either get the device’s current location or track location changes continuously, depending on
the requirements of your application.
Single Location Fetch: Get the device’s location once.
Android
java
Copy code
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback,
Looper.getMainLooper());
iOS
swift
Copy code
When tracking location over time, you will need to handle location changes. This could
involve updating the UI or performing background tasks when the user moves. You can use
either foreground updates or background updates depending on the app requirements.
Foreground Updates: The app is active, and you can update the UI with the new
location.
Background Updates: The app is in the background, and you must configure your
app to continue receiving location updates in the background.
Android (Background)
You must declare a background service or use JobIntentService to keep receiving location
updates in the background.
java
Copy code
@Override
};
iOS (Background)
You need to request permission to access location services while the app is in the
background.
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startMonitoringSignificantLocationChanges()
GPS may fail to provide a location due to several reasons, such as poor signal strength, no
permission, or GPS turned off by the user. It’s important to handle these cases appropriately:
Location Unavailable: Provide a fallback mechanism, such as using Wi-Fi or cell tower
data for location.
Permission Denied: Inform the user about why the app needs the location and
request permission again.
No GPS: Provide alternative ways to detect the location, such as IP-based geolocation
or using a map for manual location input.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
} else {
Once you have access to the GPS coordinates (latitude and longitude), you can display the
user's location on a map.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
import MapKit
annotation.coordinate = userLocation
mapView.addAnnotation(annotation)
Conclusion
Integrating GPS into a mobile application provides valuable location-based features. The
process typically involves the following steps:
2. Using platform-specific APIs (Google Location Services for Android and Core Location for
iOS) to access the device's GPS data.
3. Configuring the desired level of accuracy and updating location continuously or once.
By following these steps, you can effectively integrate GPS functionality into your mobile app,
enabling it to provide valuable services like real-time navigation, location tracking, and
geofencing.
Reality: Being open-source does not inherently make Android more secure. While
open-source software allows for transparency, it also allows potential attackers to
review and exploit the code. Android’s openness does allow for greater customization
and flexibility, but it can also lead to more potential vulnerabilities. The security of an
app largely depends on how well the developer codes and implements security best
practices.
Example: A popular open-source Android app might be vulnerable to attacks like Man-
in-the-Middle (MITM) because it uses weak encryption, even though its source code
is visible for review. On the other hand, iOS has a more controlled ecosystem with strict
guidelines, and apps must meet rigorous security standards, reducing the likelihood of
certain types of attacks.
2. Myth: "Android devices are less likely to be hacked due to Google Play's security
mechanisms."
Reality: Google Play does have mechanisms to detect and remove malicious apps (like
Google Play Protect), but these protections are not foolproof. Malicious apps can still
slip through and find their way onto user devices. Also, users often install apps from
third-party sources (non-Google Play stores), which might not be as secure, exposing
them to greater risk.
Example: A popular malicious app like Joker was able to bypass Google Play's
protections for a period, infecting hundreds of thousands of users. This app stole money
by subscribing users to premium services without their knowledge.
Reality: While strong passwords are important, they are only one aspect of app
security. An attacker can bypass password protections using techniques like brute
force attacks or credential stuffing. Moreover, many Android apps do not implement
additional layers of security, such as two-factor authentication (2FA) or encryption
of sensitive data.
Example: If a mobile banking app uses only a password and does not encrypt sensitive
data, an attacker who gains access to the device (e.g., through a root exploit) could
retrieve the unencrypted data, even if the password is strong.
Reality: While regular updates are crucial for maintaining security, many Android
devices do not receive timely updates, especially older models or devices from less-
known manufacturers. Additionally, even if a device is updated, app vulnerabilities can
still exist due to improper coding or lack of secure configurations.
5. Myth: "Permissions granted to an app are not a big concern if the app is from a
trusted source."
Example: The CamScanner app, which was once popular for scanning documents,
was found to contain malicious code that could access a user's files and send them to
remote servers. Although the app was on Google Play and considered trusted, the
unnecessary permissions it requested made it vulnerable to exploitation.
Reality: Many attacks on Android apps do not require physical access to the device.
Remote exploits can be carried out through malicious Wi-Fi networks, phishing, and
app vulnerabilities. Attacks like malware injection or network-based attacks
(e.g., MITM) can be performed remotely.
Example: Stagefright, a vulnerability in Android's media processing system, allowed
attackers to send malicious multimedia messages (MMS) to phones and exploit a
device remotely without needing physical access. This vulnerability affected millions of
devices globally.
7. Myth: "Encryption is only needed for financial apps or apps with sensitive data."
Reality: Encryption should be standard for all Android applications that store any form
of personal or private data, not just for those involving financial transactions. Even
seemingly innocuous apps can store sensitive information such as personal
preferences, login credentials, or health-related data.
Example: An app that tracks fitness or health metrics (such as heart rate or steps)
could be a prime target for hackers if it doesn't properly encrypt user data. This data
might be valuable for identity theft, social engineering, or blackmail.
Example: Tools like APKTool or JADX allow attackers to decompile Android APK files
and inspect the source code. If an app doesn’t properly secure sensitive functions (e.g.,
using hardcoded API keys), attackers can exploit these vulnerabilities by modifying the
app's code.
Android applications are distributed as APK (Android Package) files. These files contain the
compiled code, resources, and manifest of the app. Hackers can reverse-engineer an APK to
decompile and analyze the app's code, looking for vulnerabilities or sensitive data.
o APKTool: A tool used to decompile the APK, providing access to resources and
source code.
o JADX: A decompiler that converts APK code back into readable Java code.
Example: A hacker might download an APK file of a popular app, like a social media app, and
use APKTool to decompile it. Upon inspection, they might find sensitive information
hardcoded into the code (e.g., API keys, usernames, passwords, or even access tokens).
2. Identifying Vulnerabilities
Once the APK is decompiled, the hacker looks for flaws in the code or app behavior. Common
vulnerabilities include:
Hardcoded credentials: Storing passwords, API keys, or sensitive data directly in the
source code.
Example: The hacker might find that the app stores sensitive API keys in plain text within the
app’s resources. This could allow them to directly access the app's backend or servers by
simply extracting the keys.
Hardcoded API Keys: If the app has hardcoded API keys, a hacker can use those keys
to access the app’s backend services, making API calls that should otherwise be
restricted. This might allow them to retrieve user data or manipulate the app's
functionality.
Insecure Data Storage: If the app stores user data (such as passwords) in plaintext
on the device, the hacker can access the device’s storage (either through a physical
connection or a root exploit) and steal this data.
Lack of Proper Encryption: If the app does not encrypt sensitive data before sending
it over the network, the hacker can intercept the data through a Man-in-the-Middle
(MITM) attack on an unsecured Wi-Fi network and gain access to sensitive user
information.
Example: If the app uses weak encryption or no encryption at all for its network traffic, a
hacker might perform a Man-in-the-Middle (MITM) attack on a public Wi-Fi network. Using
tools like Wireshark or Burp Suite, the hacker intercepts data between the app and the
server, capturing usernames, passwords, and session tokens in plain text.
Sometimes, hackers don’t just steal data but modify the app’s behavior. This could involve
changing how the app interacts with the server or the user.
Removing Restrictions: A hacker could modify the app’s code to remove certain
restrictions, such as bypassing in-app purchases, unlocking premium features without
payment, or bypassing authentication checks.
Injecting Malicious Code: Hackers may inject malicious code into the app to perform
unwanted actions, such as logging keystrokes, sending sensitive data to an external
server, or enabling backdoor access.
Example: The hacker may modify the APK to remove the authentication logic entirely,
allowing them to log in to any user account without the need for a password.
After modifying the app, the hacker repackages it into a new APK file and may attempt to
distribute it to unsuspecting users. This is often done by uploading the malicious APK to third-
party app stores or distributing it through phishing tactics.
Example: The hacker may upload the modified version of the app to a third-party app
store or send it via email to potential victims, claiming that it’s a "premium" version of
the original app. When users install the modified app, they unknowingly expose their
data or compromise their devices.
In 2020, Joker, a sophisticated Android malware, was discovered affecting over 1,700 apps
on the Google Play Store. Here's how it worked:
1. Malicious Apps: Joker malware was disguised as legitimate apps, like photo editors,
screen lock apps, and VPNs. These apps requested unnecessary permissions that
seemed harmless to users, such as access to contacts or SMS messages.
2. Exploiting Permissions: Once the app was installed, Joker malware would silently
sign up users for premium SMS services, without their knowledge or consent. It used
SMS and contacts data to carry out fraudulent actions.
3. Repackaging: The malware authors regularly updated the Joker malware, re-uploading
it to the Google Play Store to bypass detection. When users downloaded the infected
app, the malware would run in the background, sending premium-rate SMS messages
that charged the user.
o Impact: Joker infected millions of users worldwide and was able to steal money
by signing users up for fraudulent subscriptions. Despite efforts by Google to
remove the malware, it continued to reappear in new apps.
To protect against Android app hacking, both developers and users need to take precautions:
For Developers:
o Avoid hardcoding sensitive data like API keys or passwords in the code.
o Implement proper encryption for sensitive data both in storage and during
transmission.
For Users:
o Only download apps from trusted sources like the Google Play Store.
o Regularly update apps to ensure they have the latest security patches.
o Use mobile security software that can detect and prevent malicious apps.
Performance refers to how well an app functions in terms of speed, responsiveness, and
resource consumption (e.g., CPU, memory, battery). Addressing performance is vital to
ensure that the app provides a smooth user experience, minimizes lag, and doesn't drain
resources unnecessarily.
o Optimize algorithms: Make sure the code is optimized for performance, using
efficient algorithms and data structures to avoid bottlenecks in processing.
Memory Management:
o Properly manage memory allocation to avoid memory leaks and excessive use
of memory, which could cause crashes or slow performance, especially on lower-
end devices.
o Optimize API calls: Reduce the number of network requests and ensure they
are batched or minimized to optimize the app's network performance.
o Use lightweight data formats (e.g., JSON instead of XML) to reduce payload
size.
o Implement compression for images and files being transmitted over the
network to reduce the amount of data exchanged.
Background Processing:
Device Optimization:
o Consider the variety of devices (screen sizes, CPU capabilities, RAM) when
developing the app and optimize the app accordingly.
Battery Usage:
Scalability refers to the ability of an app to handle increasing numbers of users, data, and
requests without sacrificing performance. A scalable app can handle a growing user base or
workload seamlessly by expanding its resources as needed.
Backend Scalability:
Database Scalability:
o Use distributed databases (e.g., NoSQL databases like MongoDB) that can
scale horizontally by adding more servers or clusters as the app's data grows.
o Use Content Delivery Networks (CDNs) to deliver static content (like images
and videos) quickly to users by caching data on servers located closer to the
user, thus reducing latency and server load.
o Optimize API rate limiting and implement backoff strategies to handle high
traffic and ensure fair access to resources.
Asynchronous Processing:
Security is one of the most important aspects of any mobile application, as it directly impacts
the privacy and protection of users' data. Poor security practices can lead to data breaches,
unauthorized access, or malicious attacks.
Data Encryption:
o Encrypt sensitive data both in transit and at rest. Use HTTPS (SSL/TLS) for all
communication between the app and the server to prevent data interception.
o Use OAuth for secure, token-based authentication, especially for social logins or
integrations with third-party services.
Secure Storage:
Code Obfuscation:
Secure APIs:
o Ensure that backend APIs are secure by implementing proper input validation,
rate limiting, and authentication to prevent misuse.
o Conduct penetration testing and security audits on both the mobile app and
the backend services to identify and address vulnerabilities.
o Keep the app updated with the latest security patches to prevent known
vulnerabilities from being exploited.
User Privacy and Permissions:
o Request only the necessary permissions needed by the app and avoid requesting
sensitive data unless absolutely required. Clearly explain why permissions are
required.
o Implement proper privacy policies and inform users of how their data is being
used and stored.
Secure Communication:
We will follow two different approaches for the testing of mobile applications. Here we will
follow two approaches to test the mobile application, and those are manual testing and
automated testing.
Manual Testing
Manual testing is a human process. The primary focus of manual testing is on the experience
of the user. The Analysis and evaluation of the application's functionality can be done through
the medium of the user in an explorative process. Manual Testing ensures that the application
work on the standard of user-friendliness. Manual testing is generally the time-consuming
process because the process is to find out the bugs will take time. Therefore, according to the
thumb rule, 20% of applications at the time of releases should be tested with the alpha and
beta testing. In the rest part of the application, automated testing should be performed.
Automation Testing
Automated testing is the second approach to test the mobile application. In this process, an
array of test cases is set up. Automated Testing covers 80% of the testing process. The
percentage is not set up, but this is the general guideline followed by the software industry.
We will perform automation testing in the below scenarios-
o When manual test cases are slow, then we will use Automate test cases.
o The test cases which can be easily automated then we will use Automation Testing.
o Automation testing is used for test cases, which is written for the frequently used
functionality.
o Automation testing is used for the automated test cases, which we cannot perform
manually.
o Automation testing is used to automate the test cases, which gives us predictable
results.
Mobile testing has two types that we can perform on mobile devices.
1. Hardware Testing: Hardware testing is done on the internal processors, resolution,
internal hardware, size of the screen, radio, space, camera, Bluetooth or WIFI, etc. This
testing is known as simple "mobile testing."
2. Software Testing or the Application Testing: The functionality of those
applications should be tested, which works on mobile devices. We call this testing as
the "Mobile Application Testing".
1. Native Apps: Native application is used on different platforms like mobile and tablets.
2. Mobile Web Apps: Mobile apps are the server-side apps. We can access the mobile
web apps on mobile by using the different browsers like Chrome, Firefox, after
connecting the mobile to the mobile network or wireless network like WIFI.
3. Hybrid Apps: Hybrid applications are a combination of both types of applications like
native and web applications. Hybrid apps run offline on the devices. Hybrid apps are
written by using the web technologies like HTML5 and CSS.
The following are the types of testing that can be performed on mobile:
o Usability Testing: Usability testing ensures the user that the mobile app is easy to
use and gives a satisfactory experience to the user.
o Interface Testing: Interface testing is done on the menu options, bookmarks, buttons,
history, settings, and the navigation flow of the application.
o Service Testing: Service Testing is done to test the services of the application online
or offline.
o Low-Level resource Testing: This type of testing is done on the memory usage,
auto-detection of the temporary file, growing issue of the local database. The testing of
all the resources is known as Low-Level Resource Testing.
o Operational Testing: Operational Testing will perform to test the backup and recovery
plan when the battery goes down or the loss of the data when we upgrade the
application from the store.
o Security Testing: Security testing is done to test the application to validate the
information to protect it.
While deciding the testing strategy, we should have to ensure that the quality and the
performance guidelines met. Points are as shown below:
1. Selection of the device: During the selection of the device in the first analyses the
market and choose those devices which are widely used these days. The selection of
the device depends on the client.
2. Emulators: The use of the emulator is useful in the initial stage of the development;
the emulator allows us to test the application quickly. An emulator is a system used to
run the software from one environment to another environment without any change in
the software system. The emulator works on the real system.
Browser Emulator: This emulator simulates the environment of the mobile browser.
Operating Systems Emulator: The operating system Apple provides us the emulator
for the iPhones, Google provides the emulator for the Android Phone, and the Microsoft
provides the emulator for Windows Phone.
Deployment can also involve the process of updating an existing app. This can
include releasing new features, fixing bugs, or improving performance. In this case,
deployment involves not only making the new version available, but also ensuring that
existing users can smoothly transition to the updated app.
The first stage of mobile app deployment is preparation. This involves finalizing the app's
code, testing it thoroughly, and packaging it for distribution. The app may also need to be
configured for the intended platform, which can involve setting up servers, databases, and
other backend systems.
The next stage is distribution. This involves making the app available for download, either
through a public app store like Google Play or the Apple App Store, or through a private
distribution method. The app may also need to be registered with the appropriate app store,
which can involve submitting the app for review and approval.
There are several methods of mobile app deployment, each with its own advantages and
disadvantages. The most common method is through a public app store. This is a
straightforward and widely accepted method of distribution, but it can also be time-
consuming and costly, as app stores often charge fees for listing and selling apps.
Another method is private distribution, which involves making the app available for download
directly from the developer's website or through a private app store. This method offers more
control over the distribution process, but it can also be more complex to set up and manage.
There are several platforms available for mobile app deployment, each with its own features
and capabilities. These platforms provide tools and services to help developers prepare,
distribute, and manage their apps.
Some of the most popular mobile app deployment platforms include Google Play for Android
apps, the Apple App Store for iOS apps, and Microsoft Store for Windows apps. These
platforms offer a wide range of tools and services, including app testing, distribution,
analytics, and monetization options.
Google Play
Google Play is the official app store for Android devices. It offers a comprehensive set of
tools for app deployment, including a developer console for managing apps, a
distribution service for making apps available to users, and a review process for
ensuring app quality.
Google Play also offers a variety of monetization options, including in-app purchases,
subscriptions, and ads. It also provides analytics tools for tracking app performance and
user engagement.
The Apple App Store is the official app store for iOS devices. Like Google Play, it offers a
comprehensive set of tools for app deployment, including a developer portal for
managing apps, a distribution service for making apps available to users, and a review
process for ensuring app quality.
The Apple App Store also offers a variety of monetization options, including in-app
purchases, subscriptions, and ads. It also provides analytics tools for tracking app
performance and user engagement.
Another challenge is managing app updates. This involves not only developing and
testing new features, but also ensuring that users can smoothly transition to the new
version of the app. This can be particularly challenging for apps with a large user base,
as any issues can affect a large number of users.
Ensuring app compatibility involves testing the app on a variety of devices and
operating systems. This can be a time-consuming process, as there are many different
combinations to consider. However, it's an essential step in the deployment process, as
it ensures that the app will work correctly for all users.
There are tools available to help with this process, including device emulators and
testing services. These tools can simulate a variety of devices and operating systems,
allowing developers to test their apps in a controlled environment.
Managing app updates involves not only developing and testing new features, but also
ensuring that users can smoothly transition to the new version of the app. This can
involve notifying users of the update, providing instructions for installing it, and
handling any issues that arise during the update process.
There are tools available to help with this process, including update management
services and in-app messaging tools. These tools can automate the update process,
notify users of updates, and provide support for any issues that arise.
What are the various hurdles that are faced during the mobile
app development
There is a large range of different mobile application challenges that an app developer will
face throughout the development lifecycle. This ranges from choosing the best approach to
developing the app, to creating an app that is good enough to stand out in the competitive
market.
So what are the main challenges of mobile app development? Let’s look at the key mobile
problem list.
When starting app development projects, the first matter to consider is choosing the best app
development technology approach.
The real challenges in mobile app development are making sure you decide on the right
decisions in the early stages so that you create the best possible app for your customers. So
let's take a look at some of the development approaches you can take to overcome your
mobile app challenges.
One of these is the fact that native apps often perform much better than other types of
app development and are often extremely reliable and safe, helping meet any mobile
development trend.
However, If you use the native approach, and decide to put your app in an Android mobile
app market, you will have to develop it all over again if you would like your app to be shown
in another marketplace.
The second approach is called cross-platform development. Just like the name suggests,
this development type is perfect for those who are looking to put their apps on a range of
different app marketplaces. Developing Android apps comes with its own set of challenges,
including security issues, app visibility, device fragmentation, and integration of third-party
APIs.
Although it sounds good on paper, there are numerous issues with cross-platform
development. Firstly, there is a huge dependency on the type of framework that is used to
develop the app. As you will have to do all the work on these development platforms that
have a distinct lack of features, you need to ensure it will have everything you will ever need
for the app you are developing.
There are simply many more features that can be worked on and at much faster speed in
native development than in cross-platform. Because of this, teams working on the app
development will often need to work on cross-platform, as well as iOS and Android native
development, making the whole process much more costly and time consuming.
You can also go for hybrid mobile development. This way, apps are developed using standard
forms of coding, like Javascript and CSS that have higher performance than cross-platform
apps.
Hybrid applications consist where elements from native apps and web applications are
combined. They are web apps that have been placed inside a native app shell. This means
that mobile app developers require only one source of code for the app and it will still be
usable on multiple platforms. However, the unfortunate drawback is that a lot of native UX is
sacrificed as a result, along with all the great features in native development that hybrid apps
just can't replicate.
Choosing the right development approach is one of the crucial decisions in creating mobile
products. Be mindful in researching these different types and decide which one is better for
you, based on your needs and goals.
When developing an app, designing a user interface that provides a great user experience
without faults is one of the most important processes and one of the crucial application
development challenges faced by UX designers and programmers. This can often be difficult,
as it needs to meet the best usability practices or it simply won’t be used as much as
competing apps having better user experience.
Great user experience is one of the biggest mobile app design challenges when making
an app. Ease of use, and loading times are just some of the factors that are imperative in
users’ eyes for them to carry on using them otherwise they may go for another mobile
product.
One of the key factors in mobile UX design is ensuring the app works well on a range of
different mobile devices. If it is not compatible with certain popular devices and the screen
size is not catered to this could make the user experience much worse.
This is often one of the toughest challenges faced while testing mobile applications as there
are many different devices and screen sizes, so ensuring the app is compatible with all of
them can be difficult.
Although it is important to develop apps with accessibility as a main focus, there are no
special requirements that need to be met. WCAG, which is the most reliable Web Content
Accessibility Guidelines, suggest that both mobile and desktop apps should all follow all their
requirements in the same way.
Developers will need to constantly monitor the WCAG guidelines to ensure that they are
meeting their requirements at every stage of the process.
There are many iOS, Android, and Windows app development challenges that developers
face when trying to provide the top-notch user experience. Specifically, the Android OS
presents unique challenges such as fragmentation, security vulnerabilities, and the need for
compatibility with various device configurations and versions. Developers have to ensure that
the app is working well on every operating system to ensure a high-quality user experience.
After you have decided on developing a mobile application, you next need to think about the
costs, and how you will be able to afford it. Having a great idea for an app means nothing
when you don't have the funds to make it a reality.
The costs will vary depending on how complicated the app is. For example, apps often
range from $3,000 to $150,000. You need to consider all of this before developing the app.
This is often one of the biggest problems in software development, as it can be difficult to
figure out the costs involved, as well as getting the funding. You can get funding through a
range of different ways. These ways include angel investors, loans, or joint ventures.
Mobile apps are extremely popular, and as such, the mobile market is extremely competitive.
One of the main challenges is app visibility in a crowded market. So how do you develop an
app that stands out from the crowd?
One of the biggest mobile app development challenges is promoting the app. There are
several ways to do this.
One of them is making it discoverable. If people can easily find it on an app marketplace,
they are much more likely to download it. If you’ve created a high-performing app that has a
great user experience but no one can find it, you won’t reach your business goals.
Make sure to look for a mobile app feature list example to find the best ways to promote the
app.