Çalışma zamanında istenen izinler

Tüm Android uygulamaları sınırlı erişime sahip bir korumalı alanda çalışır. Uygulamanızın kendi korumalı alanı dışında kaynak veya bilgi kullanması gerekiyorsa bir çalışma zamanı izni beyan edebilir ve bu erişimi sağlayan bir izin isteği oluşturabilirsiniz. Bu adımlar, izinleri kullanma iş akışının bir parçasıdır.

Tehlikeli izinler beyan ederseniz ve uygulamanız Android 6.0 (API düzeyi 23) veya sonraki sürümleri çalıştıran bir cihaza yüklenirse çalışma zamanında bu kılavuzdaki adımları uygulayarak tehlikeli izinleri istemeniz gerekir.

Tehlikeli izin beyan etmezseniz veya uygulamanız Android 5.1 (API düzeyi 22) ya da önceki sürümleri çalıştıran bir cihazda yüklüyse izinler otomatik olarak verilir ve bu sayfadaki kalan adımların hiçbirini tamamlamanız gerekmez.

Temel ilkeler

Çalışma zamanında izin istemeyle ilgili temel ilkeler şunlardır:

  • Kullanıcı gerektiren özellikle etkileşimde bulunmaya başladığında, bağlam içinde izin isteyin.
  • Kullanıcıyı engellemeyin. Eğitsel kullanıcı arayüzü akışını (ör. izin isteme gerekçesini açıklayan bir akış) iptal etme seçeneğini her zaman sağlayın.
  • Kullanıcı bir özelliğin ihtiyacı olan bir izni reddeder veya iptal ederse uygulamanızın kullanımını düzgün bir şekilde düşürerek kullanıcının uygulamanızı kullanmaya devam edebilmesini sağlayın (muhtemelen izni gerektiren özelliği devre dışı bırakarak).
  • Herhangi bir sistem davranışı varsaymayın. Örneğin, izinlerin aynı izin grubunda yer aldığını varsaymayın. İzin grubu, sadece bir uygulama yakından ilgili izinler istediğinde sistemin kullanıcıya gösterilen sistem iletişim kutusu sayısını en aza indirmesine yardımcı olur.

İzin isteme iş akışı

Uygulamanızda çalışma zamanı izinlerini beyan etmeden ve istemeden önce uygulamanızın bunu yapması gerekip gerekmediğini değerlendirin. Uygulamanızda fotoğraf çekme, medya oynatmayı duraklatma ve alakalı reklamlar gösterme gibi birçok kullanım alanını herhangi bir izin beyan etmenize gerek kalmadan yerine getirebilirsiniz.

Uygulamanızın çalışma zamanında istenen izinleri beyan etmesi ve istemesi gerektiği sonucuna varsa aşağıdaki adımları tamamlayın:

  1. Uygulamanızın manifest dosyasında, uygulamanızın istemesi gerekebilecek izinleri beyan edin.
  2. Uygulamanızın kullanıcı deneyimini, uygulamanızdaki belirli işlemlerin belirli çalışma zamanı izinleriyle ilişkilendirilecek şekilde tasarlayın. Kullanıcılara, uygulamanızın gizli kullanıcı verilerine erişmesi için hangi işlemlerin izni gerektiğini bildirin.
  3. Kullanıcının uygulamanızda belirli gizli kullanıcı verilerine erişim gerektiren görevi veya işlemi çağırmasını bekleyin. Bu sırada, uygulamanız bu verilere erişmek için gerekli çalışma zamanı iznini isteyebilir.
  4. Kullanıcının, uygulamanızın gerektirdiği çalışma zamanı iznini önceden verip vermediğini kontrol edin. Öyleyse uygulamanız gizli kullanıcı verilerine erişebilir. Çalışmıyorsa bir sonraki adıma geçin.

    Bu izni gerektiren bir işlemi her gerçekleştirdiğinizde izniniz olup olmadığını kontrol etmeniz gerekir.

  5. Uygulamanızın kullanıcıya bir gerekçe gösterip göstermemesi gerektiğini kontrol edin ve uygulamanızın kullanıcıdan neden belirli bir çalışma zamanı izni vermesi gerektiğini açıklayın. Sistem, uygulamanızın bir gerekçe göstermemesi gerektiğini belirlerse bir kullanıcı arayüzü öğesi göstermeden doğrudan sonraki adıma geçin.

    Ancak sistem, uygulamanızın bir gerekçe göstermesi gerektiğini belirlerse gerekçeyi kullanıcıya bir kullanıcı arayüzü öğesinde sunun. Bu gerekçede, uygulamanızın hangi verilere erişmeye çalıştığını ve çalışma zamanında istenen izni vermesi durumunda uygulamanın kullanıcıya ne gibi avantajlar sağlayabileceğini net bir şekilde açıklayın. Kullanıcı gerekçeyi kabul ettikten sonra bir sonraki adıma geçin.

  6. Uygulamanızın gizli kullanıcı verilerine erişmek için ihtiyaç duyduğu çalışma zamanı iznini isteyin. Sistem, izinlere genel bakış sayfasında gösterilene benzer bir çalışma zamanı izni istemi görüntüler.

  7. Çalışma zamanı iznini vermeyi veya reddetmeyi seçmesi nedeniyle kullanıcının yanıtını kontrol edin.

  8. Kullanıcı, uygulamanıza izin verdiyse gizli kullanıcı verilerine erişebilirsiniz. Kullanıcı bunun yerine izni reddetmişse uygulama deneyiminizi zarif bir şekilde düşürerek bu izinin korunan bilgiler olmadan kullanıcıya işlevsellik sağlamasını sağlayın.

