Android Runtime Permission

Merhabalar, Android M ile birlikte runtime permission olayı hayatımıza girdi. Ben de bu konu hakkında bilgilendirmelerde bulunmak istiyorum.

Runtime permission özelliği gelmeden önce kullanıcılar bu izin verme olayı hakkında tam olarak yetkinliği yoktu. Hepsini kontrol edemiyordu. Bu gelen özellikle beraber, izni gerektiği yerde verme ile kullanıcı kontrolü sağlanmış olmuşa benziyor. En basitinden facebook uygulamasını yüklediğinizde önünüze elektrik faturası gibi kocaman bir permission sheet çıkıyordu, kullanmasam mı diye düşünüyordu insan. Mikrofon, takvim etkinlikleri, fotoğraflar, her şeye erişimi bir anda veriyorsunuz böyle olunca, bi nevi uygulamayı zorla yüklettirmiş gibi oluyorlardı. Fakat izin olaylarını runtime yapınca hem o düşünce hem de başlangıçtaki gereken izin sayısı büyük oranda kalkmışa benziyor, çünkü gerekli yerde veriyor kullanıcı izni. Bu arada Android M öncesi sürümlerde yine uygulama yüklenirken tüm izinleri soracak, uygulama güncellendiğinde yeni izin gerekiyorsa yine güncellerken soracak.

İzin grupları

Şimdi gelelim kaç tür izin var.

Android M ile birlikte izinler 8 gruba ayrılmış durumda. En basitinden kamera izni isteneceği zaman android.permission.CAMERA iznini kod içerisinde kullanmak gerekiyor. Aşağıda izinlerin listesi verilmiş durumda:

Bu sürümden sonra kullanıcıdan internete bağlanma izni almak artık gerekmiyor. Bu iznin PermissionInfo değeri PROTECTION_NORMAL olarak değiştirilmiş durumda, manifest dosyasında tanımlanmış bu değere sahip tüm izin türlerini sistem otomatik izin verilmiş olarak kabul ediyor.

Android M’ye özel permission tanımlamak

Telefon Android M sürümü üzerinde çalışıyorsa, sadece o sürüme özel izin tanımlanabilir. Bir önceki sürümler için endişelenmeden uygulamayı yeni sürümlere güncellemeyi kolaylaştırmaktadır.

<uses-permission-sdk-m android:name="android.permission.ACCESS_FINE_LOCATION"/>

Uygulama bilgileri içerisinde izinler seçeneğinden önceden vermiş olduğunuz izinleri devre dışı bırakmak mümkün. Fakat kullanıcı runtime izni sürekli reddediyorsa bu sefer uygulama içerisinde dönen değerler şu şekilde olacaktır:

  • Kişilere erişilmeye çalışıldığında “No contacts” ,
  • Konuma erişilmeye çalışıldığında “Location not available” ,
  • Yeni kişi eklemeye çalışıldığında “Kişi eklendi” dönecek fakat kişi eklenmeyecektir.

Yani kod yazarken error handling iyi yapılmış olmalıdır.

İzin düzeyleri

Önemli gözüken iki çeşit izin düzeyi vardır:
PROTECTION_NORMAL : İzin verilmesinde herhangi bir tehlike görülmeyen izin türüdür. Sistem otomatik izin verir. Örnek olarak ACCESS_WIFI_STATE ve WAKE_LOCK  izinleri örnek verilebilir.
PROTECTION_DANGEROUS : İzin verilmesi halinde kullanıcı mahremiyetine dokunabilecek türdür. Örnek olarak READ_CONTACTS verilebilir.

Buradan ayrıntılı resmi dökümana ve buradan kullanılan değerlere ulaşabilirsiniz.

Tekli izin isteği

Burada izin türünü tanımlayıp, izin önceden verilmediyse izni kullanıcıdan istiyoruz.

private static final int REQUEST_LOCATION = 1503;

private void requestSinglePermission() {
    String locationPermission = Manifest.permission.ACCESS_FINE_LOCATION;
    int hasPermission = checkSelfPermission(locationPermission);
    String[] permissions = new String[] { locationPermission };
    if (hasPermission != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(permissions, REQUEST_LOCATION);
    } else {
        // Phew - we already have permission!
    }
}

Kullanıcıdan izin alındıysa, alttaki kod parçası izni alır ve kontrol eder, izin verildiyse if case’in içindeki komutu çalıştırır, izin verilmediyse, else case’in içindekini çalıştırır.

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case REQUEST_LOCATION:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Handle permission granted
            } else {
                // Handle permission denied
            }
            break;
        default: 
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Dikkat ettiyseniz grantResults dizisinin ilk elemanına ulaşmaya çalıştık, yani tek bir izin istedik. Şimdi çoklu izin örneğini görelim.

Çoklu izin isteği

Burada da aynı izin kontrolü yapacağız.
İstenilen izinlerin hepsi listeye kaydedilir ve o şekilde izin istenir. Aşağıda kullanıcıdan dönen cevap işlenir ve istenen kod parçacığı çalıştırılır.

private void requestMultiplePermissions() {
    String locationPermission = Manifest.permission.ACCESS_FINE_LOCATION;
    String calendarPermission = Manifest.permission.WRITE_CALENDAR;
    int hasLocPermission = checkSelfPermission(locationPermission);
    int hasCalPermission = checkSelfPermission(calendarPermission);
    List<String> permissions = new ArrayList<String>();
    if (hasLocPermission != PackageManager.PERMISSION_GRANTED) {
        permissions.add(locationPermission);
    }
    if (hasCalPermission != PackageManager.PERMISSION_GRANTED) {
        permissions.add(calendarPermission);
    }
    if (!permissions.isEmpty()) {
        String[] params = permissions.toArray(new String[permissions.size()]);
        requestPermissions(params, REQUEST_PERMISSIONS);
    } else {
        // We already have permission, so handle as normal
    }
}

Runtime permission için yazılmış Dexter kütüphanesi örneklerine buradaki yazımdan bakabilirsiniz.

Leave a Reply

Your email address will not be published. Required fields are marked *