--- ## 🛠️ 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). ```kotlin 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) ```kotlin 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**. ```kotlin 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 ``` --- ## 💻 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. ```kotlin 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ô.