Şekil 1'de bu işlemle ilişkili iş akışı ve kararlar gösterilmektedir:

Şekil 1. Android'de çalışma zamanı izinlerini bildirme ve isteme iş akışını gösteren şema.

Uygulamanıza daha önce izin verilip verilmediğini belirleme

Kullanıcının uygulamanıza daha önce belirli bir izin verip vermediğini kontrol etmek için bu izni ContextCompat.checkSelfPermission() yöntemine iletin. Bu yöntem, uygulamanızın izne sahip olup olmadığına bağlı olarak PERMISSION_GRANTED veya PERMISSION_DENIED değerini döndürür.

Uygulamanızın neden bu izne ihtiyacı olduğunu açıklayın

requestPermissions() çağrısı yaptığınızda sistem tarafından gösterilen izinler iletişim kutusu, uygulamanızın hangi izni istediğini belirtir ancak nedenini belirtmez. Bazı durumlarda, kullanıcı bu zor soruyu zorlayabilir. requestPermissions() çağrısı yapmadan önce kullanıcıya uygulamanızın neden izin istediğini açıklamak iyi bir fikirdir.

Araştırmalar, uygulamanın neden gerekli olduğunu (örneğin, uygulamanın temel bir özelliğini desteklemek veya reklam yayınlamak için izin gerekli olup olmadığını) bilen kullanıcıların, izin istekleriyle ilgili olarak çok daha rahat olduklarını göstermektedir. Sonuç olarak, bir izin grubuna giren API çağrılarının yalnızca bir kısmını kullanıyorsanız bu izinlerden hangilerini neden kullandığınızı açık bir şekilde listelemek yardımcı olur. Örneğin, yalnızca yaklaşık konum kullanıyorsanız bunu uygulama açıklamanızda veya uygulamanızla ilgili yardım makalelerinde kullanıcıya bildirin.

Belirli koşullarda, hassas veri erişimini kullanıcılara gerçek zamanlı olarak bildirmek de yararlı olur. Örneğin, kameraya veya mikrofona erişiyorsanız uygulamanızın bir yerinde veya bildirim tepsisinde (uygulama arka planda çalışıyorsa) bir bildirim simgesi kullanarak durumu kullanıcıya bildirmek iyi bir fikirdir. Böylece, gizlice veri topluyormuşsunuz gibi görünmemektedir.

Son olarak, uygulamanızda bir şeyin çalışması için izin istemeniz gerekiyor ancak bunun nedeni kullanıcı tarafından net değilse kullanıcıya neden en hassas izinlere ihtiyacınız olduğunu bildirmenin bir yolunu bulun.

