Çalışma zamanında istenen izinler

Her Android uygulaması, sınırlı erişime sahip bir korumalı alanda çalışır. Uygulamanızın kendi korumalı alanının dışındaki kaynakları veya bilgileri kullanması gerekiyorsa çalışma zamanında istenen izin 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ümlerin yüklü olduğu bir cihaza yüklenirse bu kılavuzdaki adımları uygulayarak çalışma zamanında tehlikeli izinleri istemeniz gerekir.

Tehlikeli izinler beyan etmezseniz veya uygulamanız Android 5.1 (API düzeyi 22) ya da daha eski bir sürümün yüklü olduğu bir cihaza yüklenirse izinler otomatik olarak verilir ve bu sayfadaki kalan adımları tamamlamanız gerekmez.

Temel ilkeler

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

  • Kullanıcı, izin gerektiren özellikle etkileşime girmeye başladığında bağlam içinde izin isteyin.
  • Kullanıcıyı engellemeyin. İzin isteme gerekçesini açıklayan akışlar gibi eğitici kullanıcı arayüzü akışlarını iptal etme seçeneğini her zaman sunun.
  • Bir özellik için gereken izni reddeden veya iptal eden kullanıcıların uygulamanızı kullanmaya devam etmesine izin verirken kontrollü azaltma uygulayın. Bu izni gerektiren özelliği devre dışı bırakmayı değerlendirin.
  • Sistem davranışıyla ilgili varsayımlarda bulunmayın. Örneğin, izinlerin aynı izin grubunda göründüğünü varsaymayın. İzin grubu, bir uygulama yakından ilişkili izinler istediğinde kullanıcıya gösterilen sistem iletişim kutularının sayısını en aza indirmesi için sisteme yardımcı olur.

İzin isteme iş akışı

Uygulamanızda çalışma zamanında istenen izinleri beyan edip 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 etmeden gerçekleştirebilirsiniz.

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

  1. Uygulamanızın istemesi gerekebilecek izinleri uygulamanızın manifest dosyasında beyan edin.
  2. Uygulamanızdaki belirli işlemlerin belirli çalışma zamanında istenen izinlerle ilişkilendirilmesi için uygulamanızın kullanıcı deneyimini (UX) tasarlayın. Kullanıcılara, uygulamanızın özel kullanıcı verilerine erişmesi için hangi işlemlerin izin vermelerini gerektirebileceğini bildirin.
  3. Kullanıcının uygulamanızda belirli özel kullanıcı verilerine erişim gerektiren görevi veya işlemi çağırmasını bekleyin. Bu durumda uygulamanız, söz konusu verilere erişmek için gereken çalışma zamanında istenen izni talep edebilir.
  4. Kullanıcının daha önce izin verip vermediğini kontrol edin.

    Uygulamanızın gerektirdiği çalışma zamanında istenen izin. Bu durumda uygulamanız özel kullanıcı verilerine erişebilir. Sorun çözülmezse bir sonraki adıma geçin.

    İzin gerektiren bir işlem yapacağınız her seferde izniniz olup olmadığını kontrol etmeniz gerekir.

  5. Uygulamanızın, kullanıcının belirli bir çalışma zamanında istenen izni vermesine neden ihtiyaç duyduğunu açıklayan bir gerekçe göstermesi gerekip gerekmediğini kontrol edin. Sistem, uygulamanızın açıklama göstermemesi gerektiğini belirlerse kullanıcı arayüzü öğesi göstermeden doğrudan bir sonraki adıma geçin.

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

  6. Uygulamanızın özel kullanıcı verilerine erişmek için ihtiyaç duyduğu çalışma zamanında istenen izni isteyin. Sistem, izinlere genel bakış sayfasında gösterilene benzer bir çalışma zamanında istenen izin istemi gösterir.

  7. Kullanıcının yanıtını kontrol edin. Çalışma zamanında istenen izni vermeyi mi yoksa reddetmeyi mi seçtiğini öğrenin.

  8. Kullanıcı, uygulamanıza izin verdiyse özel kullanıcı verilerine erişebilirsiniz. Kullanıcı izni reddettiyse uygulama deneyiminizin kontrollü azalmasını sağlayarak kullanıcıya, söz konusu izinle korunan bilgiler olmadan işlevsellik sunun.

