Çalışma zamanında istenen izinler

Her Android uygulaması, sınırlı erişimli bir korumalı alanda çalışır. Uygulamanızın kendi korumalı alanının dışındaki kaynakları veya bilgileri kullanması gerekiyorsa ç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 ediyorsanız ve uygulamanız Android 6.0 (API düzeyi 23) veya sonraki bir sürümün yüklü olduğu bir cihaza yüklüyse bu kılavuzun adımlarını uygulayarak tehlikeli izinleri çalışma zamanında istemeniz gerekir.

Tehlikeli izin beyan etmezseniz veya uygulamanız Android 5.1 (API düzeyi 22) veya daha eski bir sürümün yüklü olduğu bir cihaza yüklüyse izinler otomatik olarak verilir ve bu sayfadaki diğer adımların hiçbirini tamamlamanız gerekmez.

Temel ilkeler

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

  • Kullanıcı, izin gerektiren özellikle etkileşime geçtiğinde bağlama göre izin isteyin.
  • Kullanıcıyı engellemeyin. Eğitim amaçlı kullanıcı arayüzü akışını her zaman iptal etme seçeneği sunun (ör. izin isteme gerekçesini açıklayan bir akış).
  • 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ırakarak da uygulamanızın kullanımına devam etmesini sağlayabilirsiniz.
  • Sistem davranışı hakkında varsayımlarda bulunmayın. Örneğin, izinlerin aynı izin grubunda göründüğünü varsaymayın. İzin grupları, yalnızca bir uygulama yakından ilişkili 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ında izinleri beyan edip istemeden önce uygulamanızın bunu yapıp yapamayacağını 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 karşılayabilirsiniz.

Uygulamanızın çalışma zamanında istenen izinleri bildirmesi ve istemesi gerektiği sonucuna varırsanız 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şkilendirileceği şekilde tasarlayın. Kullanıcılara, hangi işlemler için uygulamanızın gizli kullanıcı verilerine erişmesine izin vermeleri gerekebileceğini bildirin.
  3. Uygulamanızda belirli gizli kullanıcı verilerine erişmeyi gerektiren görevi veya işlemi kullanıcıdan çağırın. Bu sırada uygulamanız, söz konusu verilere erişmek için gereken çalışma zamanında istenen izni isteyebilir.
  4. Kullanıcıya, uygulamanızın ihtiyaç duyduğu çalışma zamanı izninin verilip verilmediğini kontrol edin. Bu durumda uygulamanız gizli kullanıcı verilerine erişebilir. Çalışmıyorsa bir sonraki adıma geçin.

    İzin gerektiren bir işlem gerçekleştirdiğinizde her seferinde izin sahibi olup olmadığınızı kontrol etmeniz gerekir.

  5. Uygulamanızın, kullanıcıya belirli bir çalışma zamanında istenen izni neden vermesi gerektiğini açıklayan bir gerekçe sunup sunmayacağını kontrol edin. Sistem, uygulamanızın gerekçe gösterilmemesi gerektiğini belirlerse kullanıcı arayüzü öğesi göstermeden doğrudan sonraki adıma geçin.

    Sistem, uygulamanızın gerekçe göstermesi gerektiğini belirlerse gerekçeyi kullanıcıya bir kullanıcı arayüzü öğesinde gösterin. Bu gerekçede, uygulamanızın hangi verilere erişmeye çalıştığını ve çalışma zamanında izin verilirse kullanıcıya ne gibi avantajlar sağlayabileceğini açıkça belirtin. Kullanıcı gerekçeyi kabul ettikten sonra bir sonraki adıma geçin.

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

  7. Kullanıcının yanıtını (çalışma zamanında izin vermeyi mi yoksa reddetmeyi mi seçtiğini) kontrol edin.

  8. Kullanıcı uygulamanıza izin verdiyse gizli kullanıcı verilerine erişebilirsiniz. Kullanıcı izni reddettiyse uygulamanızın deneyimini kontrollü bir şekilde azaltın. Böylece, kullanıcıya bu izinle korunan bilgiler olmadan işlevsellik sağlayabilirsiniz.

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

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

