ภาพรวม
ตัวอย่างนี้สาธิตการถ่ายภาพโดยใช้ Camera App ของระบบผ่าน MediaStore.ACTION_IMAGE_CAPTURE Intent และรับภาพคืนมาแสดงใน ImageView
ขั้นตอนที่ 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_above="@id/imageView"
android:layout_centerInParent="true"
android:layout_marginBottom="10dp"
android:text="Tap button to take photo from camera"
android:textAlignment="center"
android:textColor="@android:color/holo_purple"
android:textSize="16sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@id/btnCaptureImage"
android:layout_marginTop="16dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:src="@drawable/ic_baseline_image_24" />
<Button
android:id="@+id/btnCaptureImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Capture Image" />
</RelativeLayout>
ขั้นตอนที่ 3: MainActivity.kt
import android.Manifest
import android.content.ContentValues
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
private lateinit var imageView: ImageView
private lateinit var button: Button
private var imageUri: Uri? = null
// ใช้ Activity Result API (สมัยใหม่ แทน onActivityResult)
private val takePictureLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
imageUri?.let { uri ->
imageView.setImageURI(uri)
}
} else {
Toast.makeText(this, "Photo capture cancelled", Toast.LENGTH_SHORT).show()
}
}
private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (granted) {
openCamera()
} else {
Toast.makeText(this, "Camera permission denied", Toast.LENGTH_SHORT).show()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
imageView = findViewById(R.id.imageView)
button = findViewById(R.id.btnCaptureImage)
button.setOnClickListener {
checkPermissionAndOpenCamera()
}
}
private fun checkPermissionAndOpenCamera() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
}
}
private fun openCamera() {
// สร้าง URI สำหรับเก็บรูป (ใช้ MediaStore)
val values = ContentValues().apply {
put(MediaStore.Images.Media.TITLE, "New Picture")
put(MediaStore.Images.Media.DESCRIPTION, "From Camera App")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/${getString(R.string.app_name)}")
}
}
imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
// ให้ผลลัพธ์คุณภาพสูง
putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
}
// ตรวจสอบว่ามี App รองรับ Intent นี้
if (cameraIntent.resolveActivity(packageManager) != null) {
takePictureLauncher.launch(cameraIntent)
} else {
Toast.makeText(this, "No camera app found", Toast.LENGTH_SHORT).show()
}
}
}
วิธีเก่า (Deprecated) - onActivityResult
// Deprecated ใน API 30+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_CAPTURE_CODE && resultCode == RESULT_OK) {
imageUri?.let { imageView.setImageURI(it) }
}
}
ขั้นตอนที่ 4: Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.cameraapp">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<application ... >
<activity android:name=".MainActivity"> ... </activity>
<!-- สำหรับ Android 10+ (Scoped Storage) -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
file_paths.xml (res/xml/file_paths.xml)
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="https://schemas.android.com/apk/res/android">
<external-files-path name="camera_photos" path="Pictures/" />
<external-cache-path name="camera_cache" path="." />
</paths>
หมายเหตุสำคัญ
- ทดสอบบนอุปกรณ์จริงเท่านั้น Emulator จำลองกล้องได้แต่ไม่เหมือนจริง
- ใช้ Activity Result API (registerForActivityResult) แทน onActivityResult ที่ Deprecated
- Scoped Storage (Android 10+): ใช้ MediaStore + FileProvider ไม่ใช่ File URI ตรงๆ
- รูปภาพจะเก็บใน Gallery อัตโนมัติ (Pictures/<AppName>/)
- ควรจัดการ Rotation ของรูป (EXIF Orientation) หากแสดงผิดทิศทาง
การทดสอบ
รันบนโทรศัพท์จริง กด "Capture Image" → เลือก Camera App → ถ่ายรูป → ยืนยัน → รูปจะแสดงใน ImageView