Merhaba sevgili android geliştiricileri. Bu yazımda sizlere galeriden resim seçmeyi ve yeni resim çekip kaydetmeyi anlatacağım. Öncelikle eski android sürümleri ile yeni android sürümleri arasındaki dosya yolu farkını öğrenelim.
Konu Başlıkları
Android Studio – Kameradan Görüntü Alma, İşleme ve Galeriden Resim Seçme

FileProvider
FileProvider, bir içerik oluşturarak bir uygulama ile ilişkili dosyaların güvenli paylaşımını kolaylaştıran özel bir ContentProvider alt sınıfıdır.
Eskiden : file:///
Şimdi : content://
Bu özellik Nougat(API 24) ile geldi. Api 24 öncesi ve sonrası için ayrı kod yazıyoruz. Şimdi kodlara geçelim.
Önce Tasarım!
Önce resim çekme, galeriden seçme butonlarımızı ve çekilen/seçilen resmin gösterileceği imageView görünümü ekleyelim. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="takePhoto"
android:text="Resim Çek"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="chooseGallery"
android:text="Galeriden Seç"/>
</LinearLayout>
<ImageView
android:id="@+id/activity_main_imgView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"/>
</LinearLayout>
İzinler ve FileProvider
İzinleri bildiğimiz üzere manifest dosyasına ekliyoruz. Aynı şekilde FileProvider manifest dosyasına ekleniyor.
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iamkurtgoz.androidimagetakeandchooseexample">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- FILE PROVIDER -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
<!-- FILE PROVIDER -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Unutmadan.. provider_paths.xml isimli bir dosya oluşturup içerisine dosya izinlerini yazmalıyız.
Dosya yolu: /app/src/main/res/xml/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
<external-files-path
name="external_files"
path="." />
<!-- FOR SD CARD-->
<root-path
name="sdcard1"
path="." />
</paths>
Şimdi Kod Zamanı!
Kod yazarken dosya yazma, okuma ve kamera izinlerini daha hızlı kullanmak için Dexter kütüphanesini kullanacağız.
Resim Çekme:
Dexter.withActivity(this).withPermissions(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: MultiplePermissionsListener{
override fun onPermissionRationaleShouldBeShown(permissions: MutableList<PermissionRequest>?, token: PermissionToken?) {
token?.continuePermissionRequest()
}
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
if (report == null) return
if (report.areAllPermissionsGranted()) { //İzinler tamam ise
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) //Resim çekme intent
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, getImagePath()) //Dosyayı uri olarak ekliyoruz
if (takePictureIntent.resolveActivity(packageManager) != null) { //Eğer resim çekmemiz için bir uygulama yoksa hata vermesin diye kontrol ediyoruz
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE) //Başlatıyoruz
}
}
}
}).check()
Galeriden Resim Seçme:
Dexter.withActivity(this).withPermissions(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: MultiplePermissionsListener{
override fun onPermissionRationaleShouldBeShown(permissions: MutableList<PermissionRequest>?, token: PermissionToken?) {
token?.continuePermissionRequest()
}
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
if (report == null) return
if (report.areAllPermissionsGranted()) {//İzinler tamam ise
val pickPhoto: Intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) //Galeriden resim seçme intenti
if (pickPhoto.resolveActivity(packageManager) != null) { //Eğer resim çekmemiz için bir uygulama yoksa hata vermesin diye kontrol ediyoruz
startActivityForResult(pickPhoto, REQUEST_GALLERY_IMAGE) //Başlatıyoruz
}
}
}
}).check()
onActivityResult ile seçilen/çekilen resmin sonucunu aldık ve imageViewde gösterdik
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
REQUEST_IMAGE_CAPTURE -> {
imgView.setImageBitmap(BitmapFactory.decodeFile(filePath))
}
REQUEST_GALLERY_IMAGE -> {
val imageUri: Uri? = data?.data
if (imageUri == null) return
imgView.setImageURI(imageUri)
}
}
}
MainActivity.kt
import android.Manifest
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import java.io.File
import java.io.IOException
class MainActivity : AppCompatActivity() {
private val REQUEST_IMAGE_CAPTURE = 0
private val REQUEST_GALLERY_IMAGE = 1
private var filePath: String = ""
private lateinit var imgView: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
imgView = findViewById(R.id.activity_main_imgView)
}
fun takePhoto(view: View){
Dexter.withActivity(this).withPermissions(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: MultiplePermissionsListener{
override fun onPermissionRationaleShouldBeShown(permissions: MutableList<PermissionRequest>?, token: PermissionToken?) {
token?.continuePermissionRequest()
}
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
if (report == null) return
if (report.areAllPermissionsGranted()) { //İzinler tamam ise
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) //Resim çekme intent
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, getImagePath()) //Dosyayı uri olarak ekliyorz
if (takePictureIntent.resolveActivity(packageManager) != null) { //Eğer resim çekmemiz için bir uygulama yoksa hata vermesin diye kontrol ediyorız
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE) //Başlatıyoruz
}
}
}
}).check()
}
fun chooseGallery(view: View){
Dexter.withActivity(this).withPermissions(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(object: MultiplePermissionsListener{
override fun onPermissionRationaleShouldBeShown(permissions: MutableList<PermissionRequest>?, token: PermissionToken?) {
token?.continuePermissionRequest()
}
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
if (report == null) return
if (report.areAllPermissionsGranted()) {//İzinler tamam ise
val pickPhoto: Intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) //Galeriden resim seçme intenti
if (pickPhoto.resolveActivity(packageManager) != null) { //Eğer resim çekmemiz için bir uygulama yoksa hata vermesin diye kontrol ediyorız
startActivityForResult(pickPhoto, REQUEST_GALLERY_IMAGE) //Başlatıyoruz
}
}
}
}).check()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
REQUEST_IMAGE_CAPTURE -> {
imgView.setImageBitmap(BitmapFactory.decodeFile(filePath))
}
REQUEST_GALLERY_IMAGE -> {
val imageUri: Uri? = data?.data
if (imageUri == null) return
imgView.setImageURI(imageUri)
}
}
}
fun getImagePath(): Uri{
try {
createImageFile() //Yeni dosyayı oluşturduk
} catch (e: Exception) {
e.printStackTrace()
}
val imageFile: File = File(filePath) //Dcim klasörüne resim dosyasını ekliyoruz
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //Nougat ve sonrası için
return FileProvider.getUriForFile(this, applicationContext.packageName + ".provider", imageFile)
} else {
return Uri.fromFile(imageFile) //Öncesi için
}
}
@Throws(IOException::class)
private fun createImageFile(): File {
val storageDir: File = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) //Dcim klasörünün yolunu aldık
return File.createTempFile(
System.currentTimeMillis().toString(), /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
// Save a file: path for use with ACTION_VIEW intents
filePath = absolutePath
}
}
}
Şimdi kodları test edelim.



Bu yazıda android Resim Çekme ve Galeriden Seçme konusuna yer verdik. Proje kodlarına buradan ulaşabilirsiniz. Soru, görüş ve önerileriniz için lütfen yorum yapmayı unutmayın.