Unit-4
SQLite database
SQLite is an open-source relational database i.e. used to perform database
operations on android devices such as storing, manipulating or retrieving
persistent data from the database.
It is embedded in android by default.
So, it is serverless and zero configuration database engine
SQLite is a opensource SQL database that stores data to a text file on a
device. Android comes in with built in SQLite database implementation.
Database - Helper class
For managing all the operations related to the database , an helper class has been
given and is called SQLiteOpenHelper. It automatically manages the creation and update
of the database. Its syntax is given below
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(){
super(context,DATABASE_NAME,null,1);
}
public void onCreate(SQLiteDatabase db) {}
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {}}
android.database.sqlite package and serves as the primary interface for
interacting with SQLite databases in Android applications.
SQLiteDatabase is a class in the Android SDK that provides a way to
manage databases for storing and querying data locally on an Android
device. It is a part of the Android
Executing SQL Commands: You can execute SQL commands using
methods like execSQL() for non-returning SQL statements or rawQuery() for
returning result sets.
A helper class called SQLiteOpenHelper to manage database creation and version management.
What is a Cursor in Android?
In Android, a Cursor is an interface that provides read-write access to the result set returned by a
database query.
Whenever you query an SQLite database using methods like query(), rawQuery(), or
contentResolver.query() (for content providers), Android returns a Cursor object.
What is SQLite?
SQLite is a lightweight, open-source embedded SQL database engine used in Android. It doesn’t
require a server or separate installation — the database is stored as a single file inside the app’s local
storage.
Basic Operations:
Create/Open a Database
Create Tables
Insert, Update, Delete, Query Data
How to Use SQLite in Android
We use a helper class called SQLiteOpenHelper to manage database creation and version management.
public MyDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
This constructor passes the database name and version to the superclass (SQLiteOpenHelper).
Step-by-Step Example
1. Create SQLite Helper Class
public class MyDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "StudentDB.db";
private static final int DATABASE_VERSION = 1;
// Table and column names
private static final String TABLE_NAME = "students";
private static final String COL_ID = "id";
private static final String COL_NAME = "name";
// This constructor passes the database name and version to the superclass (SQLiteOpenHelper).
public MyDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Called when the database is created for the first time
@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (" +
COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+
COL_NAME + " TEXT)";
db.execSQL(createTable); // execute SQL
}
// Called when the database needs to be upgraded
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
2. Open or Create Database in Activity
MyDatabaseHelper dbHelper = new MyDatabaseHelper(this);
SQLiteDatabase db = dbHelper.getWritableDatabase();
// This line checks whether the database (StudentDB.db) already exists:
If it does not exist, it creates the database and calls onCreate() in MyDatabaseHelper.
If it does exist, it simply opens the database for writing
3. Insert Data
ContentValues values = new ContentValues();//Key-value map used for inserting data into the database.
values.put ("name", "John"); //Adds a row with name = John.
db.insert("students", null, values);// Inserts the values into the students table.
1. Retrieving Data
// db.query : Performs an SQL SELECT query on the "students" table. null (columns): This means select all
// columns (like SELECT * FROM students).
Cursor cursor = db.query("students", null, null, null, null, null, null);
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndexOrThrow("id"));
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
Log.d("DB_RESULT", "ID: " + id + ", Name: " + name);
}
cursor.close();
//getColumnIndexOrThrow("id"): Returns the index of the "id" column or throws an error if it doesn’t exist.
2. Delete row
SQLiteDatabase db = dbHelper.getWritableDatabase(); // This opens (or creates) the database for writing.
// Example: delete where id = 3
String whereClause = "id=?";
String[] whereArgs = new String[]{"3"};
int deletedRows = db.delete("students", whereClause, whereArgs);
Log.d("DELETE", "Deleted rows: " + deletedRows);
Example:
// Executing a simple SQL command
db.execSQL("CREATE TABLE IF NOT EXISTS Users (UserID INTEGER PRIMARY KEY,
UserName TEXT);");
// Inserting data
db.execSQL("INSERT INTO Users (UserName) VALUES ('Alice');");
// Querying data
Cursor cursor = db.rawQuery("SELECT * FROM Users", null);
There are many methods in SQLiteDatabase class. Some of them are as follows:
Method Description
void execSQL(String sql) executes the sql query not select query.
long insert(String table, String inserts a record on the database. The table specifies
nullColumnHack, ContentValues the table name, nullColumnHack doesn't allow
values) completely null values. If second argument is null,
android will store null values if values are empty.
The third argument specifies the values to be
stored.
int update(String table, updates a row.
ContentValues values, String
whereClause, String[] whereArgs)
Cursor query(String table, String[] returns a cursor over the resultset.
columns, String selection, String[]
selectionArgs, String groupBy,
String having, String orderBy)
1. What are Native Libraries?
Native libraries are compiled code libraries written in C or C++ that interact directly with the hardware
or OS at a low level.
These are stored under /system/lib/ or /vendor/lib/ on Android.
Examples:
o libc.so – Standard C library
o libm.so – Math library
o libOpenSLES.so – Audio library
o libGLESv2.so – Graphics
2. What are Header Files?
Header files (.h files) declare the interfaces, functions, constants, and data types that your native
code (C/C++) will use.
They don't contain code themselves.
Think of headers as “contracts” — they tell your C/C++ code what functions and constants are
available in the native libraries.
Why do we need Native Libraries and Headers in Android?
We need them when:
Performance is critical (e.g., games, audio/video processing, real-time apps).
Reusing existing C/C++ libraries (like OpenCV, FFmpeg, SQLite).
Direct access to hardware features or low-level system capabilities.
Where are Native Libraries Used?
Area Example
Game Engines Unity, Unreal use C++ libraries for performance
Media Processing FFmpeg for video/audio encoding
Computer Vision OpenCV for face/object detection
Cryptography OpenSSL for secure communication
Machine Learning TensorFlow Lite (C++ backend)
Hardware Drivers Direct interaction with hardware components
Example: Using a Native C++ Library
// native-lib.cpp (Native C++)
#include <jni.h>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_ndkapp_MainActivity_stringFromJNI(JNIEnv* env, jobject) {
return env->NewStringUTF("Hello from C++!");
}
Header: Defined by JNI and system.
Library: Compiled to .so (shared object), e.g., libnative-lib.so
Use in Java:
static {
System.loadLibrary("native-lib");
}
public native String stringFromJNI();
5. Building Client-Server Applications
Definition:
In client-server architecture:
The client sends requests (mobile app)
The server processes and sends back responses (database, APIs)
Why it’s Used:
Cloud-based storage
Data synchronization
Remote content updates
Example Code (Client using Retrofit):
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
Applications:
Instagram (client requests server for posts)
Banking apps
E-commerce (Flipkart, Amazon)
What is a Content Provider in Android?
A Content Provider is a component of Android that manages access to a structured set of data. It lets
different apps share data securely and consistently — like contacts, messages, media, etc.
Why Do We Need Content Providers?
1. Data Sharing Between Apps
o Apps are sandboxed (private). Content Providers enable controlled access.
o Example: Your WhatsApp app can access your phone contacts via the Contacts content
provider.
2. Abstract Database Access
o It gives a standard API to access data regardless of the storage backend (SQLite, file,
network).
3. Security & Permission Control
o Developers can grant or restrict access to data using permissions.
Where Are Content Providers Used?
Accessing:
o Contacts
o Media files (Images, Audio, Video)
o Call Logs, Messages
Sharing data from your app with other apps.
Syncing data with cloud.
Built-in Android Content Providers
Provider Type URI Example
Contacts content://contacts/people
Images content://media/external/images/media
SMS content://sms/
Content Providers are the standard Android way to store, retrieve, and share structured data.
Useful both within your app and between apps.
Accessed using a ContentResolver and URIs.
Ideal when your app needs to interact with shared/system data.
Registering a Content Provider
To create your own Content Provider:
1. Create a class that extends ContentProvider:
public class MyProvider extends ContentProvider {
// Override methods like insert(), query(), delete(), update()
}
2. Register in AndroidManifest.xml:
<provider
android:name=".MyProvider"
android:authorities="com.example.myprovider"
android:exported="true" />
//authorities is unique name (authority) of your ContentProvider that let other apps use to access this provider.
Working of the Content Provider
UI components of android applications like Activity and Fragments use an
object CursorLoader to send query requests to ContentResolver.
The ContentResolver object sends requests (like create, read, update, and delete) to
the ContentProvider as a client.
After receiving a request, ContentProvider process it and returns the desired result.
Below is a diagram to represent these processes in pictorial form.
What is a URI?
URI stands for Uniform Resource Identifier.
In Android, a ContentProvider uses URIs to let other apps or components access your data.
Using Content Providers (CRUD Operations)
1. Insert Data
ContentValues values = new ContentValues();
values.put("name", "John");
Uri newUri = getContentResolver().insert(MyProvider.CONTENT_URI, values);
2. Retrieve (Query) Data
Cursor cursor = getContentResolver().query(MyProvider.CONTENT_URI, null, null,
null, null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
}
cursor.close();
3. Update Data
ContentValues values = new ContentValues();
values.put("name", "Jane");
String selection = "id=?";
String[] selectionArgs = {"1"};
int rowsUpdated = getContentResolver().update(MyProvider.CONTENT_URI, values,
selection, selectionArgs);
4. Delete Data
String selection = "id=?";
String[] selectionArgs = {"1"};
int rowsDeleted = getContentResolver().delete(MyProvider.CONTENT_URI, selection,
selectionArgs);
Explanations and what exactly happens when each line is executed.
1. Insert Data
ContentValues values = new ContentValues();
values.put("name", "John");
Uri newUri = getContentResolver().insert(MyProvider.CONTENT_URI, values);
Line-by-Line Explanation:
ContentValues values = new ContentValues();
➤ Creates a map-like object to hold key-value pairs for the data you want to insert.
values.put("name", "John");
➤ Puts a value "John" into the column "name" in the ContentValues map.
getContentResolver().insert(...)
➤ Tells Android:
o Use the ContentResolver to talk to the Content Provider identified by
MyProvider.CONTENT_URI.
o Pass the data (values) to it for insertion into the appropriate table.
➤ Returns a Uri to the newly inserted record.
2. Retrieve (Query) Data
Cursor cursor = getContentResolver().query(MyProvider.CONTENT_URI, null, null,
null, null);
getContentResolver().query(...)
➤ Asks the Content Provider to return all data (null = select all columns, no filter).
➤ Returns a Cursor, which lets you move through the result set row by row.
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
}
cursor.moveToNext()
➤ Moves to the next row (returns false if no more rows).
cursor.getString(...)
➤ Retrieves the value of the "name" column in the current row.
cursor.close();
Frees up resources used by the cursor (important to avoid memory leaks).
3. Update Data
ContentValues values = new ContentValues();
values.put("name", "Jane");
Creates a new key-value map where "name" will be changed to "Jane".
String selection = "id=?";
String[] selectionArgs = {"1"};
You define a WHERE clause:
➤ "id=?" is a placeholder for security and flexibility.
➤ "1" is the value substituted into ? → final query becomes:
UPDATE students SET name='Jane' WHERE id=1
int rowsUpdated = getContentResolver().update(MyProvider.CONTENT_URI, values,
selection, selectionArgs);
This line updates the table using the Content Provider:
➤ Looks for record with id = 1
➤ Sets "name" column to "Jane"
➤ Returns number of rows updated (rowsUpdated).
4. Delete Data
String selection = "id=?";
String[] selectionArgs = {"1"};
Same logic as update: target record with id = 1.
int rowsDeleted = getContentResolver().delete(MyProvider.CONTENT_URI, selection,
selectionArgs);
This deletes the row with id = 1 using the Content Provider.
Returns the number of deleted rows.
Persisting Data to Files in Android: Saving to Internal and External Storage
What is Data Persistence in Android?
Data persistence means storing data permanently, even after the app is closed. In Android, this is
done using:
Internal Storage
External Storage
(Others: SharedPreferences, SQLite, Room)
We’ll focus here on saving files to Internal and External storage.
1. Internal Storage
What is it?
Storage space private to your app.
Not accessible by other apps or users.
Deleted when app is uninstalled.
Why use it?
Store sensitive data (e.g., login info, user settings).
Secure: no permission needed.
Code Example
//Save to internal storage
String filename = "mydata.txt";
String data = "Hello Internal Storage!";
try {
FileOutputStream fos = openFileOutput(filename, MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
// Read from internal storage
try {
FileInputStream fis = openFileInput(filename);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
Log.d("INTERNAL_DATA", sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
How to View Internal Storage Files (Using Android Studio):
1. Open Device File Explorer
Open Android Studio
Go to View → Tool Windows → Device File Explorer
2. Navigate to Your App's Data Directory
In the Device File Explorer window:
o Open: /data/data/<your_app_package_name>/files/
o You’ll see files like internal_data.txt if you saved them using openFileOutput().
3. Download/View Files
Right-click the file → Select Save As to download it.
Or double-click to view its contents.
Note: You Can't See It in File Manager as internal storage is sandboxed for privacy and security and It's not
visible in public folders like Downloads or Documents.
2. External Storage
What is it?
Public/shared storage (e.g., SD card or emulated storage).
Accessible to user and other apps.
Requires permissions (for API < 29).
Why use it?
Store media, documents, large files.
Files are persistent even after app is uninstalled.
Permissions (for Android < Q/API 29)
In AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Code Example
// Save to external storage
String data = "Hello External Storage!";
File file = new File(getExternalFilesDir(null), "externaldata.txt");
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(data.getBytes());
fos.close();
Log.d("EXTERNAL_WRITE", "File saved: " + file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
// Read from external storage
try {
File file = new File(getExternalFilesDir(null), "externaldata.txt");
FileInputStream fis = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
Log.d("EXTERNAL_DATA", sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
Graphics
In Android, the Graphics API lets you draw custom shapes, images, gradients, and shadows on the
screen using a Canvas. This is useful for creating games, visual effects, charts, or custom UI
components.
1. What is Canvas in Android?
Canvas is a class in Android that provides a surface (like a sheet of paper) on which you can draw
shapes, text, images, and more.
Why use Canvas?
To create custom views (e.g., signature pad, charts, games).
To draw graphics dynamically instead of using XML.
For animation, game development, and data visualization.
Example:
public class MyCustomView extends View {
Paint paint;
public MyCustomView(Context context) {
super(context);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Set color and draw a circle
paint.setColor(Color.BLUE);
canvas.drawCircle(200, 200, 100, paint);
// Draw a line
paint.setColor(Color.RED);
paint.setStrokeWidth(10);
canvas.drawLine(100, 400, 500, 400, paint);
}
}
To use this, add the view to your layout or create it dynamically:
<com.example.graphicsdemo.MyCustomView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
2. What are Shadows in Android?
Shadows add a depth effect or 3D look by drawing blurred areas behind shapes or text.
Why use Shadows?
To give elevation and visual depth to UI elements.
To make important content stand out.
For realistic graphics and effects.
Example:
paint.setShadowLayer(10, 5, 5, Color.GRAY); // radius, dx, dy, color
canvas.drawText("Hello", 100, 100, paint);
3. What are Gradients in Android?
Gradients are smooth transitions between two or more colors. Android supports:
Linear Gradient (top to bottom, left to right)
Radial Gradient (like a sunburst)
Sweep Gradient (circular sweep)
Why use Gradients?
To make UI visually appealing.
Used in backgrounds, buttons, graphs, and charts.
Better than flat colors for a modern UI feel.
Example:
Shader shader = new LinearGradient(0, 0, 0, 500, Color.RED, Color.BLUE,
Shader.TileMode.CLAMP);
paint.setShader(shader);
canvas.drawRect(0, 0, 500, 500, paint);
Linear Gradient
Radial Gradient
Sweep Gradient