Şekil 1'de bu süreçle ilişkili iş akışı ve karar grubu gösterilmektedir:

Çalışma zamanında istenen izinleri talep etme karar sürecini gösteren bir akış şeması. Bu süreç, bir uygulama işlemiyle başlar, izin verilip verilmediğini kontrol eder, gerekçenin gerekli olup olmadığını kontrol eder, izin ister ve kullanıcının yanıtını işler.
Şekil 1. Android'de çalışma zamanında istenen izinleri beyan etme ve isteme iş akışını gösteren şema.

Uygulamanıza iznin verilip verilmediğini belirleme

Kullanıcının uygulamanıza belirli bir izni 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 bu izne neden ihtiyaç duyduğunu açıklayın

requestPermissions() yöntemini çağırdığınızda sistem tarafından gösterilen izin iletişim kutusunda uygulamanızın hangi izni istediği belirtilir ancak bunun nedeni açıklanmaz. Bazı durumlarda kullanıcı bunu kafa karıştırıcı bulabilir. requestPermissions() yöntemini çağırmadan önce uygulamanızın neden izin istediğini kullanıcıya açıklamak iyi bir fikirdir.

Araştırmalar, uygulamaların izin isteme nedenini bilen kullanıcıların bu istekler konusunda çok daha rahat davrandıklarını gösteriyor. Örneğin, iznin uygulamanın temel bir özelliğini desteklemek için mi yoksa reklam için mi gerekli olduğunu bilmek kullanıcıları rahatlatıyor. Bu nedenle, bir izin grubuna giren API çağrılarının yalnızca bir kısmını kullanıyorsanız bu izinlerden hangilerini ve neden kullandığınızı açıkça belirtin. Örneğin, yalnızca yaklaşık konum kullanıyorsanız bunu uygulamanızın açıklamasında veya uygulamanızla ilgili yardım makalelerinde kullanıcıya bildirin.

Belirli koşullarda, kullanıcıları hassas verilere erişim konusunda anlık olarak bilgilendirmek de faydalı olabilir. Ö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 kullanıcıyı bilgilendirin. Böylece, gizlice veri topluyormuş gibi görünmezsiniz.

Bir özelliğin çalışması için izin istemeniz gerekiyorsa ancak bunun nedeni kullanıcı açısından net değilse hassas bilgilere erişim iznine neden ihtiyacınız olduğunu açıklamanın bir yolunu bulun.

ContextCompat.checkSelfPermission() yöntemi PERMISSION_DENIED değerini döndürürse shouldShowRequestPermissionRationale() yöntemini çağırın. Bu yöntem true değerini döndürürse kullanıcıya bilgilendirici bir kullanıcı arayüzü gösterin. Bu kullanıcı arayüzünde, kullanıcının etkinleştirmek istediği özelliğin neden belirli bir izne ihtiyaç duyduğunu açıklayın.

Ayrıca, uygulamanız konum, mikrofon veya kamerayla ilgili izin istiyorsa uygulamanızın bu bilgilere neden erişmesi gerektiğini açıklayabilirsiniz.

İzin iste

Kullanıcı eğitici bir kullanıcı arayüzü gördükten veya shouldShowRequestPermissionRationale() işlevinin döndürdüğü değer eğitici bir kullanıcı arayüzü göstermeniz gerekmediğini belirttikten sonra izin isteyin. Kullanıcılar, uygulamanıza belirli bir izin verip vermeyeceklerini seçebilecekleri bir sistem izni iletişim kutusu görür.

Bunu yapmak için AndroidX kitaplığında bulunan RequestPermission sözleşmesini kullanın. Bu sözleşmede, sistemin izin isteği kodunu sizin için yönetmesine izin verirsiniz. RequestPermission sözleşmesini kullanmak mantığınızı basitleştirdiği için mümkün olduğunda önerilen çözüm budur. Ancak gerekirse izin isteğinin bir parçası olarak istek kodunu kendiniz de yönetebilir ve bu istek kodunu izin geri çağırma mantığınıza dahil edebilirsiniz.

