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

Dota 2. MMR sıralamada Türkler

Tr bayraklı Neqroman sadece listeye 163. sıradan girebildi

ABD'nin terörist sevgisi

ABD'nin, terör örgütü PYD/PKK’ya DEAŞ ile mücadele adı altında askeri sevkiyatları sürüyor.

DOTA2 - 2017 THE INTERNATIONAL CHAMPIONSHIP

2017 yazında düzenlenen turnuvada Team Liquid şampiyon oldu

  • Toplam: 0 Oy - Ortalama: 0
  • 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-Runtime-Permissions
Teşekkürler.




Ara
Cevapla


[-]
Hızlı Cevap

İnsan Doğrulama:
Aşağıda görünen onay kutusunu işaretleyiniz. Bu işlem otomatik spam kayıtları önlemek için kullanılır.

Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Kod Enjeksiyonlu İlk Android Virüsü sempatik141 0 405 17-06-2017, Saat: 16:26
Son Yorum: sempatik141
  Android için Google Chrome'a önemli güncelleme selami 0 455 10-05-2017, Saat: 18:37
Son Yorum: selami
  Android Versiyonlar blueman 0 633 12-04-2017, Saat: 19:39
Son Yorum: blueman
  Android Xposed Framework Nedir? Nasıl Yüklenir? blueman 0 558 12-04-2017, Saat: 19:18
Son Yorum: blueman
  Android O ile gelen yenilikler blueman 0 496 12-04-2017, Saat: 19:16
Son Yorum: blueman

Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


Konuyu Okuyanlar:
1 Ziyaretçi

   
Türkçe Çeviri: MCTR, Forum Yazılımı: MyBB, © 2002-2018 MyBB Group.  



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