Ç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ı 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 izinleri beyan ederseniz ve uygulamanız, Android 6.0 (API düzeyi 23) veya sonraki sürümleri çalıştıran bir cihaza yüklendiyse bu kılavuzdaki adımları uygulayarak çalışma zamanında tehlikeli izinleri istemeniz gerekir.

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

Temel ilkeler

Çalışma zamanında izin istemeye ilişkin temel ilkeler şunlardır:

  • Kullanıcı, gerekli özellikle etkileşimde bulunmaya başladığında bir bağlam çerçevesinde 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ış).
  • Kullanıcı bir özelliğin ihtiyacı olan bir izni reddeder veya iptal ederse uygulamanızı kullanmaya devam edebilmeleri için izin gerektiren özelliği devre dışı bırakarak uygulamanızın incelikli düzeyini düşürün.
  • Herhangi bir sistem davranışı varsaymayın. Örneğin, izinlerin aynı izin grubunda göründüğünü varsaymayın. İzin grubu, yalnızca bir uygulama yakından alakalı izinler istediğinde sistemin kullanıcıya sunulan sistem iletişim kutularının sayısını en aza indirmesine yardımcı olur.

İzin isteme iş akışı

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

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 isteyebileceği 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şlemlerin uygulamanızın gizli kullanıcı verilerine erişmesine izin vermelerini gerektirebileceğ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. O anda uygulamanız bu verilere erişmek için gerekli olan çalışma zamanı iznini isteyebilir.
  4. Kullanıcının, uygulamanızın gerektirdiği çalışma zamanı iznini zaten 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 her işlemi her gerçekleştirdiğinizde, izninizin olup olmadığını 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 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 bir kullanıcı arayüzü öğesinde sunun. Bu gerekçede, uygulamanızın hangi verilere erişmeye çalıştığını ve uygulamanın çalışma zamanında istenen izni kullanıcıya sağlayabileceği avantajları 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österilen gibi bir çalışma zamanı izin istemi görüntüler.

  7. Kullanıcının yanıtını (çalışma zamanı izni vermeyi veya reddetmeyi tercih edip etmediklerini) kontrol edin.

  8. Kullanıcı uygulamanıza izin verdiyse gizli kullanıcı verilerine erişebilirsiniz. Bunun yerine kullanıcı izni reddettiyse uygulama deneyiminizin kalitesini olumsuz yönde etkileyerek söz konusu izinle korunan bilgiler olmadan kullanıcıya işlevler sunabilirsiniz.

Şekil 1'de, bu işlemle ilişkili iş akışı ve kararlar kümesi 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 önceden 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ğırdığınızda sistem tarafından gösterilen izinler iletişim kutusu, uygulamanızın hangi izni istediğini belirtir ancak bunun nedenini söylemez. Bazı durumlarda, kullanıcılar bunu 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 reklamcılık için iznin gerekip gerekmediğini) bilen kullanıcıların, izin istekleri konusunda çok daha rahat olduklarını göstermektedir. Sonuç olarak, bir izin grubuna dahil olan 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 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 verilere erişimi gerçek zamanlı olarak kullanıcılara bildirmek de yararlıdır. Örneğin, kamera veya mikrofona erişiyorsanız uygulamanızın bir yerindeki veya bildirim tepsisindeki (uygulama arka planda çalışıyorsa) bir bildirim simgesi kullanarak bunu kullanıcıya haber vermek iyi bir fikirdir. Bu şekilde gizlice veri topluyormuş gibi görünürsünüz.

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

ContextCompat.checkSelfPermission() yöntemi PERMISSION_DENIED değerini döndürürse shouldShowRequestPermissionRationale() çağrısı yapın. Bu yöntem true değerini döndürürse kullanıcıya bir eğitim kullanıcı arayüzü gösterin. Bu kullanıcı arayüzünde, kullanıcının etkinleştirmek istediği özellik için neden belirli bir izne ihtiyaç duyduğ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 iste

Kullanıcı, eğitim amaçlı bir kullanıcı arayüzünü görüntülediğinde veya döndürülen shouldShowRequestPermissionRationale() değeri, eğitim amaçlı kullanıcı arayüzü göstermenize gerek olmadığını belirttiğinde izin 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 AndroidX kitaplığındaki 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 istek 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ında aşağıdaki kitaplıklara 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. Süreç, RequestMultiplePermissions sözleşmesi için neredeyse aynıdır.

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

    ActivityResultLauncher türündeki registerForActivityResult() işlevinin döndürdüğü değere referansta bulunun.

  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() ç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 ö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 grubunu referans alır. Bu izin gruplandırması, sistemin kullanım kolaylığı için tasarlanmıştır ve uygulamanız belirli bir izin grubunun içinde veya dışında izinlere bağlı olmamalı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, bir izni 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 yönetebilirsiniz. Bunu yapmak için, requestPermissions() çağrısına istek kodunu ekleyin.