Uygulamanıza izin verilip verilmediğini belirleme

Kullanıcının uygulamanıza belirli bir izin verip vermediğini kontrol etmek için söz konusu izni ContextCompat.checkSelfPermission() yöntemine iletin. Bu yöntem, uygulamanızın izin sahibi 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() işlevini çağırdığınızda sistem tarafından gösterilen izin iletişim kutusunda, uygulamanızın hangi izni istediği belirtilir ancak bu iznin neden istendiği açıklanmaz. Bazı durumlarda kullanıcı bu durumu kafa karıştırıcı bulabilir. requestPermissions() öğesini çağırmadan önce kullanıcıya uygulamanızın neden izinleri istediğini açıklamanız iyi bir fikirdir.

Araştırmalar, uygulamanın neden ihtiyaç duyduğunu (örneğin, uygulamanın temel bir özelliğini desteklemek veya reklam yayınlamak için iznin gerekip gerekmediği) bildiklerinde, kullanıcıların izin istekleri konusunda çok daha rahat olduğunu 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ça belirtmeniz faydalı 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şullar altında, hassas verilere erişimle ilgili olarak kullanıcıları anlık olarak bilgilendirmek de faydalı olabilir. Örneğin, kameraya veya mikrofona erişiyorsanız gizlice veri topladığınız izlenimi vermemek için uygulamanızda bir yerde veya bildirim tepsisinde (uygulama arka planda çalışıyorsa) bildirim simgesi kullanarak kullanıcıyı bilgilendirmeniz iyi bir fikirdir.

Uygulamanızda bir işlevi çalıştırmak için izin istemeniz gerekiyorsa ancak kullanıcıya bunun nedeni net bir şekilde açıklanmamışsa en hassas izinlere neden ihtiyaç duyduğunuzu kullanıcıya bildirmenin bir yolunu bulun.

ContextCompat.checkSelfPermission() yöntemi PERMISSION_DENIED döndürürse shouldShowRequestPermissionRationale() çağrısı yapın. Bu yöntem true döndürürse kullanıcıya eğitici 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 ihtiyacı olduğunu açıklayın.

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

İzin isteme

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

Bunu yapmak için bir AndroidX kitaplığına dahil edilen 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ı daha basit hale getirdiğinden mümkün olduğunda önerilen çözüm budur. Ancak gerekirse izin isteğinin bir parçası olarak istek kodunu kendiniz yönetebilir ve bu istek kodunu izin geri çağırma mantığınıza ekleyebilirsiniz.

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ıklara yönelik 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. Bu işlem, RequestMultiplePermissions sözleşmesi için neredeyse aynıdır.

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

    registerForActivityResult() işlevinin döndürdüğü değere (ActivityResultLauncher türü) referans tutun.

  2. Gerekirse 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ünür. 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() numarayı aradığı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 özellik iç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 atıfta bulunur. Bu izin gruplandırması, sistemin kolay kullanımı için tasarlanmıştır ve uygulamanız, izinlerin belirli bir izin grubunda veya dışında olmasına bağlı olmamalıdır.

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

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

Aşağıdaki kod snippet'inde, izin olup olmadığını kontrol etmek ve gerektiğinde kullanıcıdan izin istemek için önerilen süreç gösterilmektedir:

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

İzin isteği kodunu sistemin yönetmesine izin verme yerine izin isteği kodunu kendiniz yönetebilirsiniz. Bunu yapmak için isteğiniz kodu requestPermissions() adresine yapılan bir çağrıya ekleyin.

Aşağıdaki kod snippet'inde, istek kodu kullanılarak nasıl izin isteneceğ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);
}

