Merih Forum Android / IOS Genel Android 6.0 ve Yenilenen İzin İsteme

  • 0 Oy - 0 Ortalama
  • 1
  • 2
  • 3
  • 4
  • 5
Android 6.0 ve Yenilenen İzin İsteme

 
#1

Bu yazımızda Android 6.0 ile birlikte yenilenen Request Permission yani telefonun bazı özelliklerini kullanabilmek için izin isteme yapısını inceleyeceğiz.
 
Bildiğiniz gibi uygulama içinde kullanmak istediğimiz özellikler için AndroidManifest.xml dosyasına gerekli izinleri tanımlamamız yetiyordu. Kullanıcı Google Play'den uygulamayı indiriken, istediğimiz izinler karşısında listeleniyor ve uygulamayı  indirmek için  bu izinleri kabul etmek zorunda kalıyor. Sonrasında ise uygulama bu özellikleri tekrar izine ihtiyaç duymadan defalarca kez kullanabiliyordu. Fakat Android 6.0 ile bu izin yapısı biraz değişikliğe uğradı. Şöyle ki, Google kullanılan izinleri NORMAL İZİNLER ve TEHLİKLELİ İZİNLER olarak ikiye ayırdı. (Aslında iki değil dört kategori var fakat ilk ikisi yeterli bizim için.) Tehlikeli olarak tanımlanan türden izinler için AndroidManifest.xml'e tanımlamak yeterli olmuyor artık, uygulama çalışırken izin gereken bir iş yapmak istediğinde anında kullanıcıya sorup, her defasında izin almamız gerekiyor.
Özetle,  tüm izinleri yine AndroidManifest.xml'e tanımlıyoruz. Beraberinde tehlikeli izin gerektiren işler içinse uygulama çalışırken tekrar izin istemek zorundayız. IPhone kullanan kullanıcılar bu yapıya aşinadır aslında. Çünkü IOS bu izin yapısını yıllardır başarıyla kullanıyor kendi uygulamaları içinde.
Bahsettiğimiz izin kategorilerine giren izinleri aşağıdaki gibi  listeleyebiliriz.
Normal İzinler:  https://developer.android.com/guide/topics/security/normal-permissions.html
Tehlikeli İzinler: https://developer.android.com/guide/topics/security/permissions.html?normal-dangerous
Örneğin internete bağlanmak normal bir izin gerektiriken, rehbere ulaşmak, SD karta dosya yazmak ya da bir numarayı aramak tehlikeli izin kategorisine giriyor.
İZİNLER İÇİN YENİ BİR DESIGN PATTERN
Gel gelelim bu izinleri nasıl isteyeceğimize. İzin istemek ve kullanıcının izin verip vermediğini kontrol etmek için yaklaşık 30 satırlık standart bir kod yazmamız gerekli. Uygulama içinde ortalama on yerde izin talebinde bulunduğumuzu düşünürsek 300 satırlık gereksiz ve kendini tekrar eden bir kod yığını oluşur. Üstelik izin istediğimiz iş ve izin isteme işlerini aynı metodda toplarsak bu Single Responsibility Prensibine de aykırı olacaktır.
Peki Çözüm Nedir?
Malum yazılım dünyasında patternlar, prensipler derken her işi yapmanın adam akıllı yolları var. Bunun için de tavsiye edilen yöntem Runtime Permissions Activity Pattern'dir.  Uzun lafın kısası, abstract bir Actvitiy sınıfı yazıyoruz. Bu abstract sınıf içinde izin istemek ve izinin sonucunu kontrol etmek için gerekli metodlar bulunuyor.  Yazdığımız tüm Activity sınıflarında bu abstract sınıfı extend ediyoruz ve gönül rahatlığı ile kullanabiliyoruz.
 

Alıntı: RuntimePermissionsActivity.java

 

Kod:
public abstract class RuntimePermissionsActivity extends AppCompatActivity {

   private SparseIntArray mErrorString;

   @Override

   protected void onCreate(@Nullable Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       mErrorString = new SparseIntArray();

   }

   @Override

   public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

       super.onRequestPermissionsResult(requestCode, permissions, grantResults);

       int permissionCheck = PackageManager.PERMISSION_GRANTED;

       for (int permission : grantResults) {

           permissionCheck = permissionCheck + permission;

       }

       if ((grantResults.length > 0) && permissionCheck == PackageManager.PERMISSION_GRANTED) {

           onPermissionsGranted(requestCode);

       } else {

           Snackbar.make(findViewById(android.R.id.content), mErrorString.get(requestCode),

                   Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",

                   new View.OnClickListener() {

                       @Override

                       public void onClick(View v) {

                           Intent intent = new Intent();

                           intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

                           intent.addCategory(Intent.CATEGORY_DEFAULT);

                           intent.setData(Uri.parse("package:" + getPackageName()));

                           intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                           intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

                           intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

                           startActivity(intent);

                       }

                   }).show();

       }

   }

   public void requestAppPermissions(final String[] requestedPermissions,

                                     final int stringId, final int requestCode) {

       mErrorString.put(requestCode, stringId);

       int permissionCheck = PackageManager.PERMISSION_GRANTED;

       boolean shouldShowRequestPermissionRationale = false;

       for (String permission : requestedPermissions) {

           permissionCheck = permissionCheck + ContextCompat.checkSelfPermission(this, permission);

           shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale || ActivityCompat.shouldShowRequestPermissionRationale(this, permission);

       }

       if (permissionCheck != PackageManager.PERMISSION_GRANTED) {

           if (shouldShowRequestPermissionRationale) {

               Snackbar.make(findViewById(android.R.id.content), stringId,

                       Snackbar.LENGTH_INDEFINITE).setAction("GRANT",

                       new View.OnClickListener() {

                           @Override

                           public void onClick(View v) {

                               ActivityCompat.requestPermissions(RuntimePermissionsActivity.this, requestedPermissions, requestCode);

                           }

                       }).show();

           } else {

               /*User has chosen "Never ask again."  So we shouldn't request again.. DO NOTHING*/

           }

       } else {

           onPermissionsGranted(requestCode);

       }

   }

   public abstract void onPermissionsGranted(int requestCode);

}

RuntimePermissionsActivity.java sınıfımız içinde üç tane metod bulunuyor. İlki requestAppPermissions()  isimli metod izin istemek için çağrılması gereken metoddur. Dikkat ederseniz ilk parametresi String değil String dizisidir.(String[]) Yani aynı anda birden fazla izin istemek için kullanılabilir bu metod.
İkinci metod onRequestPermissionsResult()    bizim yazmadığımız, FragmentActivity.java sınıfından miras alıp override ettiğimiz metoddur. Bu metod kullanıcının bize izin verip vermediğini anlayacağımız bir callback yani geri bildirim metodudur.   Eğer kullanıcı bize izin vermişse onPermissionsGranted()    isimli abstract metodu çağırarak, izin isteğinin yapıldığı asıl Activity sınıfına haber veriyoruz. bu metod bu yüzden abstract olarak tanımlandı. Eğer kullanıcı izin vermemişse de elimizden gelen birşey yok. bu özelliği kullanamayacağız demektir.
Sıklıkla yapılan bir hataya dikkat çekmek isterim.  Herhangi bir izin kullanıcıdan red almışsa, bu izin  ikinci kez istendiğinde Android işletim Sistemi, açılan pencereye "Bir daha sorma" şeklinde bir checkbox çıkarır. Kullanıcı bu kısmı işaretlerse, bu izin tekrar istenmemelidir. Bu durum kullanıcıyı rahatsız eder.  Fakat yazılım geliştiriciler genelde bu kontrolü görmezden gelerek bu ayar işaretli olsa da olmasa da izin isteme yoluna giderler. Bu durum kullanıcıyı rahatsız eder.
Kullanıcının bu izin için bir daha rahatsız edilmek istemediğini  requestAppPermissions()   metodu içerisindeki  shouldShowRequestPermissionRationale  değişkeninden anlayabiliyoruz. Eğer false  gelirse kullanıcıyı rahatsız etmiyoruz.
 
Son olarak, bu metodları nasıl çağıracağımıza bakıyoruz. Yazacağımız her Activity sınıfında RuntimePermissionAbstractActivity.java sınıfını extend etmemiz gerekiyor.

Alıntı:  MainActivity.java

Kod:
public class MainActivity extends RuntimePermissionsActivity {

   private static final int REQUEST_PERMISSION_READ_CONTACTS = 1;

   private static final int REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE = 2;

   @Override

   protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_main);



             

MainActivity.super.requestAppPermissions(new

                       String[]{Manifest.permission.READ_CONTACTS,}, R.string

                       .runtime_permissions_txt, REQUEST_PERMISSION_READ_CONTACTS);

             

MainActivity.super.requestAppPermissions(new

                       String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, R.string.runtime_permissions_txt, REQUEST_PERMISSION_READ_CONTACTS);

   }

   @Override

   public void onPermissionsGranted(final int requestCode) {

       if (requestCode == REQUEST_PERMISSION_READ_CONTACTS) {

           Toast.makeText(this, "Permissions Received for reading contacts.", Toast.LENGTH_LONG).show();

       } else if (requestCode == REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE) {

           Toast.makeText(this, "Permissions Received for writing SD card.", Toast.LENGTH_LONG).show();

       }

   }

}

 
Override ettiğimiz  onPermissionsGranted()   metodu,  kabul edilen her izin için tetiklenecek kabul edilmeyenler içinse gereksiz gürültü yapmayacaktır.
Projenin kodlarını Github hesabımızda indirebilir, bedava uygulamanın keyfine varabilirsiniz.
Github : https://github.com/burhanaras/Android-Ru...ermissions
Teşekkürler.




Bul
Alıntı


Benzer Konular...
Konu: Yazar Cevaplar: Gösterim: Son Mesaj
  Kod Enjeksiyonlu İlk Android Virüsü sempatik141 0 2,570 17-06-2017, Saat: 17:26
Son Mesaj: sempatik141
  Android için Google Chrome'a önemli güncelleme selami 0 2,519 10-05-2017, Saat: 19:37
Son Mesaj: selami
  Android Versiyonlar blueman 0 2,685 12-04-2017, Saat: 20:39
Son Mesaj: blueman
  Android Xposed Framework Nedir? Nasıl Yüklenir? blueman 0 2,835 12-04-2017, Saat: 20:18
Son Mesaj: blueman
  Android O ile gelen yenilikler blueman 0 2,445 12-04-2017, Saat: 20:16
Son Mesaj: blueman

Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


Bu konuyu görüntüleyen kullanıcı(lar):
1 Ziyaretçi

   
Türkçe Çeviri: Emre KRMN, Kodlayanlar MyBB, © 2002-2024 MyBB Group.  



Merih Forum® bilgi paylaşım platformu. 2015-∞ Tüm hakları saklıdır.