Sistemin, izin isteği kodunu yönetmesine izin verme

Sistemin, 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ıklarla ilgili bağımlılıkları 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. RequestMultiplePermissions sözleşmesi için de süreç neredeyse aynıdır.

  1. Etkinliğinizin veya parçanızın başlatma mantığında, ActivityResultCallback uygulamasını registerForActivityResult() çağrısına iletin. ActivityResultCallback, uygulamanızın kullanıcının izin isteğine verdiği yanıtı nasıl işleyeceğini tanımlar.

    ActivityResultLauncher türündeki registerForActivityResult() işlevinin döndürdüğü değer için referansı koruyun.

  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österilir. 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() yöntemini çağırdığınızda görünen iletişim kutusunu özelleştiremez. Kullanıcıya 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 ve uygulamanız, izinlerin belirli bir izin grubunun içinde veya dışında olmasına bağlı olmamalıdır.

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

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);
}

Bu kod snippet'i, izin kontrolü yapma ve gerektiğinde kullanıcıdan izin isteme için önerilen süreci 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 vermek yerine izin isteği kodunu kendiniz yönetebilirsiniz. Bunun için istek kodunu requestPermissions() çağrısına ekleyin.

Aşağıdaki kod snippet'inde, istek kodu kullanarak izin isteme işlemi gösterilmektedir:

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ızın onRequestPermissionsResult() uygulamasını çağırır. Sistem, aşağıdaki kod snippet'inde gösterildiği gibi, izin iletişim kutusuna verilen kullanıcı yanıtını ve tanımladığınız istek kodunu 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 izinleri isteme

Konum izinleri isterken diğer çalışma zamanında istenen izinler için geçerli olan en iyi uygulamaları izleyin. Konum izinleri söz konusu olduğunda önemli bir fark, sistemin konumla ilgili birden fazla izin içermesidir. Hangi izinleri nasıl isteyeceğiniz, uygulamanızın kullanım alanı için konumla ilgili koşullara bağlıdır.

Ön planda konum

Uygulamanızda konum bilgisini yalnızca bir kez veya belirli bir süre boyunca paylaşan ya da alan bir özellik varsa bu özelliğin ön planda konum erişimine ihtiyacı vardır. Aşağıda konuyla ilgili olarak bazı örnekler verilmiştir:

  • Bir navigasyon uygulamasında, kullanıcıların adım adım yol tarifi almasını sağlayan bir özellik.
  • Bir mesajlaşma uygulamasındaki ö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şiyorsa sistem, uygulamanızın ön planda konum kullandığını varsayar:

  • Uygulamanıza ait bir etkinlik görünür durumdadır.
  • Uygulamanızda ön plan hizmeti çalışı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 alındığında (ör. kullanıcı cihazındaki Ana Sayfa düğmesine bastığında veya cihazının ekranını kapattığında) erişimi devam eder.

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

    <!-- 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>

Uygulamanız aşağıdaki snippet'te gösterildiği gibi ACCESS_COARSE_LOCATION veya ACCESS_FINE_LOCATION izni istediğinde ön planda konum erişimine ihtiyaç duyduğunu 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

Uygulama içindeki bir özellik, konumu diğer kullanıcılarla sürekli olarak paylaşıyorsa veya Geofencing API'yi kullanıyorsa uygulamanın arka planda konum erişimine ihtiyacı vardır. Örnek olarak aşağıdakileri gösterebiliriz:

  • Aile konum paylaşımı uygulamasındaki bir özellik, kullanıcıların aile üyeleriyle sürekli konum paylaşmasına olanak tanıyor.
  • Bir IoT uygulamasındaki özellik, kullanıcıların ev cihazlarını, kullanıcı evden çıktığında kapanacak ve eve döndüğünde tekrar açılacak şekilde yapılandırmasına olanak tanıyor.