Kullanıcı sistem izinleri iletişim kutusunu yanıtladıktan sonra sistem, uygulamanızın onRequestPermissionsResult() uygulamasını çağırır. Sistem, izin iletişim kutusuna verilen kullanıcı yanıtını ve tanımladığınız istek kodunu iletir. Bu durum aşağıdaki kod snippet'inde gösterilmiştir:

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 izni istediğinizde diğer tüm çalışma anı izinleriyle ilgili en iyi uygulamaları uygulayın. Konum izinleriyle ilgili önemli bir fark, sistemin konumla ilgili birden fazla izin içermesidir. Hangi izinleri istediğiniz ve bunları nasıl isteyeceğiniz, uygulamanızın kullanım alanıyla ilgili konum koşullarına 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 varsa bu özellik için ön planda konum erişimi gerekir. Buna örnek olarak aşağıdakiler verilebilir:

  • Bir navigasyon uygulamasında, kullanıcıların adım adım yol tarifi almasını sağlayan bir özellik.
  • Bir mesajlaşma uygulamasında, kullanıcıların mevcut konumlarını başka bir kullanıcıyla paylaşmalarına olanak tanıyan bir özellik.

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 bir etkinlik görünür.
  • 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ının dikkatini çeker. Kullanıcı cihazındaki ana ekran düğmesine bastığında veya cihazının ekranını kapattığında uygulamanız arka plana yerleştirildiğinde erişimi korur.

    Android 10 (API düzeyi 29) ve sonraki sürümlerde, aşağıdaki kod snippet'inde gösterildiği gibi location ön plan hizmeti türü belirtmeniz gerekir. Android'in önceki sürümlerinde bu ön plan hizmet türünü beyan etmeniz ö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>
    

Uygulamanız, aşağıdaki snippet'te gösterildiği gibi ACCESS_COARSE_LOCATION veya ACCESS_FINE_LOCATION izni 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

Uygulamadaki bir özellik sürekli olarak konumu diğer kullanıcılarla paylaşıyorsa veya Coğrafi sınırlama API'sini kullanıyorsa uygulamanın arka planda konum erişimi gerekir. Aşağıda çeşitli örnekler verilmiştir:

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

Sistem, ön planda konum bölümünde açıklanan durumlar dışındaki herhangi bir durumda cihazın mevcut konumuna erişirse uygulamanızın arka planda konum bilgisi kullandığını düşünür. Arka planda konum doğruluğu, uygulamanızın belirttiği konum izinlerine bağlı olan ön planda konum doğruluğu ile aynıdır.

Android 10 (API düzeyi 29) ve sonraki sürümlerde, çalışma zamanında arka planda konum erişimi isteğinde bulunmak için uygulamanızın manifest dosyasında ACCESS_BACKGROUND_LOCATION iznini belirtmeniz gerekir. Android'in önceki sürümlerinde, uygulamanız ön planda konum erişimi aldığında otomatik olarak arka planda konum erişimi de elde eder.

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

Reddedilen izinleri işleme

Kullanıcı bir izin isteğini reddederse uygulamanız, kullanıcıların izni reddetmenin sonuçlarını anlamalarına yardımcı olmalıdır. Uygulamanız özellikle kullanıcıları, iznin eksik olması nedeniyle çalışmayan özelliklerin farkında olmasını sağlamalıdır. Bu işlemi yaparken aşağıdaki en iyi uygulamaları göz önünde bulundurun:

  • Kullanıcıların dikkatini yönlendirin. Uygulamanızın kullanıcı arayüzünün, gerekli izinlere sahip olmadığı için işlevselliğinin sınırlı olduğu belirli bir bölümünü vurgulayın. Yapabileceğiniz işlemlere örnekler:

    • Özelliğin sonuçlarının veya verilerinin gösterileceği bir mesaj gösterin.
    • Hata simgesi ve rengi içeren farklı bir düğmeyi 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 tamamen engelleyen tam ekran uyarı mesajı göstermeyin.

