IT272 Mobile Application Development

Mobile Application DevelopmentUnit 98 min read

Notifications, Background Services & Android WorkManager

Unit 9 of Mobile Application Development explores how to implement notifications (channels, types, actions), background services (foreground vs. background, constraints), and WorkManager for deferred tasks—critical for apps like eSewa’s payment reminders or Pathao’s ride updates.

Core Concepts

1. Notifications: The User’s Alert System

Notifications inform users of events without requiring them to open the app. They appear in the status bar and can expand into a full card.

Types of Notifications

mindmap
  root((Notifications))
    Types
      Basic: Title, text, icon
      Actionable: Buttons (e.g., "Dismiss" or "Reply")
      Messaging: Conversation-style (e.g., WhatsApp)
      Media: Play/pause controls (e.g., YouTube)
      Progress: Indeterminate/determinate (e.g., file upload)
    Channels
      High-priority: Urgent (e.g., "New Message")
      Low-priority: Less critical (e.g., "Reminder")
      Custom: App-defined (e.g., "Order Status")
    Permissions
      Required: `POST_NOTIFICATIONS` (Android 13+)
      Best Practice: Request at install time

How Notifications Work

  1. Create a Notification Channel (Android 8+):
    NotificationChannel channel = new NotificationChannel(
        "order_updates", "Order Status", NotificationManager.IMPORTANCE_LOW
    );
    NotificationManager manager = getSystemService(NotificationManager.class);
    manager.createNotificationChannel(channel);
    
  2. Build a Notification:
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "order_updates")
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle("Your Order #12345")
        .setContentText("Preparing...")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    
  3. Show the Notification:
    NotificationManagerCompat.from(this).notify(1, builder.build());
    

Real-World Example: Pathao Ride Updates

Pathao uses progress notifications to show:

  • Rider assigned (setContentText("Rider: Ram, 5 min away")).
  • ETA updates (setProgress(75, 100, false)).
  • Arrival (setContentText("Arrived! Tap to rate.")).

Visual: Notification States


2. Background Services: Keeping Apps Alive

Background services perform tasks without a user interface. Android restricts them to prevent battery drain.

Foreground vs. Background Services

Feature Foreground Service Background Service (WorkManager)
Visibility Status bar icon (e.g., music player) Hidden (e.g., syncing data)
Battery Impact High (must justify) Low (optimized by Android)
Use Case Long-running (e.g., GPS tracking) Short/periodic (e.g., cache refresh)
API Requirement startForeground() WorkManager.enqueue()

Foreground Service Example: eSewa Payment Reminder

// Start a foreground service for payment reminders
Intent serviceIntent = new Intent(this, PaymentReminderService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(serviceIntent);
} else {
    startService(serviceIntent);
}

// Inside PaymentReminderService:
@Override
public void onCreate() {
    Notification notification = new NotificationCompat.Builder(this, "payments")
        .setContentTitle("eSewa Payment Due")
        .setContentText("Your bill is pending. Tap to pay.")
        .setSmallIcon(R.drawable.ic_payment)
        .build();
    startForeground(1, notification);
}

Visual: Foreground Service Lifecycle

flowchart LR
  A["User Opens App"] --> B["Service Starts"]
  B --> C["Notification Shown"]
  C --> D["Service Runs in Foreground"]
  D --> E["User Dismisses Notification"]
  E --> F["Service Stops"]

3. WorkManager: Reliable Background Tasks

WorkManager schedules deferred tasks (e.g., syncing data when the app is closed or the device is charging).

Key Features

  • Constraints: Run only when:
    • Device is charging (ChargingConstraint).
    • Network is available (NetworkConstraint).
    • Battery level is high (BatteryNotLow).
  • Retry Policies: Automatic retries with exponential backoff.
  • Chaining: Sequential or parallel task execution.

Example: Daraz Order Sync

// Schedule a sync task for Daraz orders
Constraints constraints = new Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .build();

