Android'de Permission Handler: nasıl çalışır, istek işleme ve uygulama

Yazar: IT Sectr Yayınlanma: 2026-05-20 Okuma süresi: 8 dk

Permission Handler, çalışma zamanı izinlerini kontrol etmekten, istemekten ve sonuçlarını işlemekten sorumlu bir Android uygulama bileşenidir. Android Developer Guide, 2024'e göre, bir izin işleyicisi checkSelfPermission, requestPermissions ve shouldShowRequestPermissionRationale mantığını tek bir sınıf veya ViewModel'de merkezileştirir. Bu, kod bakımını basitleştirir ve test etmeyi iyileştirir.

Ana Noktalar

  • Permission Handler — Android çalışma zamanı izinlerinin merkezi yönetimi için özel bir bileşen.
  • checkSelfPermission, requestPermissions ve shouldShowRequestPermissionRationale mantığını kapsüller.
  • Modern uygulamalar, androidx.activity'den ActivityResultContracts'a dayanır.
  • Bağımlılık tersine çevirme ve platform kodu izolasyonu sayesinde birim testlerini basitleştirir.
  • En iyi uygulamalar, Activity başına tek bir işleyici ve DI kapsayıcısı aracılığıyla yeniden kullanımı içerir.

Android'de Permission Handler Nedir

Permission Handler, Android çalışma zamanı izinlerinin merkezi yönetimi için bir mimari desendir. Uygulama kodu boyunca dağınık ContextCompat.checkSelfPermission ve ActivityCompat.requestPermissions çağrıları yerine, tüm istek ve sonuç işleme mantığı tek bir sınıfta toplanır. Bu, tekrarı azaltır, bakımı basitleştirir ve kodu daha öngörülebilir hale getirir.

Permission Handler ihtiyacı, Android 6.0'da çalışma zamanı izinlerinin getirilmesiyle ortaya çıktı. Bundan önce, tüm izinler yükleme sırasında istenirdi ve uygulama kodu herhangi bir API'yi kontrol olmadan kullanabilirdi. Çalışma zamanı modeline geçtikten sonra, tehlikeli bir iznin her kullanımı üç adımlı bir kontrol gerektirir: checkSelfPermission, requestPermissions, onRequestPermissionsResult. Bu mantığı Activity ve Fragment arasında yaymak, satır içi tekrara ve hatalara yol açar. Google I/O 2019'a göre, izin işlemeyi merkezileştirmek, Permission Denial ile ilgili hataların sayısını ortalama yüzde 60 oranında azaltır.

İyi bir Permission Handler, çağıran kod için temiz bir arayüz sağlar. Activity veya Fragment, isteğin ayrıntılarını bilmek zorunda değildir — requestCamera(callback) gibi bir yöntemi çağırırlar ve işleyicinin kendisi durum kontrolünü, gerekçe görüntülemeyi, sistem diyalog çağrısını ve sonucun callback'e iletilmesini yönetir. Bu, tek sorumluluk ilkesini uygular ve iş mantığını platform izin kodundan ayırır.

Permission Handler Ne Zaman Gereklidir

Bir uygulama 3 veya daha fazla tehlikeli izin kullandığında bir Permission Handler gerekli hale gelir. Tek bir izin (örneğin, QR kod tarayıcı için kamera) içeren basit uygulamalar için doğrudan çağrı yeterli olabilir. Ancak kamera, coğrafi konum, bildirimler ve depolama içeren tipik bir mobil uygulama için — merkezi bir işleyici bakım için gereklidir.

Permission Handler Mimarisi

Tipik bir Permission Handler üç katmandan oluşur: bir arayüz sözleşmesi, ActivityResultLauncher ile bir uygulama ve bir ViewModel katmanı. Arayüz, her izin için istek yöntemlerini tanımlar — requestCamera, requestLocation, requestStorage. Uygulama, bu yöntemleri ilgili ActivityResultContracts.RequestPermission sözleşmelerine bağlar.