ContextCompat.checkSelfPermission() yöntemi PERMISSION_DENIED sonucunu döndürürse shouldShowRequestPermissionRationale() yöntemini çağırın. Bu yöntem true sonucunu döndürürse kullanıcıya eğitim amaçlı bir kullanıcı arayüzü gösterin. Bu kullanıcı arayüzünde, kullanıcının etkinleştirmek istediği özellik için neden özel bir izin gerektiğini açıklayın.

Ayrıca, uygulamanız konum, mikrofon veya kamera ile ilgili izin isterse uygulamanızın bu bilgilere neden erişmesi gerektiğini açıklayın.

İzin iste

Kullanıcı eğitici bir kullanıcı arayüzünü görüntüledikten veya shouldShowRequestPermissionRationale() işlevinin döndürülen değeri, eğitsel bir kullanıcı arayüzü göstermenize gerek olmadığını belirttikten sonra izin isteyin. Kullanıcılar, uygulamanıza belirli bir izin verip vermemeyi seçebilecekleri bir sistem izni iletişim kutusu görür.

Bunu yapmak için, sistemin izin isteği kodunu yönetmesine izin verdiğiniz AndroidX kitaplığında bulunan RequestPermission sözleşmesini kullanın. RequestPermission sözleşmesini kullanmak mantığınızı daha basit hale getirdiğinden, mümkün olduğunda önerilen çözüm budur. Ancak gerekirse izin isteğinin bir parçası olarak kendiniz de istek kodu yönetebilir ve bu istek kodunu izin geri çağırma mantığınıza ekleyebilirsiniz.

Sistemin izin isteği kodunu yönetmesine izin ver

Sistemin bir izin isteğiyle ilişkili istek kodunu yönetmesine izin vermek için modülünüzün build.gradle dosyasına aşağıdaki kitaplıklara bağımlılık ekleyin:

Ardından, aşağıdaki sınıflardan birini kullanabilirsiniz:

Aşağıdaki adımlarda RequestPermission sözleşmesinin nasıl kullanılacağı gösterilmektedir. Süreç, RequestMultiplePermissions sözleşmesiyle neredeyse aynıdır.

  1. Etkinliğinizin veya parçanızın başlatma mantığında bir ActivityResultCallback uygulamasını registerForActivityResult() çağrısına geçirin. ActivityResultCallback, uygulamanızın izin isteğine verdiği yanıtı nasıl ele alacağını tanımlar.

    ActivityResultLauncher türündeki registerForActivityResult() döndürülen değeri için bir referans kullanın.

  2. Gerektiğinde sistem izinleri iletişim kutusunu görüntülemek için önceki adımda kaydettiğiniz ActivityResultLauncher örneğinde launch() yöntemini çağırın.

    launch() çağrıldıktan sonra, sistem izinleri iletişim kutusu görüntülenir. Kullanıcı bir seçim yaptığında, sistem önceki adımda tanımladığınız ActivityResultCallback uygulamanızı eşzamansız olarak çağırır.

    Not: Uygulamanız, launch() numaralı telefonu çağırdığınızda görünen iletişim kutusunu özelleştiremez. Kullanıcılara daha fazla bilgi veya bağlam sağlamak için uygulamanızın kullanıcı arayüzünü değiştirerek kullanıcıların uygulamanızdaki bir özelliğin neden belirli bir izne ihtiyaç duyduğunu daha kolay anlamasını sağlayın. Örneğin, özelliği etkinleştiren düğmedeki metni değiştirebilirsiniz.

    Ayrıca, sistem izni iletişim kutusundaki metin istediğiniz izinle ilişkili izin grubuna referans verir. Bu izin gruplandırması, sistemin kullanım kolaylığı için tasarlanmıştır. Uygulamanız, belirli bir izin grubunun içinde veya dışında bulunan izinlere dayanmamalıdır.

Aşağıdaki kod snippet'i, izin yanıtının nasıl işleneceğini gösterir:

Kotlin

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // feature requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    }

Java

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
private ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new RequestPermission(), isGranted -> {
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // feature requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    });

Bu kod snippet'i, izin olup olmadığını kontrol etmek ve gerektiğinde kullanıcıdan izin istemek için önerilen işlemi gösterir:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
    }
    ActivityCompat.shouldShowRequestPermissionRationale(
            this, Manifest.permission.REQUESTED_PERMISSION) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected, and what
        // features are disabled if it's declined. In this UI, include a
        // "cancel" or "no thanks" button that lets the user continue
        // using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        // The registered ActivityResultCallback gets the result of this request.
        requestPermissionLauncher.launch(
                Manifest.permission.REQUESTED_PERMISSION)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
        this, Manifest.permission.REQUESTED_PERMISSION)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    // The registered ActivityResultCallback gets the result of this request.
    requestPermissionLauncher.launch(
            Manifest.permission.REQUESTED_PERMISSION);
}

İzin isteği kodunu kendiniz yönetme

Sistemin izin isteği kodunu yönetmesine izin vermeye alternatif olarak izin isteği kodunu kendiniz de yönetebilirsiniz. Bunun için istek kodunu requestPermissions() özelliğine yapılan bir çağrıya ekleyin.

Aşağıdaki kod snippet'i, istek kodu kullanarak nasıl izin isteneceğini göstermektedir:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
        performAction(...)
    }
    ActivityCompat.shouldShowRequestPermissionRationale(
            this, Manifest.permission.REQUESTED_PERMISSION) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected, and what
        // features are disabled if it's declined. In this UI, include a
        // "cancel" or "no thanks" button that lets the user continue
        // using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        requestPermissions(CONTEXT,
                arrayOf(Manifest.permission.REQUESTED_PERMISSION),
                REQUEST_CODE)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
        this, Manifest.permission.REQUESTED_PERMISSION)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    requestPermissions(CONTEXT,
            new String[] { Manifest.permission.REQUESTED_PERMISSION },
            REQUEST_CODE);
}

Kullanıcı, sistem izinleri iletişim kutusuna yanıt verdikten sonra, sistem, uygulamanızda onRequestPermissionsResult() kullanımını çağırır. Sistem, aşağıdaki kod snippet'inde gösterildiği gibi, tanımladığınız istek kodu ile birlikte izin iletişim kutusuna kullanıcının yanıtını iletir:

Kotlin

override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        PERMISSION_REQUEST_CODE -> {
            // If request is cancelled, the result arrays are empty.
            if ((grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            } else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return
        }

        // Add other 'when' lines to check for other
        // permissions this app might request.
        else -> {
            // Ignore all other requests.
        }
    }
}

Java

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            }  else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return;
        }
        // Other 'case' lines to check for other
        // permissions this app might request.
    }
}

Konum izni isteme

Konum izinleri istediğinizde diğer tüm çalışma zamanı izinlerinde geçerli olan en iyi uygulamaları izleyin. Konum izinleriyle ilgili önemli bir fark, sistemin konumla ilgili birden fazla izne sahip olmasıdır. Hangi izinleri istediğiniz ve bunları nasıl isteyeceğiniz, uygulamanızın kullanım alanına ilişkin konum gereksinimlerine bağlıdır.

Ön plan konumu

Uygulamanızda, konum bilgilerini yalnızca bir kez veya belirli bir süre boyunca paylaşan ya da alan bir özellik bulunuyorsa bu özellik ön planda konuma erişim izni gerektirir. Aşağıda konuyla ilgili olarak bazı örnekler verilmiştir:

  • Bir navigasyon uygulamasındaki özellik sayesinde kullanıcılar adım adım yol tarifi alabiliyor.
  • Mesajlaşma uygulamasındaki bir özellik, kullanıcıların mevcut konumlarını başka bir kullanıcıyla paylaşmalarına olanak tanır.

Uygulamanızın bir özelliği, aşağıdaki durumlardan birinde cihazın mevcut konumuna erişirse sistem, uygulamanızı ön plan konumunu kullanıyor olarak kabul eder:

  • Uygulamanıza ait etkinlikler görünür durumda.
  • Uygulamanız bir ön plan hizmeti çalıştırıyor. Bir ön plan hizmeti çalışırken sistem, kalıcı bir bildirim göstererek kullanıcı farkındalığını artırır. Uygulamanız arka plana yerleştirildiğinde (ör. kullanıcı cihazındaki Ana sayfa düğmesine bastığında veya cihazının ekranını kapattığında) erişmeye devam eder.

    Android 10 (API düzeyi 29) ve sonraki sürümlerde ön plan hizmet türünü aşağıdaki kod snippet'inde gösterildiği gibi location belirtmeniz gerekir. Android'in önceki sürümlerinde bu ön plan hizmet türünü bildirmeniz önerilir.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements go here. -->
    </service>
    

Aşağıdaki snippet'te gösterildiği gibi, uygulamanız ACCESS_COARSE_LOCATION veya ACCESS_FINE_LOCATION iznini istediğinde ön planda konum ihtiyacını beyan etmiş olursunuz:

<manifest ... >
  <!-- Include this permission any time your app needs location information. -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Arka planda konum

Bir uygulama, içindeki bir özellik sürekli konumunu diğer kullanıcılarla paylaşıyorsa veya Geofencing API'yi kullanıyorsa arka planda konum erişimine ihtiyaç duyar. Aşağıda konuyla ilgili birkaç örnek verilmiştir:

  • Ailelere yönelik konum paylaşımı uygulamalarındaki bir özellik, kullanıcıların aile üyeleriyle sürekli olarak konum paylaşımında bulunmalarına olanak tanır.
  • Bir IoT uygulamasındaki özellik, kullanıcıların ev cihazlarını yapılandırmalarına olanak tanır. Böylece kullanıcı evden çıktığında kapanır ve kullanıcı eve döndüğünde tekrar açılır.

Sistem, uygulamanızın ön plan konumu bölümünde açıklananlar dışında bir durumda cihazın mevcut konumuna erişiyorsa uygulamanızı arka planda konum bilgisi kullanıyor olarak kabul eder. Arka planda konum doğruluğu, ön plandaki konum doğruluğu ile aynıdır. Bu doğruluk, uygulamanızın beyan ettiği konum izinlerine bağlıdır.

Android 10 (API düzeyi 29) ve sonraki sürümlerde, çalışma zamanında arka planda konum erişimi istemek için uygulamanızın manifest dosyasında ACCESS_BACKGROUND_LOCATION iznini beyan etmeniz gerekir. Android'in eski sürümlerinde, uygulamanız ön planda konum erişimi aldığında arka planda konum erişimini de otomatik olarak alır.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

İzin reddini işleme

Kullanıcı bir izin isteğini reddederse uygulamanız bu izni reddetmenin ne gibi sonuçları olacağını anlamalarına yardımcı olmalıdır. Özellikle, uygulamanız, kullanıcıların eksik izin nedeniyle çalışmayan özelliklerden haberdar olmasını sağlamalıdır. Bunu yaparken aşağıdaki en iyi uygulamaları göz önünde bulundurun:

  • Kullanıcının dikkatini yönlendirin. Uygulamanızın kullanıcı arayüzünde, gerekli izne sahip olmadığı için işlevselliğin sınırlı olduğu belirli bir bölümü vurgulayın. Yapabileceklerinizden bazıları şunlardır:

    • Özellikle ilgili sonuçların veya verilerin nerede görüneceğine dair bir mesaj gösterin.
    • Hata simgesi ve rengi içeren farklı bir düğme görüntüleyin.
  • Net olun. Genel bir mesaj göstermeyin. Bunun yerine, uygulamanız gerekli izne sahip olmadığı için hangi özelliklerin kullanılamadığını açıkça belirtin.

  • Kullanıcı arayüzünü engellemeyin. Diğer bir deyişle, kullanıcıların uygulamanızı kullanmaya devam etmesini engelleyen tam ekran bir uyarı mesajı göstermeyin.

Aynı zamanda uygulamanız, kullanıcının izni reddetme kararına uymalıdır. Android 11'den (API düzeyi 30) itibaren, uygulamanızın bir cihaza yüklendiği süre boyunca kullanıcı belirli bir izin için Reddet'e birden fazla kez dokunursa uygulamanız bu izni tekrar istediğinde kullanıcı sistem izinleri iletişim kutusunu görmez. Kullanıcının işlemi, "bir daha sorma" anlamına gelir. Önceki sürümlerde, kullanıcılar daha önce "tekrar sorma" onay kutusunu veya seçeneğini işaretlememişlerse uygulamanız her izin istediğinde sistem izinleri iletişim kutusunu görüyordu.