Uygulamanız, ön planda konum bölümünde açıklanan durumlar dışında cihazın mevcut konumuna erişiyorsa sistem, uygulamanızın arka planda konum kullandığını varsayar. Arka planda konum doğruluğu, ön planda konum doğruluğu ile aynıdır ve 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 önceki sürümlerinde uygulamanız ön planda konum erişimi aldığında otomatik olarak arka planda konum erişimi de 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, izni reddetmenin sonuçlarını anlamasına yardımcı olmalıdır. Özellikle uygulamanız, eksik izin nedeniyle çalışmayan özellikler hakkında kullanıcıları bilgilendirmelidir. Bunu yaparken aşağıdaki en iyi uygulamaları göz önünde bulundurun:

  • İşlev kaybını en aza indirin. Kullanıcılar, istenen izinler olmadan uygulamaya mümkün olduğunca erişebilmelidir. İşlev, izin verildiğinde mümkün olacak duruma kıyasla daha düşük performans gösterse bile mevcut verilerle en azından bir dereceye kadar çalışıyorsa işlevi açık tutmak en iyi seçenektir.
  • Kullanıcının dikkatini yönlendirin. Uygulamanızın gerekli izne sahip olmaması nedeniyle işlevlerin sınırlı olduğu belirli bir kullanıcı arayüzü bölümünü vurgulayın. Yapabileceklerinize dair örnekler:

    • Özelliğin sonuçlarının veya verilerinin görüneceği yerde bir mesaj gösterilir.
    • Hata simgesi ve rengi içeren farklı bir düğme gösterilir.
  • 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. Başka bir deyişle, kullanıcıların uygulamanızı kullanmaya devam etmesini tamamen engelleyen tam ekran bir uyarı mesajı göstermeyin.

  • Kullanıcının tercihini kabul edin: Kullanıcılara, istedikleri izinlere erişim eksikliğinin işlevlerini nasıl etkilediğini anlatmakta bir sakınca yoktur ancak kullanıcılar fikirlerini değiştirmeleri için baskı altında hissetmemelidir. Kullanıcıya, uygun olduğunda (ör. uygulamanın izin olmadan engellenen bir bölümünü kullanmaya çalışırken) tüm özelliklere erişemediğini bildirmek önemlidir ancak kullanıcıyı kararını yeniden değerlendirmesi için sürekli rahatsız etmek, seçimine saygı duymamak anlamına gelir.

Bu kurallara uymak, kullanıcıların özel verilerine erişimi kendi değerlerine uygun şekilde yönetme konusunda yetki sahibi olduklarını hissetmelerine yardımcı olabilir. Kullanıcıların gizlilikle ilgili kararlarını kabul etmemek yalnızca uygulamanızın değil, tüm ekosistemin güvenini ve saygınlığını zedeler.

Ayrıca, uygulamanızın bir cihazda yüklü olduğu süre boyunca kullanıcı belirli bir izin için birden fazla kez Reddet'e dokunursa uygulamanız bu izni tekrar istediğinde kullanıcı artık sistem izinleri iletişim kutusunu görmez. Kullanıcının işlemi "tekrar sorma" anlamına gelir ve kalıcı bir 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 olanağını yanlışlıkla kaybedebilirsiniz. Bazı durumlarda, kullanıcı herhangi bir işlem yapmadan izin otomatik olarak reddedilebilir. (İzin otomatik olarak da verilebilir.) Otomatik davranışla ilgili herhangi bir varsayımda bulunmamak önemlidir. Uygulamanızın izin gerektiren bir işleve her erişmesi gerektiğinde, uygulamanıza bu iznin hâlâ verilip verilmediğini kontrol edin. Uygulama izinleri isterken en iyi kullanıcı deneyimini sunmak için Uygulama izinleriyle ilgili en iyi uygulamalar başlıklı makaleyi de inceleyin.

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

Buradaki PACKAGE_NAME, incelenecek paketin adıdır.

Komutun çıkışı aşağıdaki gibi görünen 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 ile işaretlenir. İki kez Reddet seçilerek kalıcı olarak reddedilen izinler USER_FIXED ile işaretlenir.

Test kullanıcılarının test sırasında istek iletişim kutusunu gördüğünden emin olmak için uygulamanızda hata ayıklamayı tamamladığınızda bu işaretleri sıfırlayın. Bunun 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.

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

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

Tek seferlik izinler

&quot;Yalnızca bu sefer&quot; seçeneği, 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 kamerayla ilgili bir izin istediğinde, kullanıcılara yönelik izin iletişim kutusunda Şekil 2'de gösterildiği gibi Yalnızca bu sefer adlı bir seçenek bulunur. Kullanıcı iletişim kutusunda bu seçeneği belirlerse uygulamanıza geçici bir tek seferlik izin verilir.

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

  • Uygulamanızın etkinliği görünür durumdayken uygulamanız 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 durana kadar verilere erişmeye devam edebilir.

İzin iptal edildiğinde uygulama işlemi sonlandırılır

Kullanıcı, sistem ayarlarında olduğu gibi tek seferlik izni iptal ederse uygulamanız, ön plan hizmeti başlatıp başlatmadığınıza bakılmaksızın verilere erişemez. Diğer izinlerde olduğu gibi, kullanıcı uygulamanızın tek seferlik iznini iptal ederse uygulamanızın işlemi sonlandırılır.

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

Kullanılmayan izinleri sıfırlama

Android, kullanılmayan çalışma zamanında istenen izinleri varsayılan, reddedilmiş durumlarına sıfırlamak için çeşitli yöntemler sunar:

Uygulama erişimini kaldırma

Android 13 (API düzeyi 33) ve sonraki sürümlerde, uygulamanızın artık ihtiyaç duymadığı çalışma zamanında istenen izinlere erişimini kaldırabilirsiniz. Uygulamanızı güncellerken bu adımı uygulayarak kullanıcıların, uygulamanızın belirli izinleri istemeye devam etme nedenini daha iyi anlamasını sağlayın. Bu bilgi, kullanıcıların uygulamanıza güvenmesini sağlar.

Çalışma zamanında istenen bir izne erişimi kaldırmak için ilgili iznin adını revokeSelfPermissionOnKill() yöntemine iletin. Çalışma zamanında istenen izinlerden oluşan bir grubun erişimini aynı anda kaldırmak için revokeSelfPermissionsOnKill() yöntemine bir izin adı koleksiyonu iletin. İzin kaldırma işlemi eşzamansız olarak gerçekleşir ve uygulamanızın UID'siyle ilişkili tüm işlemleri sonlandırır.

Sistemin, uygulamanızın izinlere erişimini kaldırabilmesi için uygulamanıza bağlı tüm işlemlerin sonlandırılması gerekir. API'yi çağırdığınızda sistem, bu işlemleri sonlandırmanın ne zaman güvenli olduğunu belirler. Sistem genellikle uygulamanızın ön planda değil, arka planda uzun süre çalışmasını bekler.

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

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

Uygulamanız Android 11 (API düzeyi 30) veya sonraki sürümleri hedefliyorsa ve birkaç ay boyunca kullanılmazsa sistem, kullanıcının uygulamanıza verdiği hassas çalışma zamanında istenen izinleri otomatik olarak sıfırlayarak kullanıcı verilerini korur. Uygulamayı hazırda bekletme ile ilgili kılavuzdan daha fazla bilgi edinebilirsiniz.

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

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

Kullanıcılara varsayılan işleyici istemi gösterme ile ilgili bilgiler de dahil olmak üzere varsayılan işleyiciler hakkında daha fazla bilgi için yalnızca varsayılan işleyicilerde kullanılan izinlerle ilgili kılavuzu inceleyin.

Test amacıyla çalışma zamanında istenen tüm izinleri verme

Bir emülatöre veya test cihazına uygulama yüklediğinizde çalışma zamanında istenen tüm izinleri otomatik olarak vermek için aşağıdaki kod snippet'inde gösterildiği gibi adb shell install komutunun -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 edinmek için izin örneklerini inceleyin.

Ayrıca gizlilikle ilgili en iyi uygulamaları gösteren bu codelab'i de tamamlayabilirsiniz.