Temel mimari bileşenler:

  • PermissionHandlerContract — her izin için yöntemler içeren bir arayüz
  • PermissionHandlerImpl — ActivityResultRegistry'ye bağlanan bir uygulama
  • PermissionResult — GRANTED, DENIED, NEVER_ASK_AGAIN durumlarına sahip sealed bir sınıf
  • RationaleHandler — istekten önce açıklamaları görüntülemek için bir bileşen

Bu mimari, testlerde uygulamaların kolayca değiştirilmesine olanak tanır: gerçek bir ActivityResultLauncher yerine, sistem etkileşimi olmadan önceden tanımlanmış bir sonuç döndüren bir mock kullanılır. Bu, izin diyaloğu için bir Activity başlatmanın imkansız olduğu UI mantığının birim testleri için çok önemlidir.

Yaşam Döngüsü Yönetimi

Permission Handler, Activity ve Fragment yaşam döngüsünü dikkate almalıdır. Başlatıcılar, ekran döndürme ve Activity yeniden oluşturma sırasında durumu otomatik olarak kaydeden ve geri yükleyen ActivityResultRegistry'ye kaydedilir. İşleyici, Activity veya Fragment'e doğrudan referanslar saklamamalıdır — bunun yerine WeakReference kullanın veya registry'yi yapıcı aracılığıyla iletin. Bu, yapılandırma değişiklikleri sırasında bellek sızıntılarını ve çökmeleri önler.

Kotlin'de Permission Handler Uygulaması

Bir Permission Handler'ın temel uygulaması, ActivityResultContracts.RequestPermission üzerine inşa edilir. İşleyici, ComponentActivity veya Fragment'ten ActivityResultRegistry'yi alır ve her izin için başlatıcılar kaydeder. Her başlatıcı, kullanıcının yanıtından sonra çağrılan bir callback lambda'sını kabul eder.

kotlin
sealed class PermissionResult {
    object GRANTED : PermissionResult()
    data class DENIED(
        val shouldShowRationale: Boolean
    ) : PermissionResult()
}

interface PermissionHandler {
    fun requestCamera(
        callback: (PermissionResult) -> Unit
    )
    fun requestLocation(
        callback: (PermissionResult) -> Unit
    )
    fun isPermissionGranted(
        permission: String
    ): Boolean
}

class AndroidPermissionHandler(
    private val registry: ActivityResultRegistry,
    private val context: Context
) : PermissionHandler {

    private var cameraLauncher: ActivityResultLauncher<String>? = null

    fun initialize() {
        cameraLauncher = registry.register(
            "camera_permission",
            ActivityResultContracts.RequestPermission()
        ) { isGranted ->
            if (isGranted) {
                pendingCameraCallback?.invoke(
                    PermissionResult.GRANTED
                )
            } else {
                val rationale = ActivityCompat.shouldShowRequestPermissionRationale(
                    context as Activity,
                    Manifest.permission.CAMERA
                )
                pendingCameraCallback?.invoke(
                    PermissionResult.DENIED(rationale)
                )
            }
        }
    }

    private var pendingCameraCallback:
        ((PermissionResult) -> Unit)? = null

    override fun requestCamera(
        callback: (PermissionResult) -> Unit
    ) {
        if (isPermissionGranted(
                Manifest.permission.CAMERA
        )) {
            callback.invoke(PermissionResult.GRANTED)
            return
        }
        pendingCameraCallback = callback
        cameraLauncher?.launch(
            Manifest.permission.CAMERA
        )
    }

    override fun isPermissionGranted(
        permission: String
    ): Boolean {
        return ContextCompat.checkSelfPermission(
            context, permission
        ) == PackageManager.PERMISSION_GRANTED
    }
}

Activity'de Başlatma