OneTimeWorkRequest syncRequest = new OneTimeWorkRequest.Builder(SyncWorker.class)
    .setConstraints(constraints)
    .setInitialDelay(1, TimeUnit.HOURS) // Delay for 1 hour
    .build();

WorkManager.getInstance(this).enqueue(syncRequest);

Visual: WorkManager Execution Flow

flowchart TD
  A["Task Scheduled"] --> B{"Constraints Met?"}
  B -->|"Yes"| C["Worker Executes"]
  B -->|"No"| D["Waits for Conditions"]
  C --> E["Syncs Orders"]
  E --> F["Completes or Retries"]

4. Notifications vs. Background Services: When to Use Which

Scenario Recommended Approach
User needs immediate attention Notification (e.g., WhatsApp)
Long-running task (e.g., download) Foreground Service
Periodic sync (e.g., weather app) WorkManager
Silent background updates WorkManager

5. Best Practices

  1. Notifications:
    • Use channels (Android 8+).
    • Avoid spammy notifications (respect user privacy).
    • Provide actions (e.g., "Reply" or "Dismiss").
  2. Background Services:
    • Prefer WorkManager over raw Service for most tasks.
    • Justify foreground services with a persistent notification.
  3. Battery Efficiency:
    • Use setForeground(false) when possible.
    • Limit WorkManager task frequency.

In the Real World

  1. eSewa:
    • Uses foreground services for payment reminders (e.g., "Your bill is due in 3 days").
    • Shows a persistent notification until the user pays or dismisses it.
  2. Pathao:
    • Progress notifications update riders in real-time (e.g., "Your ride is 2 minutes away").
    • WorkManager syncs ride history when the app is closed.
  3. Ncell:
    • Actionable notifications let users recharge directly (e.g., "Tap to top-up").
    • Background services monitor data usage and send alerts when limits are near.

Exam Tip

  • Notifications:
    • Remember: Channels are mandatory on Android 8+. Always create them in onCreate().
    • Know the priority levels (IMPORTANCE_HIGH, IMPORTANCE_LOW).
  • Background Services:
    • Foreground services require a notification. Never start one without it.
    • WorkManager is preferred for most background tasks. Know its constraints (ChargingConstraint, NetworkConstraint).
  • Common Pitfalls:
    • Forgetting to request POST_NOTIFICATIONS permission (Android 13+).
    • Starting a foreground service without a notification (app will crash).
    • Using raw Service instead of WorkManager (higher battery drain).

Worked Example: Kathmandu Traffic Route Updates Imagine an app that tracks traffic in Kathmandu and notifies users of delays. Here’s how it would use WorkManager + Notifications:

  1. WorkManager Task:
    • Checks traffic data every 30 minutes (setPeriodic(30, TimeUnit.MINUTES)).
    • Constraints: Only runs when the device is charging or plugged in.
  2. Notification:
    • If traffic is heavy on the user’s route, it shows:
      NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "traffic")
          .setContentTitle("Heavy Traffic Ahead!")
          .setContentText("Route to Thapathali via Ring Road is delayed by 20 mins.")
          .addAction(R.drawable.ic_alternate_route, "Find Alternative", pendingIntent);
      
  3. User Action:
    • Tapping "Find Alternative" opens a map with rerouting options.

Visual: Traffic App Workflow

sequenceDiagram
  participant User
  participant App
  participant WorkManager
  participant TrafficAPI

  User->>App: Opens app (or closes it)
  App->>WorkManager: Schedules traffic check
  WorkManager->>TrafficAPI: Fetches real-time data
  TrafficAPI-->>WorkManager: Returns delay info
  WorkManager->>App: Triggers notification
  App->>User: Shows "Heavy Traffic Ahead!"
  User->>App: Taps "Find Alternative"
  App->>User: Opens map with new route

Based on the TU BITM syllabus for Mobile Application Development (IT272), unit 9.

Discussion

Loading…