Aynı zamanda uygulamanız, kullanıcının izin vermeme kararına saygı göstermelidir. Android 11'den (API düzeyi 30) itibaren, uygulamanızın bir cihazda yüklü kaldığı süre boyunca belirli bir izin için kullanıcı Reddet'e birden fazla kez dokunursa uygulamanız bu izni tekrar isterse 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 sormayın" onay kutusunu veya seçeneğini işaretlemedikleri sürece, uygulamanız her izin istediğinde sistem izinleri iletişim kutusunu görüyordu.

Bir kullanıcı izin isteğini birden fazla kez reddederse bu durum 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 yetkinizi yanlışlıkla kaybedebilirsiniz.

Bazı durumlarda, kullanıcı herhangi bir işlem yapmadan izin otomatik olarak reddedilebilir. (İzin otomatik olarak verilebilir.) Otomatik davranış hakkında herhangi bir durumu varsaymamak önemlidir. Uygulamanızın izin gerektiren işlevlere erişmesi gerektiğinde, uygulamanıza hâlâ bu iznin verildiğ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 çıktısı şu şekilde 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. Reddet'i iki kez seçerek 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örmesini sağlamak için uygulamanızdaki hata ayıklama işlemini tamamladığınızda bu işaretçileri 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.

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; 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 kamerayla ilgili bir izin istediğinde, kullanıcıya yönelik izinler 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.

Böylece uygulamanız, davranışına ve kullanıcının işlemlerine bağlı olarak 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 verilere kısa bir süre boyunca erişmeye devam edebilir.
  • Etkinlik görünür durumdayken bir ön plan hizmeti başlatırsanız ve kullanıcı 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ı, tek seferlik izni iptal ederse (ör. sistem ayarlarında) uygulamanız, ön plan hizmeti başlatmış olsanız bile verilere erişemez. Her izinde 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 sefer 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ırlama

Android, kullanılmayan çalışma zamanı izinlerini 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ı izinlerine erişimini kaldırabilirsiniz. Uygulamanızı güncellediğinizde, kullanıcıların uygulamanızın neden belirli izinleri istemeye devam ettiğini anlama olasılığını artırmak için bu adımı uygulayın. Bu bilgiler, kullanıcıların uygulamanıza güvenmelerini sağlar.

Bir çalışma zamanında izine erişimi kaldırmak için söz konusu iznin adını revokeSelfPermissionOnKill() içine aktarın. Bir çalışma zamanı izni grubuna erişimi aynı anda kaldırmak için revokeSelfPermissionsOnKill() içine bir izin adı koleksiyonu gönderin. İzin kaldırma işlemi eşzamanlı olarak gerçekleşir ve uygulamanızın UID'si ile ilişkili tüm işlemleri sonlandırı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 sistem, bu işlemlerin ne zaman sonlandırılmasının güvenli olduğunu belirler. Sistem genellikle uygulamanızın ön plan yerine arka planda uzun süre çalıştırılmasını bekler.

Uygulamanızın artık belirli çalışma zamanında izinlere erişmesi gerekmediğini kullanıcıya bildirmek için kullanıcı uygulamanızı bir sonraki açışında bir iletişim kutusu gösterin. Bu iletişim kutusu izinlerin listesini içerebilir.

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

Uygulamanız Android 11'i (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ı izinlerini otomatik olarak sıfırlayarak kullanıcı verilerini korur. Uygulama uyku modu hakkındaki kılavuzda daha fazla bilgi edinin.

Gerekirse varsayılan işleyici olma isteği

Bazı uygulamalar, arama kayıtları ve SMS mesajlarıyla ilgili hassas kullanıcı bilgilerine erişmek zorundadır. Arama kayıtları ve SMS mesajlarına özel izinleri istemek ve uygulamanızı Play Store'da yayınlamak istiyorsanız bu çalışma zamanında istenen izinleri 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 konusunda rehberlik 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ılavuza bakın.

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

Bir uygulamayı bir emülatöre veya test cihazına 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.

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