İşleyici, ActivityResultRegistry'ye erişim sağlayan registerForActivityResult aracılığıyla Activity'nin onCreate yönteminde başlatılır. Başlatmadan sonra, işleyici Activity yaşam döngüsü boyunca istekleri işlemeye hazırdır. İlk istekten önce initialize'i çağırmak önemlidir, aksi takdirde başlatıcı kaydedilmez.

ViewModel ile Permission Handler

Permission Handler'ı ViewModel ile Entegre Etmek en gelişmiş yaklaşımdır. ViewModel istek durumunu yönetirken, Handler yalnızca platform çağrılarını gerçekleştirir. ViewModel, UiState'in hangi iznin istendiğini ve hangi sonucun alındığını açıkladığı StateFlow<PermissionUiState> içerir. Activity bu StateFlow'a abone olur ve isteği Handler'a devreder.

kotlin
class PermissionsViewModel : ViewModel() {

    private val _uiState =
        MutableStateFlow<PermissionUiState>(
            PermissionUiState.Idle
        )
    val uiState: StateFlow<PermissionUiState> = _uiState.asStateFlow()

    fun onCameraRequested() {
        _uiState.value = PermissionUiState.RequestingCamera
    }

    fun onPermissionResult(
        permission: String,
        result: PermissionResult
    ) {
        when (result) {
            PermissionResult.GRANTED -> {
                _uiState.value = PermissionUiState.Granted(permission)
            }
            is PermissionResult.DENIED -> {
                _uiState.value = PermissionUiState.Denied(
                    permission,
                    result.shouldShowRationale
                )
            }
        }
    }
}

sealed class PermissionUiState {
    object Idle : PermissionUiState()
    object RequestingCamera : PermissionUiState()
    data class Granted(val permission: String) : PermissionUiState()
    data class Denied(
        val permission: String,
        val shouldShowRationale: Boolean
    ) : PermissionUiState()
}

Bu modelde, Activity başlangıçta Handler aracılığıyla isPermissionGranted'ı kontrol ederken, ViewModel yalnızca durumu yönetir. İzin verilmemişse — Activity uiState'e abone olur, Handler'dan requestCamera'yı çağırır ve sonucu onPermissionResult aracılığıyla ViewModel'e geri iletir. Platform kodunu iş mantığından ayırmak, ViewModel'in Android bağımlılıkları olmadan test edilmesine olanak tanır.

Permission Handler Test Etme

PermissionHandler arayüzü sayesinde Permission Handler'ın birim testi mümkündür. Testlerde, farklı senaryoları simüle eden bir FakePermissionHandler oluşturulur: izin verildi, reddedildi, Never Ask Again. Her senaryo bağımsız olarak test edilir. Bu, üç sonucun tümüne doğru tepki vermesi gereken UI mantığını test etmek için özellikle önemlidir.

kotlin
class FakePermissionHandler : PermissionHandler {

    var cameraResult: PermissionResult =
        PermissionResult.GRANTED
    var grantedPermissions: Set<String> =
        setOf(Manifest.permission.CAMERA)

    override fun requestCamera(
        callback: (PermissionResult) -> Unit
    ) {
        callback.invoke(cameraResult)
    }

    override fun isPermissionGranted(
        permission: String
    ): Boolean {
        return permission in grantedPermissions
    }
}

Sahte uygulama, emülatör olmadan ViewModel'i test etmeye olanak tanır. cameraResult'ı istenen değere ayarlayın ve ViewModel'in UiState'ini doğru şekilde güncellediğini doğrulayın. Entegrasyon testleri, ActivityScenario ile gerçek PermissionHandler'ı kontrol eder, ancak genellikle uygulama başına yalnızca 2-3 test bulunur — kalan senaryolar sahte ile birim testleri tarafından kapsanır.

Yaygın Kalıplar ve Hatalar

