ภาพรวม
ตัวอย่างนี้สาธิตการเปิด/ปิดไฟฉาย (Flashlight/Torch) ของกล้องหลังโดยใช้ Camera2 API (CameraManager.setTorchMode) ซึ่งเป็นวิธีมาตรฐานตั้งแต่ Android 6.0 (API 23)
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
เปิด Android Studio เลือก File → New Project
ขั้นตอนที่ 2: Layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Tutorials Point"
android:textAlignment="center"
android:textColor="@android:color/holo_green_dark"
android:textSize="32sp"
android:textStyle="bold" />
<ToggleButton
android:id="@+id/onOffFlashlight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textOff="Turn On Flashlight"
android:textOn="Turn Off Flashlight"
android:checked="false" />
</RelativeLayout>
ขั้นตอนที่ 3: MainActivity.kt
import android.content.Context
import android.content.pm.PackageManager
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraManager
import android.os.Build
import android.os.Bundle
import android.widget.CompoundButton
import android.widget.Toast
import android.widget.ToggleButton
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
private lateinit var cameraManager: CameraManager
private lateinit var cameraId: String
private lateinit var toggleButton: ToggleButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
// ตรวจสอบว่ามี Flashlight หรือไม่
val hasFlash = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)
if (!hasFlash) {
showNoFlashError()
return
}
cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
try {
// ใช้กล้องหลังตัวแรก (มักมี Flash)
cameraId = cameraManager.cameraIdList.first { id ->
val characteristics = cameraManager.getCameraCharacteristics(id)
val facing = characteristics.get(android.hardware.camera2.CameraCharacteristics.LENS_FACING)
facing == android.hardware.camera2.CameraCharacteristics.LENS_FACING_BACK
}
} catch (e: CameraAccessException) {
e.printStackTrace()
Toast.makeText(this, "Cannot access camera", Toast.LENGTH_SHORT).show()
finish()
return
}
toggleButton = findViewById(R.id.onOffFlashlight)
toggleButton.setOnCheckedChangeListener { _, isChecked ->
switchFlashLight(isChecked)
}
}
private fun showNoFlashError() {
AlertDialog.Builder(this)
.setTitle("Oops!")
.setMessage("Flashlight not available on this device")
.setPositiveButton("OK") { _, _ -> finish() }
.show()
}
private fun switchFlashLight(enable: Boolean) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraManager.setTorchMode(cameraId, enable)
}
} catch (e: CameraAccessException) {
e.printStackTrace()
runOnUiThread {
toggleButton.isChecked = !enable // Revert toggle state
Toast.makeText(this, "Failed to toggle flashlight: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
override fun onStop() {
super.onStop()
// ปิดไฟฉายเมื่อแอปไปอยู่ Background
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraManager.setTorchMode(cameraId, false)
}
} catch (e: CameraAccessException) {
e.printStackTrace()
}
}
}
ขั้นตอนที่ 4: Manifest (AndroidManifest.xml)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.flashlight">
<!-- สิทธิ์ Camera (จำเป็นสำหรับ Camera2 API) -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- Feature Flash (บอก Play Store ว่าต้องการอุปกรณ์ที่มี Flash) -->
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<application ... >
<activity android:name=".MainActivity"> ... </activity>
</application>
</manifest>
ขอสิทธิ์ Runtime (Android 6.0+)
Camera เป็น Dangerous Permission ต้องขอใน Runtime:
// ใน onCreate ก่อนใช้ CameraManager
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), CAMERA_PERMISSION_CODE)
} else {
initCamera()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_PERMISSION_CODE && grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initCamera()
} else {
Toast.makeText(this, "Camera permission required", Toast.LENGTH_SHORT).show()
finish()
}
}
หมายเหตุสำคัญ
- ทดสอบบนอุปกรณ์จริงเท่านั้น Emulator ไม่มี Flashlight
- ใช้
FEATURE_CAMERA_FLASHไม่ใช่FEATURE_CAMERA_FRONT(โค้ดเดิมผิด) - ปิดไฟฉายใน
onStop()หรือonDestroy()เพื่อไม่ให้ไฟติดค้าง - บางอุปกรณ์มีหลายกล้อง ต้องเลือก Camera ID ที่มี Flash (ปกติคือกล้องหลัง)
- Android 12+ อาจต้องการ Foreground Service สำหรับ Flashlight แบบค้างนาน
การทดสอบ
รันบนโทรศัพท์จริง กด Toggle Button จะเปิด/ปิดไฟฉายได้