Aşağıdaki kod snippet'i, istek kodu kullanarak nasıl izin isteyeceğinizi 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ı başlatır. Sistem, kullanıcı yanıtını izin iletişim kutusuna ve tanımladığınız istek kodunu aşağıdaki kod snippet'inde gösterildiği gibi 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 izni istediğinizde diğer çalışma zamanı izinleriyle aynı en iyi uygulamaları izleyin. Konum izinleri konusundaki önemli farklardan biri, sistemin konumla ilgili birden fazla izin içermesidir. Hangi izinleri istediğiniz ve bunları nasıl istediğ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 özelliğin ön planda konum erişimine ihtiyacı vardır. Buna örnek olarak aşağıdakiler verilebilir:

  • Navigasyon uygulamasındaki bir özellik, kullanıcıların adım adım yol tarifi almasını sağlar.
  • Mesajlaşma uygulamasındaki bir özellik, kullanıcıların mevcut konumlarını başka bir kullanıcıyla paylaşması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 (örneğin, kullanıcı cihazındaki Ana sayfa düğmesine bastığında veya cihazının ekranını kapattığında) erişimi korur.

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

Bir uygulamadaki bir özellik, diğer kullanıcılarla sürekli olarak konum bilgisini paylaşıyorsa veya Geofencing API'yi kullanıyorsa arka planda konum erişimi gerekir. Aşağıda çeşitli örnekler verilmiştir:

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

Uygulamanız, ön plan konum bölümünde açıklananlar dışında herhangi bir durumda cihazınızın mevcut konumuna erişirse sistem, uygulamanızın arka planda konumu kullanıyor olduğunu kabul eder. Arka planda konum doğruluğu, uygulamanızın beyan ettiği konum izinlerine bağlı olan ön plan 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 konuma erişim isteğinde bulunmak 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 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ı anlaması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. Bunu yaparken aşağıdaki en iyi uygulamaları aklınızda bulundurun:

  • Kullanıcının dikkatini yönlendirin. Uygulamanız gerekli izne sahip olmadığı için işlevlerinin sınırlı olduğu uygulama kullanıcı arayüzünde belirli bir bölümü vurgulayın. Yapabileceklerinizle ilgili örnekleri aşağıda bulabilirsiniz:

    • Özellik sonuçlarının veya verilerinin görüntülenebileceği bir mesajı gösterir.
    • 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 engelleyen tam ekran bir uyarı mesajı göstermeyin.

Uygulamanız aynı zamanda, kullanıcının izni reddetme kararına da saygı göstermelidir. Android 11'den (API düzeyi 30) itibaren, uygulamanızın bir cihazda yüklü olduğu süre boyunca kullanıcı belirli bir izin için Reddet'e birden fazla kez dokunursa uygulamanız bu izni tekrar isterse sistem izinleri iletişim kutusunu görmez. Kullanıcının yaptığı işlem "bir daha sorma" anlamına gelir. Önceki sürümlerde kullanıcılar, daha önce "bir daha sorma" onay kutusunu veya seçeneğini belirlememiş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 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.

Belirli 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 bu iznin hâlâ verilip verilmediğini kontrol edin.

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

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

Bir uygulamaya izinlerin 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 çıkışı aşağıdaki gibi 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çilerek 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ıklama işlemini bitirdiğinizde bu işaretleri sıfırlayın. Bunu 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üntülenen 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ı da 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 sona erer

Kullanıcı tek seferlik izni iptal ederse (ör. sistem ayarları) uygulamanız, ön plan hizmeti başlatıp başlatmamanızdan bağımsız olarak verilere erişemez. Her izinte olduğu gibi, kullanıcı uygulamanızın tek seferlik iznini iptal ederse uygulamanızın işlemi sona erer.

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

Kullanılmayan izinleri sıfırlayın

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

Uygulama erişimini kaldır

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

Çalışma zamanında istenen izne erişimi kaldırmak için söz konusu iznin adını revokeSelfPermissionOnKill() hesabına iletin. Çalışma zamanında istenen izin grubuna erişimi aynı anda kaldırmak için izin adları koleksiyonunu revokeSelfPermissionsOnKill() hizmetine 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 güvenli olup olmadığını belirler. Sistem genellikle, 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 uygulamanızı bir sonraki açışında 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 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. Uygulamayı hazırda bekleme hakkında 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şime bağlıdır. Arama kayıtlarına ve SMS mesajlarına özgü 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ı istemelisiniz.

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 ver

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.