Permission Handler ile çalışırken tipik hatalar şunları içerir: her API çağrısından önce checkSelfPermission'ı kontrol etmemek, shouldShowRequestPermissionRationale'ı yok saymak, Never Ask Again'den sonra requestPermissions'ı yeniden çağırmak ve Activity yaşam döngüsünü dikkate almadan başlatıcıları saklamak. Her sorunu ve çözümünü inceleyelim.

En yaygın hata, izin durumunu kontrol etmeden bir API'yi çağırmaktır. Geliştiriciler, bir izin bir kez verildiyse sonsuza kadar kalacağını varsayar. Ancak, kullanıcı izni istediği zaman ayarlar aracılığıyla iptal edebilir. Bir Permission Handler, hassas bir işlem gerçekleştirmeden önce her zaman isPermissionGranted'ı çağırmalıdır. İkinci yaygın hata, shouldShowRequestPermissionRationale'ı yok saymak ve isteği tekrarlamaktır; bu, Never Ask Again modunda diyalog olmadan anında reddedilmeye yol açar.

En iyi uygulamalar şunları içerir: tüm Activity yaşam döngüsü için tek bir Handler örneği oluşturmak, sonuçları ViewModel'e iletmek için SharedFlow kullanmak, analiz için tüm istekleri ve reddetmeleri günlüğe kaydetmek ve ilk reddetmede sistem diyaloğundan önce özel bir gerekçe diyaloğu göstermek. Bu kurallara uymak, tüm Android sürümlerinde kararlı izin yönetimini garanti eder.

Sıkça Sorulan Sorular

Android'de Permission Handler nedir?

Permission Handler, checkSelfPermission, requestPermissions ve shouldShowRequestPermissionRationale'ı kapsülleyen, çalışma zamanı izinlerinin merkezi yönetimi için bir bileşendir. Kod bakımını basitleştirir ve test etmeyi iyileştirir.

2024'te Handler için hangi API kullanılmalı?

androidx.activity kütüphanesinden ActivityResultContracts.RequestPermission kullanılması önerilir. Eski onRequestPermissionsResult'ın yerini alır ve Boolean sonucu ile temiz bir callback API'si sağlar.

Tek bir izin için Handler gerekli mi?

Tek bir izin için Handler zorunlu değildir — Activity'de doğrudan RequestPermission başlatıcı çağrısı kullanabilirsiniz. Kod tekrarını önlemek için 3 veya daha fazla izin olduğunda Handler gerekli hale gelir.

Permission Handler nasıl test edilir?

Birim testleri için bir PermissionHandler arayüzü ve onun sahte uygulamasını oluşturun. Sahte, sistem çağrıları olmadan önceden tanımlanmış sonuçlar döndürür. Bu, emülatör olmadan ViewModel ve UI mantığını test etmeye olanak tanır.

Handler'da Never Ask Again nasıl işlenir?

Reddetmeden sonra, shouldShowRequestPermissionRationale'ı kontrol edin. Yöntem false döndürürse — Never Ask Again modu aktiftir. Handler, PermissionResult.DENIED(false) döndürmeli ve UI, Ayarlar'a gitmek için bir buton göstermelidir.

Özet

  • Permission Handler — Android çalışma zamanı izinlerinin merkezi yönetimi için bir mimari bileşen.
  • androidx.activity kütüphanesinden ActivityResultContracts.RequestPermission'a dayanır.
  • Her izin için yöntemler içeren bir arayüz, sahte uygulamalar aracılığıyla birim testlerini basitleştirir.
  • StateFlow aracılığıyla ViewModel ile entegrasyon, platform kodunu iş mantığından ayırır.
  • Tipik hatalar: checkSelfPermission eksikliği, gerekçeyi yok sayma ve Never Ask Again.
  • En iyi uygulama — onCreate'te kayıtlı Activity başına bir Handler.
  • Merkezileştirme, tipik projelerde Permission Denial hatalarının sayısını yüzde 60 azaltır.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun