Ç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ı dışındaki kaynakları veya bilgileri kullanması gerekiyorsa çalışma zamanı izni beyan edebilir ve bu erişimi sağlayan bir izin isteği ayarlayabilirsiniz. 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 seviyesi 23) veya sonraki sürümlerin yüklü olduğu bir cihaza yüklenirse bu kılavuzdaki adımları uygulayarak tehlikeli izinleri çalışma zamanında istemeniz gerekir.

Tehlikeli izin beyan etmiyorsanız veya uygulamanız Android 5.1 (API düzeyi 22) ya da daha eski bir sürümün yüklü olduğu cihaza yükleniyorsa 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 başladığında bağlam içinde izin isteyin.
  • Kullanıcıyı engellemeyin. Her zaman bir eğitici kullanıcı arayüzü akışını (ör. izin isteme gerekçesini açıklayan bir akış) iptal etme seçeneği 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ırakabilirsiniz.
  • Sistemin herhangi bir davranışını varsaymayın. Örneğin, izinlerin aynı izin grubunda görüneceğini varsaymayın. İzin grubu yalnızca bir uygulama, yakından ilişkili izinler istediğinde sisteme, kullanıcıya gösterilen sistem iletişim kutularının sayısını en aza indirmesinde yardımcı olur.

İzin isteme iş akışı

Uygulamanızda çalışma zamanı izinlerini beyan edip istemeden önce bunun gerekli olup olmadığı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 etmenize gerek kalmadan karşılayabilirsiniz.

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

  1. Uygulamanızın manifest dosyasında, uygulamanızın isteyebileceği izinleri beyan edin.
  2. Uygulamanızdaki belirli işlemlerin belirli çalışma zamanı izinleriyle ilişkilendirilmesi için uygulamanızın kullanıcı deneyimini tasarlayın. Kullanıcılara, uygulamanızın gizli kullanıcı verilerine erişmesi için hangi işlemlerin izin vermelerini gerektirebileceğini bildirin.
  3. Uygulamanızda belirli özel kullanıcı verilerine erişim gerektiren görevin veya işlemin kullanıcı tarafından başlatılmasını bekleyin. Bu durumda uygulamanız, söz konusu verilere erişmek için gereken çalışma zamanı iznini isteyebilir.
  4. Kullanıcının, uygulamanızın gerektirdiği çalışma zamanı iznini daha önce verip vermediğini kontrol edin. Bu durumda uygulamanız, gizli kullanıcı verilerine erişebilir. Sorun çözülmezse bir sonraki adıma geçin.

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

  5. Uygulamanızın, kullanıcıya gerekçe gösterip göstermemesi gerektiğini kontrol edin. Bu gerekçede, uygulamanızın kullanıcının belirli bir çalışma zamanı izni vermesine neden ihtiyaç duyduğu açıklanır. Sistem, uygulamanızın gerekçe göstermemesi gerektiğini belirlerse 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ğine karar verirse 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 kullanıcının çalışma zamanında istenen izni vermesi durumunda uygulamanın kullanıcıya sağlayabileceği faydaları net bir şekilde açıklayın. Kullanıcı gerekçeyi onayladıktan 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. Kullanıcının yanıtını kontrol edin. Kullanıcı, çalışma zamanı iznini vermeyi mi yoksa reddetmeyi mi seçti?

  8. Kullanıcı, uygulamanıza izin verdiyse özel kullanıcı verilerine erişebilirsiniz. Kullanıcı izni reddettiyse uygulama deneyiminizi kontrollü bir şekilde azaltın. Böylece, kullanıcıya bu izinle korunan bilgiler olmadan işlevsellik sunabilirsiniz.

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

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

Uygulamanıza iznin verilip verilmediğini belirleme

Kullanıcının uygulamanıza belirli bir izni daha önce verip vermediğini kontrol etmek için bu izni ContextCompat.checkSelfPermission() yöntemine iletin. Bu yöntem, uygulamanızın izni olup olmaması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.

Siz 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 neden istediği belirtilmez. Bazı durumlarda kullanıcı bu durumu kafa karıştırıcı bulabilir. requestPermissions() işlevini çağırmadan önce uygulamanızın neden izin istediğini kullanıcıya açıklamanız iyi bir fikirdir.

Araştırmalar, uygulamaların izin isteme nedenini (ör. iznin uygulamanın temel bir özelliğini desteklemek veya reklamcılık için gerekli olup olmadığı) bilen kullanıcıların bu istekler konusunda çok daha rahat davrandıklarını gösteriyor. Sonuç olarak, bir izin grubu kapsamındaki 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 belirtmeniz gerekir. Örneğin, yalnızca kaba konum kullanıyorsanız bunu uygulama açıklamanızda veya uygulamanızla ilgili yardım makalelerinde kullanıcıya bildirin.

Belirli koşullarda, kullanıcıları hassas verilere erişim hakkında anlık olarak bilgilendirmek de faydalı olur. Örneğin, kameraya veya mikrofona erişiyorsanız uygulamanızın herhangi bir yerinde ya da bildirim tepsisinde (uygulama arka planda çalışıyorsa) bildirim simgesi kullanarak kullanıcılara bilgi vermeniz iyi olur. Böylece, verileri gizlice topladığınız izlenimi vermezsiniz.

Sonuç olarak, uygulamanızda bir şeyin çalışması için izin istemeniz gerekiyorsa ancak bunun nedeni kullanıcıya net bir şekilde açıklanmıyorsa kullanıcıya en hassas izinlere neden ihtiyacınız olduğunu bildirecek bir yol 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 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çıklayın.

İzin isteğinde bulunma

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

Bunu yapmak için AndroidX kitaplığında yer alan RequestPermission sözleşmesini kullanın. Bu sözleşmede, sistemin sizin için izin isteği kodunu yönetmesine izin verirsiniz. RequestPermission sözleşmesini kullanmak mantığınızı basitleştirdiği için mümkün olduğunda önerilen çözümdür. 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 verin.

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.

    registerForActivityResult() işlevinin ActivityResultLauncher türünde olan dönüş değerine referans tutun.

  2. Gerekli olduğunda sistem izinleri iletişim kutusunu göstermek 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()'ı aradığınızda gösterilen 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 anlamasını kolaylaştırın. Örneğin, özelliği etkinleştiren düğmedeki metni değiştirebilirsiniz.

    Ayrıca, sistem izni iletişim kutusundaki metinde, istediğiniz izinle ilişkili izin grubuna referans verilir. 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

// 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'i, izin kontrolü ve gerekirse 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önetin

Sistemin izin isteği kodunu yönetmesine izin vermek yerine izin isteği kodunu kendiniz yönetebilirsiniz. Bunu yapmak için requestPermissions() numarasına yapılan bir aramaya istek kodunu ekleyin.

Aşağıdaki kod snippet'inde, istek kodu kullanarak 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, onRequestPermissionsResult() uygulamanızı ç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 izni isterken diğer çalışma zamanı izinlerinde olduğu gibi aynı en iyi uygulamaları kullanın. Konum izinleriyle ilgili önemli bir fark, sistemin konumla ilgili birden fazla izin içermesidir. İstediğiniz izinler ve bunları nasıl istediğiniz, uygulamanızın kullanım alanıyla ilgili konum şartlarına bağlıdır.

Ön planda konum

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. Örnek olarak aşağıdakiler verilebilir:

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

Uygulamanızın bir özelliği aşağıdaki durumlardan birinde cihazın mevcut konumuna erişirse sistem, uygulamanızın ön planda konum kullandığını kabul eder:

  • Uygulamanıza ait bir etkinlik görünür.
  • Uygulamanız ön plan hizmeti çalıştırıyor. Ön plan hizmeti çalışırken sistem, kalıcı bir bildirim göstererek kullanıcıların farkındalığını artırır. Uygulamanız, arka plana alındığında (ör. kullanıcı cihazındaki ana ekran 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 location ön plan hizmeti türü beyan etmeniz gerekir. Android'in önceki sürümlerinde bu ön plan hizmeti 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 iznini veya ACCESS_FINE_LOCATION iznini istediğinde ön planda konum iznine ihtiyaç duyduğunu beyan edersiniz:

<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 sürekli olarak konum paylaşımı yapıyorsa veya Geofencing API'yi kullanıyorsa arka planda konum erişimi gerekir. Aşağıda birkaç örnek verilmiştir:

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

Sistem, uygulamanızın ön planda konum bölümünde açıklanan durumlar dışında herhangi bir durumda cihazın mevcut konumuna erişmesi halinde arka planda konum kullandığını kabul eder. Arka plan konum doğruluğu, uygulamanızın bildirdiğ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 konum erişimi 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 arka planda konum erişimi 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 ele alma

Kullanıcı bir izin isteğini reddederse uygulamanız, kullanıcının izni reddetmesinin sonuçlarını anlamasına yardımcı olmalıdır. Uygulamanız, özellikle eksik izin nedeniyle çalışmayan özellikler konusunda kullanıcıları bilgilendirmelidir. Bu işlemi yaparken aşağıdaki en iyi uygulamaları göz önünde bulundurun:

  • Kullanıcının dikkatini yönlendirin. Uygulamanızın gerekli izne sahip olmaması nedeniyle işlevselliğin sınırlı olduğu, uygulamanızın kullanıcı arayüzünün belirli bir 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österin.
  • Net olun. Genel bir mesaj göstermeyin. Bunun yerine, uygulamanızda gerekli izin olmadığı için hangi özelliklerin kullanılamadığını net bir şekilde 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 uyarı mesajı göstermeyin.

Aynı zamanda, uygulamanız kullanıcının izni reddetme kararına saygı göstermelidir. Android 11'den (API düzeyi 30) itibaren, uygulamanızın bir cihazda yüklü kaldığı süre boyunca kullanıcı belirli bir izin için Reddet'e birden fazla kez dokunursa uygulamanız bu izni tekrar istediğinde sistem izinleri iletişim kutusu gösterilmez. 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ş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 kalıcı ret olarak kabul edilir. Kullanıcılardan yalnızca belirli bir özelliğe erişmeleri gerektiğinde izin istemeniz çok önemlidir. Aksi takdirde, izinleri yeniden isteme olanağını istemeden kaybedebilirsiniz.

Bazı durumlarda, kullanıcı herhangi bir işlem yapmadan izin otomatik olarak reddedilebilir. (İzinler otomatik olarak da verilebilir.) Otomatik davranışla ilgili herhangi bir varsayımda bulunmamak önemlidir. Uygulamanızın izin gerektiren bir işlevselliğe erişmesi gerektiğinde, uygulamanıza bu iznin hâlâ verilip verilmediğini kontrol edin.

Uygulama izinleri istenirken en iyi kullanıcı deneyimini sağlamak 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ı, 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 ile işaretlenir. Reddet seçeneği iki kez tıklanarak 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ızda hata ayıklama işlemini tamamladığınızda 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 izinler API'si 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österilen 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 gösterilen izin iletişim kutusunda Şekil 2'de gösterildiği gibi Yalnızca bu sefer adlı bir seçenek bulunur. Kullanıcı bu seçeneği iletişim kutusunda belirlerse uygulamanıza geçici bir tek seferlik izin verilir.

Uygulamanız daha sonra, 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ürken uygulamanız verilere erişebilir.
  • Kullanıcı uygulamanızı arka plana gönderirse uygulamanız kısa bir süre boyunca verilere erişmeye devam edebilir.
  • Etkinlik görünürken 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ı, tek seferlik izni (ör. sistem ayarlarında) 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 ve uygulamanızdaki bir özellik konum, mikrofon 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 reddedilen 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 gerektirmediği ç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 daha iyi anlamaları için bu adımı uygulayın. Bu bilgiler, kullanıcıların uygulamanıza güvenmesini sağlar.

Bir çalışma zamanı iznine erişimi kaldırmak için bu iznin adını revokeSelfPermissionOnKill() içine iletin. Bir grup çalışma zamanı iznine erişimi aynı anda kaldırmak için izin adlarının bir koleksiyonunu revokeSelfPermissionsOnKill() içine 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ırması için uygulamanızla ilişkili tüm işlemlerin sonlandırılması gerekir. API'yi çağırdığınızda sistem, bu işlemlerin ne zaman güvenli bir şekilde sonlandırılabileceğini belirler. Genellikle sistem, uygulamanızın ön planda değil de arka planda uzun süre çalışmasını bekler.

Kullanıcıya uygulamanızın artık belirli çalışma zamanı izinlerine erişmesi gerekmediğini 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ırlama

Uygulamanız Android 11'i (API düzeyi 30) veya daha yeni bir sürümü hedefliyorsa ve birkaç aydır 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. Uygulama uyku modu hakkındaki kılavuzdan 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ı ve SMS mesajlarıyla ilgili 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 bir sistem işlevi için varsayılan işleyici olarak ayarlamasını istemeniz gerekir.

Varsayılan işleyiciler hakkında daha fazla bilgi edinmek ve kullanıcılara varsayılan işleyici istemi gösterme ile ilgili yönergeleri incelemek 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 uygulamayı 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 aşağıdaki makaleleri inceleyin:

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