6. Android Application Components

Android applications are built using core components that define their functionality and behavior. These components, working together, form the backbone of every app. They are defined in the AndroidManifest.xml file, which acts as a blueprint for the application.

1. Activities (UI)

An Activity in Android represents a single, focused screen that users interact with. It acts as the entry point for user interactions and forms the core of an app’s user interface (UI). Each activity displays a specific layout and provides the logic to handle user interactions, such as button clicks or gestures.

Key Features of Activities

  1. **Lifecycle Management**: Activities have a well-defined lifecycle managed by the Android operating system. This lifecycle includes states like: - Created: When the activity is first initialized.

    • Started: When it becomes visible to the user.

    • Resumed: When it is in the foreground and actively interacting with the user.

    • Paused: When another activity partially obscures it.

    • Stopped: When it is no longer visible.

    • Destroyed: When the activity is removed from memory. These states ensure efficient use of system resources and allow activities to handle user interruptions gracefully.

  2. UI Design: Each activity is associated with an XML layout file that defines the visual structure (buttons, text fields, etc.) of the screen.

    • Example: A login activity might have text fields for username and password, along with a "Login" button.

  3. Interaction with Users: Activities handle user inputs like taps, swipes, and gestures. The logic to respond to these actions is implemented in the activity's Java/Kotlin code.

  4. Communication with Other Components: Activities can directly interact with other app components, such as services or fragments, to perform tasks or share data.

Types of Activities

  1. Main Activity:

    • The entry point of the app, specified in the AndroidManifest.xml file.

    • Typically the first screen users see when launching the app.

  2. Sub Activities:

    • Secondary screens that provide additional functionality.

    • Example: A settings screen or a product details page.

Simple Java example of an Android Activity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Find the Button by its ID
        Button clickMeButton = findViewById(R.id.clickMeButton);

        // Set a click listener for the Button
        clickMeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Display a short message when the Button is clicked
                Toast.makeText(MainActivity.this, "Button Clicked!", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

2. Services

A Service in Android is a component that runs in the background to perform long-running operations or to handle tasks that do not require a UI. It is independent of the activity lifecycle, so it continues running even if the activity is destroyed. Services can be used to perform background tasks such as playing music, fetching data from the network, or running periodic tasks.

Types of Services:

  1. Started Service:

    • A service is started when an application component (like an activity) starts it using startService().

    • Once started, it runs indefinitely in the background until it is stopped by calling stopService() or stopSelf().

    • Example: Playing music or downloading a file.

  2. Bound Service:

    • A service is bound when an application component binds to it using bindService().

    • The service runs only as long as there are active clients bound to it. Once all clients unbind, the service stops.

    • Example: A service providing an API for other components (such as providing data to an activity).

Life Cycle of a Service:

  1. onCreate(): Called when the service is first created. You can use this method to initialize resources or set up connections.

  2. onStartCommand(): Called when the service is started using startService(). It defines what action the service will perform.

  3. onBind(): Called when the service is bound to a client (using bindService()).

  4. onUnbind(): Called when the service is unbound from all clients.

  5. onDestroy(): Called when the service is destroyed or stopped.

Example of a Simple Service (Java):

1. Simple Started Service:

public class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Perform background task here
        Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();

        // Return START_STICKY to keep the service running
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null; // This service is not bound
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
    }
}

2. Starting the Service from an Activity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button startServiceButton = findViewById(R.id.startServiceButton);

        startServiceButton.setOnClickListener(v -> {
            Intent intent = new Intent(MainActivity.this, MyService.class);
            startService(intent); // Start the service
        });
    }
}

Explanation:

  1. MyService is a simple service that shows a toast message when created, started, or destroyed. It runs indefinitely after being started and can perform background tasks.

  2. The MainActivity has a button. When clicked, it starts the service using startService().

  3. The service performs some action in the background and displays toasts when certain lifecycle methods are triggered.

Manifest Declaration:

Don't forget to declare the service in the AndroidManifest.xml file:

<service android:name=".MyService" />

3. Broadcast Receivers

A Broadcast Receiver in Android is a component that allows the application to listen for system-wide or application-specific broadcast messages. These broadcasts are events or intents sent by the Android system or other apps.

Broadcast Receivers enable applications to respond to these messages even if the application is not running in the foreground.

Key Features:

  1. System-Wide Broadcasts: Triggered by system events like battery changes, device boot, network connectivity, etc.

  2. Custom Broadcasts: Sent by apps to communicate events or notify other components.

Lifecycle of a Broadcast Receiver:

  • A Broadcast Receiver doesn’t run continuously.

  • It is triggered only when it receives a broadcast message and remains active only for a short duration to handle the event.

  • Once the event is handled, it is terminated.

Types of Broadcast Receivers:

  1. Static Broadcast Receivers:

    • Declared in the AndroidManifest.xml.

    • Registered at application install time.

    • Always active as long as the app is installed.

  2. Dynamic Broadcast Receivers:

    • Registered programmatically at runtime using registerReceiver().

    • Active only while the app or activity is running.

Examples of System Broadcasts:

  1. Battery Low: Intent.ACTION_BATTERY_LOW

  2. Device Boot Completed: Intent.ACTION_BOOT_COMPLETED

  3. Network Connectivity Change: ConnectivityManager.CONNECTIVITY_ACTION

Steps to Implement a Broadcast Receiver:

1. Static Broadcast Receiver Example

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // Handle the broadcast event
        String action = intent.getAction();
        if (action != null) {
            Toast.makeText(context, "Broadcast Received: " + action, Toast.LENGTH_SHORT).show();
        }
    }
}

Register in AndroidManifest.xml:

<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

2. Dynamic Broadcast Receiver Example

public class MainActivity extends AppCompatActivity {

    private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Handle network connectivity change
            Toast.makeText(context, "Network connectivity changed!", Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Register the dynamic receiver
        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Unregister the dynamic receiver
        unregisterReceiver(networkReceiver);
    }
}

Use Cases for Broadcast Receivers:

  1. Listening for System Events:

    • Battery status, network changes, charging status, etc.

  2. Application-Specific Notifications:

    • Notify other components about specific events in the app.

  3. Custom Communication:

    • Custom events triggered between activities, services, or other apps.


4. Content Providers

A Content Provider in Android is a component that manages access to a structured set of data. It provides a mechanism for sharing data between different applications or within the same application. Content Providers use a URI (Uniform Resource Identifier) to uniquely identify data and allow CRUD (Create, Read, Update, Delete) operations on the data.

Key Features of Content Providers:

  1. Data Sharing:

    • Enable applications to share data securely with other apps.

    • Commonly used for accessing contacts, media files, and other shared data.

  2. Data Management:

    • Use SQLite databases, files, or any other persistence storage mechanism as a backend.

  3. Standardized Access:

    • Provides a uniform way to query and manipulate data using URIs and ContentResolvers.

  4. Security:

    • Access to data is controlled by permissions defined in the manifest.

Content Provider URI Structure:

The URI is composed of the following parts:

content://<authority>/<path>/<id>

Example URI:
content://com.android.contacts/contacts/1
  • content:// → Scheme used by content providers.

  • authority → The unique name of the content provider (usually the package name).

  • path → The data type (e.g., "contacts", "images").

  • id → The specific data item (optional).

Steps to Implement a Content Provider:

1. Create a Content Provider MyContentProvider.java:

public class MyContentProvider extends ContentProvider {

    @Override
    public boolean onCreate() {
        // Initialize data storage (e.g., SQLite database)
        return true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection,
                        @Nullable String selection, @Nullable String[] selectionArgs,
                        @Nullable String sortOrder) {
        // Handle data query
        return null; // Return a Cursor with the requested data
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        // Return the MIME type of data
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        // Handle data insertion
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection,
                      @Nullable String[] selectionArgs) {
        // Handle data deletion
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values,
                      @Nullable String selection, @Nullable String[] selectionArgs) {
        // Handle data update
        return 0;
    }
}

2. Register the Content Provider in AndroidManifest.xml

<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="true"
    android:grantUriPermissions="true" />

3. Access Data Using ContentResolver

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Access content provider
        ContentResolver resolver = getContentResolver();
        Uri uri = Uri.parse("content://com.example.myapp.provider/table_name");
        Cursor cursor = resolver.query(uri, null, null, null, null);

        if (cursor != null) {
            while (cursor.moveToNext()) {
                // Retrieve data from the cursor
                String columnValue = cursor.getString(cursor.getColumnIndex("column_name"));
            }
            cursor.close();
        }
    }
}

5. Intents and Intent Filters in Android

Intents and Intent Filters are essential components of Android that allow communication between application components or different applications.

1. Intents

An Intent is a messaging object used to request an action from another component or application. It acts as a bridge that helps in passing data or instructions between components (e.g., Activity, Service, BroadcastReceiver).

Types of Intents

  1. Explicit Intent:

    • Targets a specific component by name (Activity or Service).

      • Used within the same application for direct communication.

      • Example: Navigating to another Activity. Code Example:

      Intent intent = new Intent(MainActivity.this, SecondActivity.class);
      intent.putExtra("message", "Hello from MainActivity");
      startActivity(intent);
  2. Implicit Intent:

    • Does not specify the target component.

    • The system determines which component can handle the request based on the Intent Filters declared in the manifest.

    • Example: Sharing text or opening a URL in a browser. Code Example:

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse("<https://www.google.com>"));
    startActivity(intent);

Common Use Cases of Intents

  • Starting an Activity or Service.

  • Delivering a broadcast message.

  • Passing data between components.

  • Opening system features (e.g., camera, browser).

2. Intent Filters

An Intent Filter defines how the system should match an implicit intent to the components in an application. Components register Intent Filters in the manifest to indicate the actions they can handle.

Intent Filter Attributes

  1. Action: Describes the operation to be performed (android.intent.action.VIEW).

  2. Data: Specifies the type of data the component can handle (http://, content://).

  3. Category: Adds additional information about the component that can handle the intent (android.intent.category.DEFAULT).

Code Example: Intent Filter in Manifest

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http" android:host="www.example.com" />
    </intent-filter>
</activity>

How It Works:

  • If an app sends an implicit intent with ACTION_VIEW and data starting with http://www.example.com, the system will launch SecondActivity.

Examples of Actions, Categories, and Data

Component

Description

Actions

ACTION_VIEW, ACTION_SEND, ACTION_CALL

Categories

CATEGORY_DEFAULT, CATEGORY_BROWSABLE

Data Schemes

http, https, tel, geo, content

3. Passing Data with Intents

You can pass additional data using the putExtra() method. Example:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("username", "JohnDoe");
startActivity(intent);

To retrieve the data in SecondActivity:

String username = getIntent().getStringExtra("username");

4. Starting Activities for Results

You can use Intents to start another Activity and get a result back. Example:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivityForResult(intent, REQUEST_CODE);

To handle the result:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        String result = data.getStringExtra("result");
    }
}

5. Broadcast Intents

Intents can also be used for broadcasting messages. Example:

Intent intent = new Intent("com.example.CUSTOM_INTENT");
sendBroadcast(intent);

Last updated