Bir kullanıcı bir izin isteğini birden fazla kez reddederse bu, kalıcı ret olarak kabul edilir. Kullanıcılardan yalnızca belirli bir özelliğe erişmeleri gerektiğinde izin istemek çok önemlidir. Aksi takdirde, izinleri yeniden isteme imkanını yanlışlıkla kaybedebilirsiniz.

Bazı durumlarda izin, kullanıcı herhangi bir işlem yapmadan otomatik olarak reddedilebilir. (Ayrıca otomatik olarak bir izin verilebilir.) Otomatik davranış hakkında hiçbir şey varsaymamak önemlidir. Uygulamanızın izin gerektiren işlevlere her erişmesi gerektiğinde uygulamanıza hâlâ bu iznin verilip verilmediğini kontrol edin.

Uygulama izinleri isterken en iyi kullanıcı deneyimini sunmak için Uygulama izinleri en iyi uygulamaları konusuna da bakın.

Test ve hata ayıklama sırasında ret durumunu inceleme

Bir uygulamanın izinlerinin kalıcı olarak reddedilip reddedilmediğini belirlemek için (hata ayıklama ve test amacıyla) aşağıdaki komutu kullanın:

adb shell dumpsys package PACKAGE_NAME

Burada PACKAGE_NAME, incelenecek paketin adıdır.

Komutun çıktısı, aşağıdakine benzer bölümler içerir:

...
runtime permissions:
  android.permission.POST_NOTIFICATIONS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
  android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SET|USER_FIXED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
  android.permission.BLUETOOTH_CONNECT: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
...

Kullanıcı tarafından bir kez reddedilen izinler USER_SET tarafından işaretlenir. İki kez Reddet seçeneği belirlendiğinde kalıcı olarak reddedilen izinler USER_FIXED tarafından işaretlenir.

Test kullanıcılarının test sırasında istek iletişim kutusunu görmelerini sağlamak için uygulamanızda hata ayıklamayı tamamladığınızda bu işaretleri sıfırlayın. Bu işlemi yapmak için şu komutu kullanın:

adb shell pm clear-permission-flags PACKAGE_NAME PERMISSION_NAME user-set user-fixed

PERMISSION_NAME, sıfırlamak istediğiniz iznin adıdır.

Android uygulama izinlerinin tam listesini görüntülemek için permissions API referans sayfasını ziyaret edin.

Tek seferlik izinler

&quot;Yalnızca bu sefer&quot; adlı seçenek, iletişim kutusundaki üç düğmeden ikincisidir.
Şekil 2. Bir uygulama tek seferlik izin istediğinde görünen sistem iletişim kutusu.

Android 11'den (API düzeyi 30) itibaren, uygulamanız konum, mikrofon veya kamera ile ilgili bir izin istediğinde kullanıcılara yönelik izinler iletişim kutusunda Yalnızca bu sefer adlı bir seçenek bulunur (Şekil 2'de gösterildiği gibi). Kullanıcı iletişim kutusunda bu seçeneği belirlerse uygulamanıza geçici tek seferlik izin verilir.

Daha sonra uygulamanız, uygulamanızın davranışına ve kullanıcı işlemlerine bağlı olarak ilgili verilere belirli bir süre erişebilir:

  • Uygulamanızın etkinliği görünür durumdayken bu verilere erişebilir.
  • Kullanıcı, uygulamanızı arka plana gönderirse uygulamanız kısa bir süre için verilere erişmeye devam edebilir.
  • Etkinlik görünür durumdayken bir ön plan hizmeti başlatırsanız ve kullanıcı daha sonra uygulamanızı arka plana taşırsa uygulamanız, ön plan hizmeti durdurulana kadar verilere erişmeye devam edebilir.

İzin iptal edildiğinde uygulama işlemi sona erer

Kullanıcı, sistem ayarlarında olduğu gibi tek seferlik izni iptal ederse bir ön plan hizmeti başlatmış olsanız da olmasanız da uygulamanız verilere erişemez. Her türlü izinde olduğu gibi, kullanıcı uygulamanızın bir defalık iznini iptal ederse uygulamanızın süreci sonlandırılır.

Kullanıcı uygulamanızı tekrar açtığında ve uygulamanızdaki bir özellik konuma, mikrofona veya kameraya erişim istediğinde kullanıcıdan tekrar izin istenir.

Kullanılmayan izinleri sıfırla

Android, kullanılmayan çalışma zamanı izinlerini varsayılan, reddedildi durumuna sıfırlamak için çeşitli yöntemler sunar:

Uygulama erişimini kaldır

Android 13 (API düzeyi 33) ve sonraki sürümlerde, uygulamanızın artık ihtiyaç duymadığı çalışma zamanı izinlerine erişimini kaldırabilirsiniz. Uygulamanızı güncellerken bu adımı uygulayarak kullanıcıların neden belirli izinler istemeye devam ettiğini daha iyi anlamalarını sağlayın. Bu bilgi, kullanıcıların uygulamanızda güvenini kazanmanıza yardımcı olur.

Bir çalışma zamanı iznine erişimi kaldırmak için söz konusu iznin adını revokeSelfPermissionOnKill() işlevine iletin. Çalışma zamanında istenen izin grubuna erişimi aynı anda kaldırmak için bir izin adları koleksiyonunu revokeSelfPermissionsOnKill()'e iletin. İzin kaldırma işlemi eşzamansız olarak gerçekleşir ve uygulamanızın UID'siyle ilişkili tüm işlemler sonlandırılır.

Sistemin, uygulamanızın izinlere erişimini kaldırması için uygulamanıza bağlı tüm işlemlerin sonlandırılması gerekir. API'yi çağırdığınızda, bu süreçleri ne zaman sonlandırmanın güvenli olduğu sistem tarafından belirlenir. Genellikle sistem, uygulamanız ön plan yerine arka planda uzun süre çalışana kadar bekler.

Uygulamanızın artık belirli çalışma zamanı izinlerine erişim gerektirmediğini kullanıcıya bildirmek için kullanıcı uygulamanızı bir sonraki açışında bir iletişim kutusu gösterin. Bu iletişim kutusunda izinlerin listesi yer alabilir.

Kullanılmayan uygulamaların izinlerini otomatik olarak sıfırla

Uygulamanız Android 11 (API düzeyi 30) veya sonraki bir sürümü hedefliyorsa ve birkaç ay boyunca kullanılmıyorsa sistem, kullanıcının uygulamanıza verdiği hassas çalışma zamanı izinlerini otomatik olarak sıfırlayarak kullanıcı verilerini korur. Uygulamayı hazırda bekletme hakkında daha fazla bilgiyi kılavuzda bulabilirsiniz.

Gerekirse varsayılan işleyici olma isteğinde bulunun

Bazı uygulamalar, arama kayıtları ve SMS mesajlarıyla ilgili hassas kullanıcı bilgilerine erişim gerektirir. Arama kayıtlarına ve SMS mesajlarına özel izinleri istemek ve uygulamanızı Play Store'da yayınlamak istiyorsanız, bu çalışma zamanı izinlerini istemeden önce kullanıcıdan uygulamanızı temel sistem işlevi için varsayılan işleyici olarak ayarlamasını isteyin.

Kullanıcılara bir varsayılan işleyici istemi göstermeyle ilgili rehberlik de dahil olmak üzere varsayılan işleyiciler hakkında daha fazla bilgi için yalnızca varsayılan işleyicilerde kullanılan izinler hakkındaki kılavuza bakın.

Test amacıyla tüm çalışma zamanı izinlerini verme

Bir emülatöre veya test cihazına uygulama yüklediğinizde tüm çalışma zamanı izinlerini otomatik olarak vermek için aşağıdaki kod snippet'inde gösterildiği gibi adb shell install komutu için -g seçeneğini kullanın:

adb shell install -g PATH_TO_APK_FILE

Ek kaynaklar

İzinler hakkında daha fazla bilgi için şu makaleleri okuyun:

İzin isteme hakkında daha fazla bilgi için izin örneklerini inceleyin.

Gizlilikle ilgili en iyi uygulamaları gösteren bu codelab'i de tamamlayabilirsiniz.