Android -programin-notes
Android -programin-notes
● Applications Layer:
○ Top layer: Native apps (Phone, Contacts) & third-party apps.
○ Built using Android framework APIs.
● Application Framework Layer:
○ High-level Java services for apps.
○ Includes: Activity Manager, Content Providers, Resource Manager, Notification
Manager, View System, Location Manager, etc.
● Libraries and Android Runtime Layer:
○ Native Libraries (C/C++): Core libraries (SQLite, WebKit, OpenGL ES, Media
Framework).
○ Android Runtime (ART): Executes app code (replaces Dalvik). Uses AOT/JIT
compilation. Manages memory (garbage collection).
● Hardware Abstraction Layer (HAL):
○ Standard interface between framework and hardware drivers (e.g., Camera HAL,
Bluetooth HAL). Enables hardware agnosticism.
● Linux Kernel Layer:
○ Foundation: Core system services (Process/Memory/Device Management,
Security, Networking).
● Definition: Integer identifier for each platform version, indicating available APIs.
● Purpose: Manage application compatibility.
● Key Manifest Attributes:
○ minSdkVersion: Minimum API level required to run.
○ targetSdkVersion: API level the app is designed/tested against (influences
behavior). Keep updated.
○ compileSdkVersion: API level used for compilation (usually latest stable).
● Example: Android 13 = API 33. minSdkVersion="21" runs on API 21+.
targetSdkVersion="33" targets Android 13 features.
1. Setup: Install Android Studio, SDK, create New Project ("Empty Activity").
2. Layout (res/layout/activity_main.xml):
○ Defines UI. Modify the default TextView.
<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>
○
3. Activity (java/com.example.myapp/MainActivity.java):
○ Controls the screen. onCreate() is the entry point.
○ setContentView(R.layout.activity_main) links Java/Kotlin to XML layout.
(Code Example - Java):
package com.example.helloworld;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
● View: Basic UI building block (widget); occupies rectangular area, handles drawing and
events (e.g., TextView, Button, ImageView).
● ViewGroup: Container for other Views; defines layout structure (e.g., LinearLayout,
RelativeLayout). Base class for layouts.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username:"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Login"/>
</LinearLayout>
<EditText
android:id="@+id/editTextName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name"/>
<Button
android:id="@+id/buttonCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/editTextName"
android:layout_alignParentLeft="true"
android:text="Cancel"/>
<Button
android:id="@+id/buttonOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/buttonCancel"
android:layout_alignParentRight="true"
android:text="OK"/>
</RelativeLayout>
● Most flexible and powerful layout; default in Android Studio. Part of androidx.
● Creates flat view hierarchies (better performance) by defining constraints between views
and parent.
● Uses visual editor and attributes like app:layout_constraintTop_toTopOf,
app:layout_constraintStart_toEndOf, etc. (values: parent or @id/other_view_id).
● Key Concepts: Constraints, Handles, Bias, Dimensions (0dp for match constraint),
Guidelines, Barriers, Chains.
● Simplest layout; stacks children one on top of the other (last added is topmost).
● Good for holding a single child or overlapping views (e.g., progress indicator over
content).
● Use android:layout_gravity to position children within the frame.
● Containers that make their single child scrollable if its content exceeds the container's
bounds.
● ScrollView: Vertical scrolling.
● HorizontalScrollView: Horizontal scrolling.
● The single child is usually another layout (LinearLayout, ConstraintLayout) holding the
actual content.
● Push Button (Button): Standard clickable text button. Use android:text, handle clicks
via OnClickListener or android:onClick.
(XML): <Button android:id="@+id/myButton" ... android:text="Click Me"/>
● Check Box (CheckBox): Select multiple options or toggle on/off. Use android:text,
android:checked. Listen with OnCheckedChangeListener.
(XML): <CheckBox android:id="@+id/myCheckBox" ... android:text="Enable Feature"/>
Radio Button (RadioButton): Select one option from a set. Must be inside a RadioGroup. Use
android:text, android:checked. Get selection from RadioGroup.
(XML):
<RadioGroup ...>
<RadioButton android:id="@+id/radio1" ... android:text="Option 1"/>
<RadioButton android:id="@+id/radio2" ... android:text="Option 2"/>
</RadioGroup>
● Dropdown list for single selection. Requires an Adapter (like ArrayAdapter) to provide
data.
● Vertically scrollable list. Requires an Adapter to populate items. Efficient for long lists
(renders visible items). Modern alternative: RecyclerView.
● Short-lived popup message for simple feedback. Does not block UI.
(Java):
Toast.makeText(getApplicationContext(), "Operation Complete",
Toast.LENGTH_SHORT).show();
● (See section 2.5.8) Container for vertical scrolling of a single child view.
(Java):
new AlertDialog.Builder(this)
.setTitle("Confirmation")
.setMessage("Are you sure?")
.setPositiveButton("Yes", (dialog, which) -> { /* Action for Yes */ })
.setNegativeButton("No", null) // Dismisses dialog
.show();
(Java):
Calendar cal = Calendar.getInstance();
// ... get current year, month, day ...
DatePickerDialog dateDialog = new DatePickerDialog(this,
(view, year, month, dayOfMonth) -> {
// month is 0-based; Use selected year, month+1, dayOfMonth
}, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
dateDialog.show();
(Java):
Calendar cal = Calendar.getInstance();
// ... get current hour, minute ...
boolean is24Hour = android.text.format.DateFormat.is24HourFormat(this);
TimePickerDialog timeDialog = new TimePickerDialog(this,
(view, hourOfDay, minute) -> {
// Use selected hourOfDay, minute
}, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), is24Hour);
timeDialog.show();
● Use your own XML layout inside a dialog. Inflate the layout and set it using
AlertDialog.Builder.setView().
(Java - Conceptual):
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.custom_dialog_layout, null);
builder.setView(dialogView);
// ... Find views inside dialogView (EditText, etc.) ...
builder.setTitle("Custom Dialog");
builder.setPositiveButton("OK", (dialog, which) -> { /* Use custom view data */ });
// ...
AlertDialog dialog = builder.create();
dialog.show();
UNIT 4: ADAPTER AND MENU
● Concrete adapter for arrays or Lists. Simple for basic TextView items.
(Java - Conceptual):
// 1. Get ListView from layout
ListView listView = findViewById(R.id.myListView);
// 2. Prepare data (e.g., ArrayList<String> items)
// 3. Create Adapter (e.g., ArrayAdapter)
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
items);
// 4. Set Adapter on ListView
listView.setAdapter(adapter);
// 5. Set OnItemClickListener (optional)
4.4 GridView using Adapter
(Java - Conceptual):
// 1. Get GridView from layout
GridView gridView = findViewById(R.id.myGridView);
// 2. Prepare data (e.g., ArrayList<MyObject> data)
// 3. Create custom Adapter (e.g., extending BaseAdapter)
MyCustomGridAdapter adapter = new MyCustomGridAdapter(this, data);
// 4. Set Adapter on GridView
gridView.setAdapter(adapter);
// 5. Set OnItemClickListener (optional)
(Java - Conceptual):
new Thread(() -> {
// Long work here...
final String result = performLongOperation();
// Post result back to UI thread (using Handler or runOnUiThread)
runOnUiThread(() -> {
// Update UI here (e.g., myTextView.setText(result))
});
}).start();
(Java - Skeleton):
private class MyAsyncTask extends AsyncTask<Void, Integer, String> {
@Override protected void onPreExecute() { /* Show progress */ }
@Override protected String doInBackground(Void... voids) {
// Long work... publishProgress(percentComplete); ... return result;
}
@Override protected void onProgressUpdate(Integer... values) { /* Update progress bar */ }
@Override protected void onPostExecute(String result) { /* Hide progress, show result */ }
}
(Java - Skeleton):
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
// Handle boot completed - maybe start a service
}
// ... check other actions ...
}
}
5.5 Services
● Two main paths: Started (via startService) and Bound (via bindService).
● Started Lifecycle: onCreate() -> onStartCommand() (called for each startService) ->
(running) -> onDestroy(). Service runs until stopSelf() or stopService() is called.
● Bound Lifecycle: onCreate() -> onBind() (returns IBinder for interaction) -> (clients
bound) -> onUnbind() -> onDestroy(). Service lives as long as clients are bound (unless
also started).
● onBind(): Returns IBinder interface for client communication.
● onStartCommand(): Receives Intent from startService(); return value (START_STICKY,
etc.) dictates restart behavior if killed.
5.6 Notification
● UI alerts displayed outside the app (status bar, notification drawer, heads-up).
● Requires: NotificationManager, NotificationCompat.Builder (from AndroidX),
NotificationChannel (API 26+).
● Steps (API 26+):
1. Create Notification Channel: Define channel ID, name, importance. Do this
once (e.g., in Application class).
2. Create PendingIntent: Intent to fire when notification is tapped (e.g., open
Activity). Use PendingIntent.FLAG_IMMUTABLE.
3. Build Notification: Use NotificationCompat.Builder - set small icon (mandatory),
title, text, priority, content intent, channel ID, etc.
4. Issue Notification: Get NotificationManagerCompat, call notify(notificationId,
builder.build()). Requires POST_NOTIFICATIONS permission on Android 13+.
● System service to schedule code execution (via PendingIntent) at a future time, even if
app isn't running.
● Types: ELAPSED_REALTIME (time since boot), RTC (wall-clock time). Use _WAKEUP
variants to wake the device.
● Exact vs. Inexact: Use setExact(), setExactAndAllowWhileIdle() for precise timing
(needs SCHEDULE_EXACT_ALARM permission on Android 12+). Prefer
setInexactRepeating() or set() for battery efficiency when precision isn't critical.
WorkManager is often better for deferrable tasks.
● Usage: Get AlarmManager, create PendingIntent (for BroadcastReceiver/Service), call
set...() method.
● Cancel: alarmManager.cancel(pendingIntent).
● Note: Alarms cancelled on reboot; use BOOT_COMPLETED receiver to reschedule if
needed.
(Use implicit Intents; Requires Manifest permissions and often runtime checks).
● Purpose: Standard interface to manage and share app data securely. Abstracts
underlying storage.
● Key Concepts:
○ Content URI: Uri identifying data: content://<authority>/<path>/<optional_id>.
Authority is unique name (e.g., com.android.contacts).
○ ContentResolver: Client object (getContentResolver()) used to interact with
providers (query, insert, update, delete).
● Usage: Access system providers (Contacts, MediaStore) or create your own by
extending ContentProvider and implementing its methods. Register in Manifest with
authority and permissions.
● Android's built-in relational database engine. Stored in app's private directory. Accessed
via SQL.
6.3 SQLiteOpenHelper
6.4 SQLiteDatabase
6.5 Cursor
(Java - Iteration):
Cursor cursor = db.query(...);
try {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
// ... process data ...
}
} finally {
if (cursor != null) cursor.close();
}
● Use SQLiteDatabase methods (insert, update, delete) with ContentValues for data and
whereClause/whereArgs for targeting rows.
● Or use ContentResolver methods (insert, update, delete) with a Content URI and
ContentValues/whereClause/whereArgs.
Prerequisites: Setup Google Cloud Project, enable Maps SDK for Android, get API key, restrict
key, add key to Manifest, add dependencies (play-services-maps, play-services-location).
7.1.2 Obtaining the Maps API Key: (Covered by prerequisites - Cloud Console setup &
Manifest entry)
(XML - Manifest Snippet):
xml <application ...> <meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY_HERE"/> </application>