← Back to Tutorials Chapter 4

Core Components

Activities

An Activity represents a single screen with a user interface. It's the entry point for interacting with the user.

// Manifest declaration
<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

// Activity with intent extras
class DetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail)

        val itemId = intent.getIntExtra("ITEM_ID", 0)
        val itemName = intent.getStringExtra("ITEM_NAME") ?: ""
    }
}

// Starting an activity
val intent = Intent(this, DetailActivity::class.java).apply {
    putExtra("ITEM_ID", 42)
    putExtra("ITEM_NAME", "Sample")
}
startActivity(intent)

Fragments

Fragments represent reusable portions of your app's UI. They have their own lifecycle and can be combined in multiple activities.

class HomeFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // Setup UI components
    }
}

// Adding a fragment to an activity
supportFragmentManager.beginTransaction()
    .replace(R.id.fragmentContainer, HomeFragment())
    .addToBackStack(null)
    .commit()

Services

class MusicService : Service() {
    private lateinit var mediaPlayer: MediaPlayer

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            "PLAY" -> playMusic()
            "STOP" -> stopMusic()
        }
        return START_STICKY
    }

    private fun playMusic() {
        mediaPlayer = MediaPlayer.create(this, R.raw.song)
        mediaPlayer.start()
    }

    private fun stopMusic() {
        mediaPlayer?.stop()
        mediaPlayer?.release()
        stopSelf()
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

Broadcast Receivers

class AirplaneModeReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_AIRPLANE_MODE_CHANGED) {
            val isEnabled = intent.getBooleanExtra("state", false)
            Toast.makeText(context,
                "Airplane Mode: ${if (isEnabled) "ON" else "OFF"}",
                Toast.LENGTH_SHORT).show()
        }
    }
}

// Register in manifest
<receiver android:name=".AirplaneModeReceiver">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE" />
    </intent-filter>
</receiver>

Content Providers

class NoteProvider : ContentProvider() {
    private lateinit var dbHelper: SQLiteOpenHelper

    override fun query(uri: Uri, projection: Array<String>?, selection: String?,
        selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
        val db = dbHelper.readableDatabase
        return db.query("notes", projection, selection, selectionArgs,
            null, null, sortOrder)
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        val db = dbHelper.writableDatabase
        val id = db.insert("notes", null, values)
        return ContentUris.withAppendedId(uri, id)
    }
}

Intents & Filters

// Explicit intent - specific component
val intent = Intent(this, DetailActivity::class.java)

// Implicit intent - system resolves component
val webIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://android.com"))
startActivity(webIntent)

// Share intent
val shareIntent = Intent(Intent.ACTION_SEND).apply {
    type = "text/plain"
    putExtra(Intent.EXTRA_TEXT, "Check out this Android app!")
}
startActivity(Intent.createChooser(shareIntent, "Share via"))

// Intent filter in manifest
<activity android:name=".ShareReceiverActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>
Exercise: Create an Android app with two Activities. The first Activity has a list of items (mock data). Clicking an item opens the second Activity showing the item's details. Pass data using Intent extras. Add a Share button in the detail screen using an implicit intent.