Files
photobooth-app/2_PROJECT_ANDROID.md

8.1 KiB


🛠️ Bước 1: Khởi tạo các file build cấu hình Gradle cho Android

Để Android Studio có thể nhận diện và compile dự án, bạn cần tạo các file cấu hình bằng Kotlin DSL (.gradle.kts) tại thư mục android-project.

1. Tạo file android-project/settings.gradle.kts

File này dùng để khai báo tên dự án và quản lý kho chứa thư viện (Repositories).

pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "RetroPhotobooth"
include(":app")

2. Tạo file android-project/build.gradle.kts (Của thư mục gốc Android)

plugins {
    id("com.android.application") version "8.2.2" apply false
    id("org.jetbrains.kotlin.android") version "1.9.22" apply false
}

3. Tạo file android-project/app/build.gradle.kts (Của module app)

Đây là nơi chúng ta khai báo SDK và các thư viện cần dùng (CameraX, Jetpack Compose hoặc XML Views). Ở đây mình cấu hình sẵn các dependency cho CameraX.

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.photobooth.app"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.photobooth.app"
        minSdk = 26 // Android 8.0 trở lên để hỗ trợ tốt các tính năng đồ họa
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
    buildFeatures {
        viewBinding = true // Bật ViewBinding để thao tác với giao diện dễ dàng
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.11.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")

    // --- Thư viện CameraX Core ---
    val cameraVersion = "1.3.1"
    implementation("androidx.camera:camera-core:$cameraVersion")
    implementation("androidx.camera:camera-camera2:$cameraVersion")
    implementation("androidx.camera:camera-lifecycle:$cameraVersion")
    implementation("androidx.camera:camera-view:$cameraVersion")
    implementation("androidx.camera:camera-extensions:$cameraVersion")
}


📸 Bước 2: Thiết lập Giao diện Chụp ảnh (XML Layout)

Tạo file giao diện hiển thị Camera preview và nút chụp ảnh tại đường dẫn: android-project/app/src/main/res/layout/activity_main.xml (Bạn cần tạo thêm các thư mục res/layout nếu chưa có).

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#121212">

    <!-- Màn hình xem trước Camera -->
    <androidx.camera.view.PreviewView
        android:id="@+id/viewFinder"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="3:4"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/controlPanel" />

    <!-- Bảng điều khiển phía dưới -->
    <RelativeLayout
        android:id="@+id/controlPanel"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="#000000"
        app:layout_constraintBottom_toBottomOf="parent">

        <!-- Nút chụp hình -->
        <ImageButton
            android:id="@+id/btnCapture"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_centerInParent="true"
            android:background="@android:color/transparent"
            android:src="@android:drawable/ic_menu_camera"
            android:contentDescription="Capture Button" />
    </RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>


💻 Bước 3: Viết Code Logic Khởi Tạo CameraX (Kotlin)

Tạo file MainActivity.kt tại đường dẫn android-project/app/src/main/java/com/photobooth/app/MainActivity.kt. Đoạn code này thực hiện xin quyền Camera và kích hoạt kính ngắm.

package com.photobooth.app

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.photobooth.app.databinding.ActivityMainBinding
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var cameraExecutor: ExecutorService

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // Xin quyền Camera
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
        }

        cameraExecutor = Executors.newSingleThreadExecutor()
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // Cấu hình Kính ngắm (Preview)
            val preview = Preview.Builder().build().also {
                it.setSurfaceProvider(binding.viewFinder.surfaceProvider)
            }

            // Chọn Camera Trước (Mặc định cho Photobooth)
            val cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA

            try {
                cameraProvider.unbindAll()
                cameraProvider.bindToLifecycle(this, cameraSelector, preview)
            } catch (xc: Exception) {
                Toast.makeText(this, "Không thể khởi động Camera", Toast.LENGTH_SHORT).show()
            }
        }, ContextCompat.getMainExecutor(this))
    }

    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
    }

    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
    }

    companion object {
        private const val REQUEST_CODE_PERMISSIONS = 10
        private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
    }
}


🏃‍♂️ Việc cần làm ngay lúc này của bạn:

  1. Mở Android Studio trên Debian và thực hiện Import Project, trỏ tới thư mục android-project.
  2. Hệ thống sẽ tự động đồng bộ hóa (Gradle Sync).
  3. Chạy thử nghiệm: Bật Android Emulator (hoặc cắm điện thoại Android của bạn qua cổng USB bật gỡ lỗi ADB) để xem ứng dụng đã hiển thị được Camera lên màn hình chưa.

Khi luồng hiển thị Camera này chạy thành công, chúng ta sẽ chuyển sang code tính năng Đếm ngược tự động chụp liên tiếp 4 tấm và lưu file ảnh thô.