Mesh Renderer, Unity’de 3D nesnelerin sahnede görüntülenmesini sağlayan önemli bir bileşendir. Mesh Filter nesnenin şekil ve geometrisini tanımlarken, Mesh Renderer ise bu şeklin sahnede nasıl görüneceğini, materyal, ışık yansımaları gibi görsel detayları belirler.
1. Mesh Renderer Menüsüne Nasıl Ulaşılır?
Mesh Renderer bileşenine Unity’de şu adımlarla ulaşabilirsiniz:
Hierarchy Panelinden Ekleme: Sahneye bir 3D nesne (örneğin bir Cube veya Sphere) ekleyin. Unity, nesneye otomatik olarak Mesh Renderer ekleyecektir.
Inspector Panelinde Mesh Renderer’i Görüntüleme: 3D nesne seçildiğinde, Inspector panelinde Mesh Renderer bileşenini görebilir ve özelliklerini düzenleyebilirsiniz.
Manuel Mesh Renderer Ekleme: Eğer bir nesneye manuel olarak Mesh Renderer eklemek isterseniz, Add Component butonuna tıklayıp “Mesh Renderer” araması yaparak ekleyebilirsiniz.
2. Mesh Renderer Çeşitleri
Unity’de Mesh Renderer bileşeni, temel olarak tek bir türdür ancak farklı materyallerle ve ayarlarla özelleştirilebilir. Mesh Renderer, sadece 3D projelerde kullanılan bir bileşendir ve 2D projelerde doğrudan işlevi yoktur. Fakat Mesh Renderer, çeşitli materyaller, ışık ve gölge ayarları ile zenginleştirilebilir.
Standart Materyallerle Kullanım: Unity’nin yerleşik materyalleriyle (Diffuse, Standard) çalışarak nesnenin temel rengini, yansımasını ve ışıkla etkileşimini ayarlar.
Özel Shader ve Materyallerle Kullanım: Özel shader’lar kullanılarak daha detaylı görseller ve efektler elde edilebilir.
HDRP ve URP Materyalleri: Unity’nin HDRP (High Definition Render Pipeline) veya URP (Universal Render Pipeline) kullanılarak daha gelişmiş ışık ve gölge efektleri sağlanır.
3. Mesh Renderer Özellikleri ve Ayrıntılı Açıklamaları
Mesh Renderer, nesnenin nasıl render edileceğini belirlemek için pek çok özelliğe sahiptir. Aşağıda Mesh Renderer bileşeninin en önemli özelliklerini, ne işe yaradıklarını ve nasıl kullanıldıklarını detaylı olarak açıklayan bir tablo sundum:
Özellik
Açıklama
Kullanım Durumları
Programatik Erişim
Materials
Nesneye atanan materyallerin listesini gösterir. Mesh Renderer, nesneyi bu materyallerle render eder.
Farklı materyaller ile nesne yüzeyini özelleştirmek için kullanılır.
meshRenderer.materials = new Material[]{mat1, mat2};
Cast Shadows
Nesnenin gölge oluşturup oluşturmayacağını belirler. On, Off, Two Sided, Shadows Only gibi seçenekler vardır.
Gerçekçi gölgeler için veya gölgesiz nesneler gerektiğinde kullanılır.
Mesh Renderer bileşeninin tüm özelliklerine C# kodu ile erişebilir ve bu özellikleri değiştirebilirsiniz. Aşağıda her bir özelliğin kod ile nasıl kontrol edilebileceğini gösteren bir tablo hazırladım:
Özellik
Kod ile Erişim Örneği
Açıklama
Materials
meshRenderer.materials = new Material[] { mat1, mat2 };
4. Mesh Renderer Özelliklerinin Değer Aralıkları ve Kullanım Durumları
Aşağıdaki tabloda Mesh Renderer özelliklerinin alabileceği değer aralıklarını ve önerilen durumları detaylandırdım:
Özellik
Değer Aralığı / Seçenekler
Önerilen Değerler
Kullanım Durumları
Cast Shadows
On, Off, Two Sided, Shadows Only
On (genel kullanım), Off (gölge gerekmiyorsa)
Gölge oluşturması gereken nesnelerde On, gölge gerekmediğinde Off.
Receive Shadows
true / false
true (gölge alan yüzeylerde)
Gölge alan yüzeyler için true, gölge almaması gereken durumlarda false.
Light Probes
Off, Blend Probes, Use Proxy Volume
Blend Probes
Çevresel ışık etkilerini kullanmak için Blend Probes ayarı yapılabilir.
Reflection Probes
Off, Blend Probes, Simple, Use Proxy Volume
Blend Probes
Yansıma etkilerini eklemek için Blend Probes seçeneği kullanılabilir.
Probe Anchor
Transform referansı
Nesneye uygun bir anchor
Yansıma veya ışık etkilerinin merkezleneceği konum için uygun referans.
Materials
Materyal listesi
Uygun materyal seçimi
Nesnenin yüzey yapısına göre materyal atanmalıdır.
5. Mesh Renderer Kullanım Alanları ve Dikkat Edilecekler
Kullanım Alanları
3D Nesnelerin Render Edilmesi: Mesh Renderer, nesnenin sahnede görünür olmasını sağlar. Bu, 3D nesnelerin tümünde kullanılabilir.
Materyal ve Gölge Kontrolü: Mesh Renderer, nesnenin hangi materyalle render edileceğini belirler ve gölge efektlerini yönetir.
Yansıma ve Işık Etkileşimleri: Mesh Renderer, ışık ve yansıma propları ile etkileşime girerek sahneye gerçekçi ışıklandırma efektleri ekler.
Dikkat Edilmesi Gerekenler
Materials Ayarı: Çok sayıda materyal kullanımı, performansı etkileyebilir. Mümkün olduğunca az sayıda materyal kullanarak optimizasyon sağlanmalıdır.
Cast Shadows ve Receive Shadows Ayarları: Gereksiz gölgelerden kaçınmak için doğru ayar yapılmalıdır. Örneğin, küçük ve önemsiz nesnelerin gölge oluşturmasına gerek olmayabilir.
Light ve Reflection Probes Kullanımı: Işık ve yansıma propları, sahneye gerçekçilik katabilir ancak performansı etkileyebilir. Propları uygun noktalarda kullanmak önemlidir.
Uygulanmaması Gereken Nesneler
2D Nesneler ve UI Elemanları: Mesh Renderer, 3D nesneler için geliştirilmiştir. 2D projelerde veya UI elemanlarında kullanılması gerekmez.
Görünmez veya Statik Nesneler: Sahnede görüntülenmesi gerekmeyen, sadece fiziksel olarak var olan nesnelerde Mesh Renderer kullanmaya gerek yoktur.
Özet
Dikkat Edilmesi Gereken Noktalar: Gereksiz materyal ve gölgelerden kaçınılmalı, doğru ışık ve yansıma ayarları yapılmalıdır.
Mesh Renderer Menüsüne Erişim: 3D nesnelerle çalışırken otomatik olarak eklenir ya da manuel olarak Add Component ile eklenebilir.
Çeşitleri: Tek bir Mesh Renderer bileşeni vardır, ancak farklı materyal ve shader’larla özelleştirilebilir.
Özellikler ve Kullanımı: Materials, Cast Shadows, Receive Shadows gibi özellikleri bulunur ve her biri render kalitesini etkiler.
Kullanım Alanları: 3D nesneleri render etme, materyal ve gölge kontrolü sağlama, ışık ve yansıma etkileşimleri için kullanılır.
Material (Malzeme), Unity’de bir nesnenin yüzey özelliklerini tanımlamak için kullanılır ve nesnelerin renk, yansıma, saydamlık gibi görsel efektlerini kontrol eder. Material, 3D nesnelerde olduğu gibi 2D nesnelerde de kullanılabilir, ancak temel olarak 3D projelerde daha fazla işlev görür.
Material bileşeni, sahnedeki nesnelerin gerçekçi veya stilize bir görünüme sahip olmasını sağlar. Material bileşeninin yüzey özellikleri Shader adı verilen görsel işleme motorları ile belirlenir. Her material bir shader kullanır, ancak shader’ı değiştirdikçe material’in özellikleri de değişir.
1. Materials Menüsüne Nasıl Ulaşılır?
Unity’de Material bileşeni oluşturmak ve düzenlemek için şu adımları izleyebilirsiniz:
Project Panelinde Material Oluşturma:
Assets paneline sağ tıklayın, ardından Create > Material seçeneğini tıklayın. Yeni bir Material oluşturulacaktır.
Inspector Panelinde Material’i Düzenleme:
Material’i seçtiğinizde, sağ taraftaki Inspector panelinde Material özelliklerini görebilir ve düzenleyebilirsiniz.
Nesneye Material Ekleme:
Bir nesneye material eklemek için oluşturduğunuz material’i doğrudan nesnenin üzerine sürükleyebilirsiniz. Alternatif olarak, Mesh Renderer bileşeninde Material alanına material’i sürükleyip bırakabilirsiniz.
2. Material Çeşitleri
Unity’de Material’ler, kullanılan shader türüne göre çeşitlenir. Material’in hangi türde görüneceğini belirleyen şey Shader’dır. Unity, farklı efektler için çeşitli yerleşik shader’lar sağlar. İşte en yaygın kullanılan shader türleri:
Standard Shader: Unity’nin varsayılan shader’ıdır ve pek çok özelliğe sahiptir. Nesnelerin saydamlığı, yansıması, metalik görünümü gibi özellikleri kontrol edilebilir.
Unlit Shader: Işıktan etkilenmeyen basit bir shader türüdür. Özellikle simgesel veya çizgi film tarzı grafikler için uygundur.
Transparent Shader: Saydam nesneler için kullanılır. Cam, su veya duman efektleri için idealdir.
Toon Shader: Çizgi film tarzı gölgelendirme sağlar ve stilize grafikler için uygundur.
HDRP ve URP Shader’ları: Unity’nin High Definition Render Pipeline (HDRP) ve Universal Render Pipeline (URP) shader’ları, yüksek kaliteli grafikler için optimize edilmiştir ve HDRP veya URP projelerinde kullanılır.
3. Material Özellikleri ve Ayrıntılı Açıklamaları
Aşağıda Material bileşeninin özelliklerini, ne işe yaradıklarını ve nasıl kullanıldıklarını ayrıntılı olarak açıkladığım bir tablo bulabilirsiniz:
Özellik
Açıklama
Kullanım Durumları
Programatik Erişim
Albedo (Renk)
Nesnenin temel rengini veya dokusunu belirler. Material’in ana rengidir.
Tüm nesnelerin temel renk ve dokusunu ayarlamak için.
material.SetColor("_Color", Color.red);
Metallic
Nesnenin metalik görünümünü belirler. 0 ile 1 arasında değer alır. 1 değeri nesneyi tamamen metalik yapar.
Metalik yüzeyler veya parlak metaller için yüksek değer kullanılabilir.
material.SetFloat("_Metallic", 0.5f);
Smoothness (Pürüzsüzlük)
Yüzeyin ne kadar yansıtıcı veya pürüzsüz olduğunu belirler. 0 ile 1 arasında değer alır.
Cam veya parlak yüzeylerde yüksek, mat yüzeylerde düşük değer kullanılabilir.
material.SetFloat("_Glossiness", 0.8f);
Normal Map
Nesnenin yüzeyine detay kazandıran bir harita ekler. Normallerin etkisini arttırır, yüzeye gerçekçilik katılır.
Kabartma efektleri veya yüzey detayları vermek için kullanılır.
material.SetTexture("_BumpMap", normalTexture);
Occlusion (Gölgeleme)
Nesnenin çevresel gölgelenmesini belirler. 0 ile 1 arasında değer alır, yüzeyin gölge miktarını etkiler.
Çevresel ışık alan yüzeylerde gölge derinliği sağlamak için kullanılır.
material.SetFloat("_OcclusionStrength", 1.0f);
Emission (Emisyon)
Nesnenin kendi ışığını yaymasını sağlar. Karanlıkta bile parlayarak dikkat çeken nesneler için kullanılır.
LED ekranlar, ışık saçan nesneler veya neon efektleri için.
material.SetColor("_EmissionColor", Color.blue);
Detail Map (Detay Haritası)
Yüzeydeki ince detayları arttırmak için ek bir harita sağlar.
Doku detaylarını arttırmak ve daha gerçekçi yüzeyler için kullanılır.
Material bileşeninin özelliklerine C# kodu ile erişebilir ve bunları değiştirebilirsiniz. İşte Material özelliklerine kodla nasıl erişileceğini gösteren bir tablo:
Özellik
Kod ile Erişim Örneği
Açıklama
Albedo (Renk)
material.SetColor("_Color", Color.red);
Nesnenin temel rengini kırmızıya ayarlar.
Metallic
material.SetFloat("_Metallic", 0.5f);
Nesnenin metalik görünümünü %50 olarak ayarlar.
Smoothness (Pürüzsüzlük)
material.SetFloat("_Glossiness", 0.8f);
Yüzeyi daha pürüzsüz ve yansıtıcı yapar.
Normal Map
material.SetTexture("_BumpMap", normalTexture);
Normaller haritasını ekler, yüzey detayları kazandırır.
Occlusion (Gölgeleme)
material.SetFloat("_OcclusionStrength", 1.0f);
Gölgeleme efektini maksimize eder.
Emission (Emisyon)
material.SetColor("_EmissionColor", Color.blue);
Emisyon rengi mavi olarak ayarlanır, yüzey parlak görünür.
4. Material Özelliklerinin Değer Aralıkları ve Kullanım Durumları
Aşağıdaki tabloda Material bileşeninin özelliklerine ait değer aralıklarını ve hangi durumlarda hangi değerlerin kullanılabileceğini detaylandırdım:
Özellik
Değer Aralığı / Seçenekler
Önerilen Değerler
Kullanım Durumları
Albedo (Renk)
Renk paleti
Yüzeyin istenen rengine göre
Nesnenin ana rengini belirlemek için.
Metallic
0 – 1
0.5 (Orta parlaklık), 1 (Tam parlaklık)
Metalik yüzeylerde 0.5-1 arası, mat yüzeylerde daha düşük değerler tercih edilir.
Smoothness (Pürüzsüzlük)
0 – 1
0.7 (Cam için), 0.2 (Ahşap için)
Yansıtıcı yüzeyler için yüksek, mat yüzeyler için düşük değerler.
Normal Map
Doku Haritası
Normal Map kullanımı
Yüzey detayları vermek için yüksek çözünürlüklü normal mapler tercih edilir.
Occlusion (Gölgeleme)
0 – 1
1 (Yoğun gölgeler), 0.5 (Yumuşak gölgeler)
Koyu gölge isteyen nesnelerde yüksek, hafif gölgelerde düşük değerler.
Emission (Emisyon)
Renk paleti
Renk ve ışık yayılımına göre
LED ışıklar, neon tabelalar veya ışık saçan nesneler için parlak renkler tercih edilir.
Detail Map
Doku Haritası
Detay yoğunluğuna göre
Küçük detaylar, ince çizgiler veya yüzey efektleri için kullanılır.
Rendering Mode
Opaque, Transparent, Cutout, Fade
Opaque (Kapalı yüzey), Transparent (Saydam yüzey)
Cam veya saydam yüzeylerde Transparent, katı yüzeylerde Opaque kullanılır.
5. Material Kullanım Alanları ve Dikkat Edilecekler
Kullanım Alanları
Nesne Yüzeylerini Belirleme: Material, bir nesnenin rengini, yansımasını ve ışıkla olan etkileşimini belirler. Tüm nesnelerde kullanılabilir.
Saydam ve Yarı Saydam Yüzeyler: Saydamlık gerektiren cam, su veya duman gibi efektlerde Material’in Transparent veya Cutout gibi render modları tercih edilir.
Özel Shader ve Grafik Efektleri: Unity’nin yerleşik shader’ları dışında, özel shader’lar kullanarak daha gerçekçi ve karmaşık efektler elde edebilirsiniz.
Dikkat Edilmesi Gerekenler
Doğru Render Modu Kullanımı: Saydam yüzeyler için Transparent, mat yüzeyler için Opaque seçilmelidir. Yanlış render modu performansı düşürebilir.
Metalik ve Pürüzsüzlük Ayarları: Yüksek metalik ve pürüzsüzlük değerleri, özellikle mobil cihazlarda performans sorunlarına yol açabilir. Gereksiz yüksek değerlerden kaçınılmalıdır.
Texture Boyutları: Yüksek çözünürlüklü texture’lar, bellekte fazla yer kaplayabilir ve oyunun performansını düşürebilir. Texture boyutları optimize edilmelidir.
Uygulanmaması Gereken Nesneler
Arka Plan veya Statik Grafikler: Material, genellikle 3D nesnelerde kullanılır. Arka planlarda ve statik grafiklerde gereksiz kullanımdan kaçınılmalıdır.
UI Elemanları: 2D UI elemanlarında Sprite Renderer ve UI Material tercih edilmelidir. Standart Material, UI elemanları için fazla olabilir.
Özet
Dikkat Edilecek Noktalar: Doğru render modu kullanımı, texture boyutlarının optimize edilmesi ve metalik/pürüzsüzlük ayarlarına dikkat edilmelidir.
Materials Menüsüne Erişim: Project panelinde Create > Material yoluyla yeni bir material oluşturulur ve Inspector panelinde ayarlanır.
Çeşitleri: Material, Standard, Unlit, Transparent, Toon gibi farklı shader’larla özelleştirilebilir.
Özellikler ve Kullanımı: Albedo, Metallic, Smoothness, Normal Map gibi özellikler ile nesne yüzeyi üzerinde tam kontrol sağlanır.
Kullanım Alanları: Nesne yüzeyini tanımlamak, saydamlık veya parlaklık efektleri eklemek, özel shader’lar ile görsel kaliteyi artırmak için kullanılır.
İzin kelimesinin resmi anlamı, birisinin belirli bir şeyi yapmasına izin vermek anlamına gelir – herhangi bir işlem yapılması için verilen izin veya izindir. Android dünyasında, izinler mektup tanımını takip ediyor. Android uygulamaları, bazıları kullanıcılardan izin gerektiren bir dizi işlem gerçekleştirmek üzere oluşturulmuştur.
Bu yazı da Android’in izinlerini nasıl sınıflandırdığını ve kullanıcılardan nasıl izin alacağınızı anlamaya çalışacağız. Bu izinler doğru şekilde kullanılmazsa, uygulamanın çökmesine neden olabilir.
Varsayılan olarak, bir Android uygulaması kendisine verilen sıfır izinlerle başlar. Uygulamanın, cihazın korumalı özelliklerinden herhangi birini kullanması gerektiğinde (ağ istekleri gönderme, kameraya erişme, SMS gönderme vb.), kullanıcının bunu yapması için uygun izin alması gerekir.
Yani Android’in izin sistemi, kurulum sırasında bu izinlerin istenmesi nedeniyle baştan beri en büyük güvenlik sorunlarından biridir. Uygulama bir kez yüklendiğinde, herhangi bir kullanıcının izni ile tam olarak ne yaptığını kabul etmeden, herhangi bir kullanıcının onayı olmadan verilen tüm şeylere erişebiliyordu. Bu güvenlik zayıflığıyla kullanıcının kişisel verilerini toplamaya ve bunları kötü bir şekilde kullanmaya çalışan çok fazla yazılım mevcuttu. Android özgürlüktü ama bu sebepten de çok eleştiriliyordu.
Özgürlüktü ama dezavantajı da oldukça açıktı: geliştiriciler veri toplamak için izin almaya ve kullanıcının gizliliğini ihlal etmeye başladı. Google, uygulamanın söz konusu izinleri gerçekten gerektirip gerektirmediğini kontrol etmediğinden ve kullanıcının belirli izinleri sağlama ve uygulamayı kullanmaya devam etme seçeneği bulunmadığından, geliştiriciler sistem bilgisine veya mikrofona herhangi bir kısıtlama olmadan erişme konusunda çok rahattılar
.
Android içerisinde 130’dan fazla farklı izin türü vardır. Geliştiricilerin bunlardan her biri için izin alması zordu. Daha da kötüsü, uygulamanızın kullanıcıların kaç tane iznine ihtiyacı olduğunu görmelerinin korkutuculuğundan ziyade neden bu kadar çok izne ihtiyacınız olduğunu kullanıcıya açıklamak çok daha zordur.
Android M (Marshmallow , Android 6.0, API 23)
İOS’un aksine, Android uygulama izinlerine partiye biraz geç geldi. Android Marshmallow (Android M), 5 Ekim 2015 tarihinde piyasaya sürüldü.
Marshmallow’dan önce, izinler kurulum zamanında ele alınmış AndroidManifest.xml ve proje içerisinde belirtilmiştir . İzinlerin tam listesi burada bulunabilir.
Marshmallow’dan önce izinler çok daha basittir (API 23). Tüm izinler kurulum sırasında ele alındı. Bir kullanıcı Google Play Store’dan bir uygulama yüklemeye gittiğinde , kullanıcıya uygulamanın gerekli kıldığı izinlerin bir listesi sunuldu (bazı kişiler buna “izin duvarı” olarak adlandırılıyordu. Kullanıcı tüm izinleri kabul edip devam edebilirdi. Uygulamayı yüklemek veya uygulamayı yüklememeye karar vermekle, kullanıcı izinlerin tamamına izin veriyordu ya da hiç birine izin vermiyordu.Uygulama için yalnızca belirli izinlervermenin bir yolu yoktu ve kullanıcının uygulama yüklendikten sonra belirli izinleri iptal etmesinin bir yolu yoktu.
Android Marshmallow’un halka açık sürümüyle Google, Android için çalışma zamanı izinlerini sundu ve böylece izinler alanını daha iyi hale getirdi. Android Marshmallow, yalnızca izinleri basitleştirmek değil, aynı zamanda gereken izin sayısını azaltmak için uygulama izinlerinde tamamen yeni bir uygulama sunar.
Peki daha önce başlatılmış olan uygulamaya ne oldu?
Eski uygulamalar Android Marshmallow’da çalışacak mı? TargetSdkVersion 22 ya da daha az ise cevap evet .
Bu yeni izin sistemi şu anda size biraz panik getirebilir. “Hey! 3 yıl önce başlattığım uygulamama ne oldu. Android 6.0 aygıtına yüklenmişse, bu davranış da geçerli mi? Uygulamam da çökecek mi?!?”
Endişelenme. Android ekibi çoktan düşünmüş. Uygulamanın targetSdkVersion değeri 23’ten küçükse, uygulamanın henüz yeni izin sistemiyle test edilmediği ve aynı eski davranışa geçeceği varsayılır: kullanıcı yükleme zamanında her bir izni kabul etmek zorundadır ve hepsine izin verilir kurulduktan sonra!
Sonuç olarak, uygulama önceki gibi mükemmel şekilde çalışacaktır. Yine de, kullanıcının bundan sonra hala bir izni iptal edebileceğini unutmayın! Her ne kadar Android 6.0 bunu yapmaya çalıştıklarında kullanıcıyı uyarıyorlar ancak yine de iptal edebiliyorlar.
Şu an kafandaki bir sonraki soru. Peki başvurum çökecek mi?
Android ekibi aracılığıyla Tanrı’dan gönderilen böylesi bir nezaket. TargetSdkVersion uygulamasının 23’ten daha az olduğu uygulamada izinli kullanıcının iptal edilmesini gerektiren bir işlev çağırdığımızda, İstisna atılmaz. Bunun yerine sadece hiçbir şey yapmaz. Değeri döndüren işlev için nulldöndürür veya 0 duruma göre değişir.
Android 6.0 Marshmallow’da, uygulama kurulum sırasında herhangi bir izin verilmez. Bunun yerine, uygulama çalışma zamanında kullanıcıdan birer birer izin istemelidir.
Sağdaki reismde yani Api 23 den sonra geliştiricinin, kullanıcının henüz izin vermemiş olması gereken izni gerektiren bazı işlevleri çağırmayı denemesi durumunda, işlev aniden uygulamanın çökmesine neden olacak bir İstisna atar.
Ayrıca, kullanıcı telefonun Ayarlar uygulamasını kullanarak verilen izni istediği zaman iptal edebilir.
Şimdi geliştirici artık uygulama kurulumunda tüm izinlere sahip değil. Bunun yerine, geliştiricinin bir resmi tıklatmak veya bir dosyayı kaydetmek için kullanıcının deposuna erişmek için kamerayı kullanmak gibi belirli bir işlemi gerçekleştirme iznini istemesi gerekir. Google ayrıca Android’deki izinler kümesini normal ve tehlikeli izinlere ayırdı .
Kurulum sırasında otomatik olarak verilecek ve iptal edilemeyecek bazı izinler vardır. Buna Normal İzin (PROTECTION_NORMAL) diyoruz.
Normal izinler, kullanıcının gizliliği veya cihazın çalışması için risk teşkil etmeyen izinlerdir. Sistem bu izinleri otomatik olarak verir. Bunlar arasında internete bağlanmak, ağ, Bluetooth, wifi ve NFC bilgilerini almak, alarmları ve duvar kağıtlarını ayarlamak ve bir cihazdaki ses ayarlarını değiştirmek sayılabilir.
Normal izinler, uygulamanızın uygulama sanal alanı dışındaki verilere veya kaynaklara erişmesi gereken alanları kapsar, ancak kullanıcının gizliliği veya diğer uygulamaların çalışması için çok az risk olduğu yerlerdir. Örneğin, saat dilimini ayarlama izni normal bir izindir.
Bir uygulama normal bir izne ihtiyaç duyduğunu beyan ederse, sistem otomatik olarak bu izni yükleme sırasında uygulamayı verir. Sistem, kullanıcıdan normal izinler vermesini istemez ve kullanıcılar bu izinleri iptal edemez.
Android 9’dan itibaren (API seviyesi 28), aşağıdaki izinler şöyle sınıflandırılır PROTECTION_NORMAL:
Sadece basitçe bu izin isteklerini AndroidManifest.xml dosyasına yazın, gayet iyi sonuç verecektir. Bu izinler kullanıcı tarafından İptal edilemediğinden yazılım içerisinde bu listelenen izinleri kontrol etmeniz gerekmez.
Sistem bu uygulama izinlerini yükleme sırasında verir, ancak yalnızca izin kullanmaya çalışan uygulama, izni tanımlayan uygulama ile aynı sertifika ile imzalandığında verilir.
Android 8.1’den itibaren (API seviyesi 27), üçüncü taraf uygulamaların kullanabileceği aşağıdaki izinler şöyle sınıflandırılır PROTECTION_SIGNATURE:
Tehlikeli izinler, uygulamanın, kullanıcının kişisel bilgilerini içeren veri veya kaynakları istediği veya kullanıcının depolanan verilerini veya diğer uygulamaların çalışmasını etkileyebileceği alanları kapsar. kullanıcının gizliliğini veya cihazın çalışmasını potansiyel olarak etkileyebilecek izinlerdir. Kullanıcı açıkça bu izinleri vermeyi kabul etmelidir. Bunlar, kameraya, rehbere, konuma, mikrofona, sensörlere, SMS’e ve depolamaya erişmeyi içerir.
Örneğin, kullanıcının bağlantılarını okuyabilmek tehlikeli bir izindir. Bir uygulama tehlikeli bir izin gerektirdiğini bildirirse, kullanıcının açıkça uygulamaya izin vermesi gerekir. Kullanıcı izni onaylayana kadar, uygulamanız bu izne bağlı işlevler sağlayamaz.
Normal ve tehlikeli izinler gibi davranmayan birkaç izin vardır. SYSTEM_ALERT_WINDOWve WRITE_SETTINGSözellikle hassastır, bu nedenle çoğu uygulama bunları kullanmamalı. Bir uygulama şu izinlere birini gerekiyorsa, apaçık izne beyan, gerekir ve kullanıcının izni talep eden bir niyet gönderin. Sistem, kullanıcıya ayrıntılı bir yönetim ekranı göstererek amacına cevap verir.
Android sistemi tarafından sağlanan tüm izinler adresinde bulunabilir Manifest.permission
İzin Grupları
İzinler, bir cihazın yetenekleri veya özellikleriyle ilgili gruplar halinde düzenlenir. Bu sistem altında, izin talepleri grup düzeyinde ele alınmakta ve tek bir izin grubu, uygulama bildiriminde birkaç izin beyanına karşılık gelmektedir. Örneğin, SMS grubu hem bildirimleri hem READ_SMSde RECEIVE_SMSbildirimleri içerir. Bu şekilde gruplama izinleri, kullanıcının karmaşık ve teknik izin talepleri tarafından boğulmadan daha anlamlı ve bilinçli seçimler yapmasını sağlar.
Tehlikeli izinler kendi içerisinde gruplara ayrılmıştır. İzinler, dokuz gruba ayrılarak kullanıcıların bir grup halinde bir araya getirilerek tek bir işlemle kapsanan tüm izinleri vermelerini sağlar.
Örneğin, Bu, kullanıcının konumunu bulmak için GPS’i kullanmanız gerekirse, ACCESS_FINE_LOCATION ve ACCESS_COARSE_LOCATION gibi 2 adet izin belirtmeniz anlamına geliyordu ya da bir kullanıcıya Rehber’i görüntüleme, düzenleme ve ekleme izni vermek için 3 adet izin belirtmek gerekiyordu.
Bunun yerine izinleri tek tek almak yerine izin grubuna (Kişiler adı verilen) izin istemek daha etkilidir.
İzin Grupları Konum, Rehber, Telefon, Sensörler, SMS ve Depolama gibi benzer işlemleri gerçekleştiren izinleri basitleştirmeye çalışır. Bir uygulama grubu şu anda tek bir izin grubuna bir ila yedi izin arasında herhangi bir yerde bir araya geliyor. Bu, bir gruptaki tüm izinlerin tek seferde talep edebileceğiniz anlamına gelir!
Tüm tehlikeli Android izinleri izin gruplarına aittir. Herhangi bir izin, koruma seviyesinden bağımsız olarak bir izin grubuna ait olabilir. Bununla birlikte, bir izin grubu yalnızca izin tehlikeli olduğunda kullanıcı deneyimini etkiler.
Cihaz Android 6.0 kullanıyorsa (API seviye 23) ve uygulamanın targetSdkVersion23 veya daha üstü ise, uygulamanız tehlikeli bir izin istediğinde aşağıdaki sistem davranışı uygulanır:
Uygulamanın izin grubunda şu anda herhangi bir izni yoksa, sistem, uygulamanın erişmek istediği izin grubunu tanımlayan kullanıcıya izin isteği iletişim kutusunu gösterir. İletişim kutusu, o gruptaki belirli izni açıklamıyor. Örneğin, bir uygulama READ_CONTACTSizin isterse, sistem iletişim kutusu sadece uygulamanın cihazın bağlantılarına erişmesi gerektiğini söyler. Kullanıcı onay verirse, sistem uygulamaya sadece istediği izni verir.
Uygulamaya, aynı izin grubunda başka bir tehlikeli izin verilmişse, sistem kullanıcı ile herhangi bir etkileşime girmeden derhal izni verir. Örneğin, bir uygulamanın daha önce talep etmesi ve READ_CONTACTSizin verilmiş olması ve daha sonra talep WRITE_CONTACTSetmesi durumunda, sistem, izinler iletişim kutusunu kullanıcıya göstermeden hemen bu izni verir.
Cihaz Android 5.1 kullanıyorsa (API seviye 22) veya daha düşükse veya uygulama targetSdkVersion22 veya daha düşükse, sistem kullanıcıdan yükleme sırasında izinleri vermesini ister. Bir kez daha, sistem kullanıcıya bireysel izinleri değil, uygulamanın hangi izin grubunu gerektirdiğini söyler . Örneğin, bir uygulama READ_CONTACTSkurulum istediğinde , iletişim kutusu Rehber grubunu listeler. Kullanıcı kabul ettiğinde, uygulamaya yalnızca READ_CONTACTSizin verilir.
Not: Kullanıcı, aynı grupta başka bir izin vermiş olsa bile, uygulamanızın ihtiyacı olan her izni açıkça talep etmesi gerekir. Ek olarak, izinlerin gruplara ayrılması gelecekteki Android sürümlerinde değişebilir. Kodunuz, aynı grupta bulunan belirli bir izin grubuna bağlı bir mantığa sahip olmamalıdır.
Aygıttan mikrofon sesine erişimle ilgili izinler için kullanılır. Telefon görüşmelerinin de ses yakaladığını ancak ayrı (daha görünür) bir izin grubunda olduğunu unutmayın.
Manifest.permission.RECORD_AUDIO (Mikrofon ile kayıt)
Artık uygulamamızın yeni Çalışma Zamanı İznini mükemmel bir şekilde desteklemesinin zamanı geldi. Önce compileSdkVersion ve targetSdkVersion ayarlarını 23 yaparak başlayalım.
Dikkat:Manfest izni verilmezse uygulama kilitlenir.
İzinler, aşağıdaki tablo gibi İzin Grubunda gruplandırılmıştır .
Bir uygulamada tehlikeli kategorisindeki bir izne ihtiyaç varsa, bu izin kullanıcı tarafından daha önce onaylanmış bile olsa her seferinde uygulama tarafından kontrol edilmelidir. Çünkü kullanıcı verdiği izinden istediği an cayma hakkına sahiptir. Telefonun “Ayarlar – Uygulamalar – İlgili Uygulama – İzinler” kısmından bu işlemi yapabilir.
Android uygulamamız tehlikeli kategorisindeki bir izne ihtiyaç duyarsa, bu yetki için mutlaka kullanıcıya sorulması gerekir. Bir sonraki adım, izin verilip verilmediğini kontrol etmek için bir işlev oluşturmaktır.
//Öyleyse önce kullanıcıdan izin istemek için bir iletişim kutusu çağıralım. Sonra yeni bir kişi oluşturarak bir sonraki adıma geçebiliriz.
Not:Bir izin grubunda herhangi bir izin verilirse aynı gruptaki başka bir izin de otomatik olarak verilecektir.
Yani, bir kez WRITE_CONTACTS izni verildiyse READ_CONTACTS ve GET_ACCOUNTS izinleri de otomatik olarak verilir.
Uygulama tarafından izin kontrolü ContextCompat.checkSelfPermission(Context context, String permission)metodu ile yapılır.
Bu metotta kullanıcı
izin verdiğindePackageManager.PERMISSION_GRANTED döndürülürken,
izin vermediğinde ise PackageManager.PERMISSION_DENIED döndürülür.
private void izin_Kontrolet_Al() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
//Önceden izin VERİLMİŞ öyleyse Serbestçe istediğimizi yapalım.
yapilacaklar();
} else {
// Önceden izin verilmemiş öyleyse İZİN İSTEYELİM
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, ONAY_KODU);
}
return;
}
2. İzin önceden alınmadıysa izin isteyelim
requestPermissions(String [] izinler, int ONAY_KODU)
İzin alma işlemi için android sistemine ait standart bir dialog mevcuttur. Bu dialog requestPermissions() metodu ile çağrılır ve özelleştirilemez.
Activity izni almak için (Üstteki kodlara ekleme yapalım)
Daha önceden izin verilmişse, çalıştırılacak kodlar çağrılıyor, bu örnekte yapilacaklar() çağrılıyor.
İzin verilmediyse requestPermissions(context, new String [] {izinler}, int ONAY_KODU) ile izin istemek için aşağıdaki gibi bir iletişim kutusunu çağırılıyor.
final private int ONAY_KODU = 1234;
private void izin_Kontrolet_Al() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
//Önceden izin VERİLMİŞ öyleyse Serbestçe istediğimizi yapalım.
yapilacaklar();
} else {
// Önceden izin verilmemiş öyleyse İZİN İSTEYELİM
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, ONAY_KODU);
}
return;
}
İzin grubu simgesi
Uygulama ismi
“Bir daha asla sorma” onay kutusu (Bir kullanıcı iki kez izin vermezse bu görüntülenir)
Çoklu diyaloglar için gösterge
Aksiyon
3. İzin verilip verilmediğini kontrol edelim
İzin istedik ama izin verildi mi acaba? İşlem sonucunda izin verilip verilmediğini kontrol etmek için ise
onRequestPermissionsResult (int permsRequestCode, String [] izinleri, int [] grantResults)
Yukarıdaki kodda, istek kodunun izin talep ederken tarafımızdan gönderilen istek koduyla eşleşip eşleşmediğini kontrol ediyoruz. İstek kodu eşleşirse, kullanıcının izin verdiği veya reddedildiği izinleri kontrol ediyoruz. Kullanıcı izin verirse, CALL_PHONE başlatabiliriz, aksi takdirde kullanıcının izin vermesine izin verecek bir mesaj gösterebiliriz.
4. izin almadan önce neden izin istediğimizi izah edelim
Eğer kullanıcı izin için ilk kez çıkan dialog’a izin vermeyip, yeniden o özelliği kullanmaya çalışırsa, büyük ihtimalle o iznin ne için gerekli olduğunu anlamamıştır. Bu sebeple kullanıcıya standart izin dialog’u gösterilmeden önce, uygulamanın izne neden ihtiyacı olduğunu anlatan bir açıklama gösterilmelidir. Eğer kullanıcı açıklamaya ikna olup izin vermeyi kabul ederse, standart izin penceresine yeniden yönlendirilir.
Android sistemi, kullanıcıya bir açıklama göstermenin gerekli olup olmadığına karar vermemizi kolaylaştıran bir metod sunmuştur:
shouldShowRequestPermissionRationale() metodu
true dönerse, kullanıcıya daha önceden android standart dialog’u gösterilmiş ve kullanıcı izni onaylamamıştır. Bu sebeple true döndüğü durumlarda önce iznin ne için gerekli olduğunu anlatan bir açıklama gösterilmesi ve kullanıcı bu açıklamayı onaylarsa standart izin dialog’una yönlendirilmesi gerekir.
İzin kullanıcıdan ilk defa istenecekse ya da kullanıcı “Never ask again” durumu onaylanmışsa metod false döner.
requestPermissions çağrılmadan önce biz izni neden talep ettiğimizi shouldShowRequestPermissionRationale metodu ile kullanıcıya bir pencerede gerekçe göstermemiz gerekir.
private void izin_Kontrolet_Al() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CALL_PHONE);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
showMessageOKCancel("Çağrı için izin vermeniz gerekir", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[] {Manifest.permission.CALL_PHONE}, ONAY_KODU);
}
});
return;
}
requestPermissions(new String[] {Manifest.permission.CALL_PHONE}, ONAY_KODU);
return;
}
yapilacaklar();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(Eeeeeee.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
Birinci durumda açılan diyalog kutusunda neden izin istediğimizi açıklıyoruz.
İzine hayır derse pencere kapanıyor dolayısıyla “bir daha sorma” kutusunun işaretlenmesine engel olmuş oluyoruz. Uygulama tekrar açıldığında yine baştan alıyoruz. Bu yolla kullanıcının fikir değiştirmesinin önünü açmış oluyoruz. Diğer türlü “bir daha asla sorma” kutusunu işaretlerse kararından geri dönemeyeceği için ona bu yolla fikir değiştirme özgürlüğü vermiş oluyouruz.
İzine evet derse bu sefer 2.diyalog kutusunda izin talebinde bulunuyoruz..
İkinci durumda, herhangi bir izin verme diyalogu olmadan onRequestPermissionsResultçağrılacaktır PERMISSION_DENIED.
Buraya kadar olanlar kafa karıştırmaması için tek bir dosyada toplarsak;
package com.mobilprogramlar.ntzinal;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
public class Eeeeeee extends Activity {
final private int ONAY_KODU = 1234;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.eeeeee);
izin_Kontrolet_Al();
}
public void yapilacaklar() {
Toast.makeText(getApplicationContext(), "yapilacaklar şunlar", Toast.LENGTH_LONG).show();
}
private void izin_Kontrolet_Al() {
int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CALL_PHONE);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
if (!shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE)) {
showMessageOKCancel("Çağrı için izin vermeniz gerekir", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[] {Manifest.permission.CALL_PHONE}, ONAY_KODU);
}
});
return;
}
requestPermissions(new String[] {Manifest.permission.CALL_PHONE}, ONAY_KODU);
return;
}
yapilacaklar();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(Eeeeeee.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case ONAY_KODU: {
// CALL_PHONE izni verilip verilmediğini kontrol edin
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(Eeeeeee.this, "CALL_PHONE izni VERİLDİ", Toast.LENGTH_SHORT).show();
yapilacaklar();
} else {
Toast.makeText(Eeeeeee.this, "CALL_PHONE izni REDDEDİLDİ", Toast.LENGTH_SHORT).show();
}
break;
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Sonuç; önce isteyeceğimiz izin için bir pencere açarak sebebini anlatıyoruz. Tamam derse asıl izin penceresi çıkıyor ve izin talebinde bulunuyoruz.
Kullandığımız komutları özetlersek;
ContextCompat.checkSelfPermission () izni olup olmadığını kontrol etmek için verilir.
ActivityCompat.requestPermissions () izinleri istemek için. Birden fazla izin grubu ile birden fazla izin talep edilebilir.
ActivityCompat.shouldShowRequestPermissionRationale () , neden izin almak istediğine dair mantıklı bir mesaj göstermeye karar verdi.
onRequestPermissionsResult () , kullanıcının izin istemine verdiği yanıtı ele almak için.
Kesinlikle birden fazla izin gerektiren bazı özellikler var. Bir kerede yukarıdaki gibi aynı yöntemle birden fazla izin talep edebilirsiniz. Her neyse, her bir izin için de ‘Bir daha asla sorma’ durumunu kontrol etmeyi unutmayın.
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
private void insertDummyContactWrapper() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("GPS");
if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
permissionsNeeded.add("Kişileri Oku");
if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
permissionsNeeded.add("Kişileri Yaz");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "Erişim izni vermeniz gerekiyor " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
insertDummyContact();
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Gerekçe Seçeneğini Denetle
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
Her bir izin verilen hibe sonucunu aldığında, sonuç aynı geri çağırma yöntemine gönderilir onRequestPermissionsResult. Kaynak kodun daha temiz ve daha okunaklı görünmesi için HashMap kullanılabilir.
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
{
Map<String, Integer> perms = new HashMap<String, Integer>();
// ilk
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
// Sonuçları doldurun
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// ACCESS_FINE_LOCATION için kontrol et
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
// Tüm İzin Verildi
insertDummyContact();
} else {
// İzin reddedildi
Toast.makeText(MainActivity.this, "Bazı İzin Reddedildi", Toast.LENGTH_SHORT)
.show();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Kodların tamamın birarada;
package com.mobilprogramlar.uygulamazinleri2;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
private static final String TAG = "İletişim";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
insertDummyContactWrapper();
}
private void insertDummyContact() {
// Yeni bir temas kurmak için iki işlem gerekir.
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(2);
// İlk önce, yeni bir raw kişisi kur.
ContentProviderOperation.Builder op = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null);
operations.add(op.build());
// Ardından, kişinin adını ayarlayın.
op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
"__DUMMY CONTACT from runtime permissions sample");
operations.add(op.build());
// İşlemleri uygula.
ContentResolver resolver = getContentResolver();
try {
resolver.applyBatch(ContactsContract.AUTHORITY, operations);
} catch (RemoteException e) {
Log.d(TAG, "Yeni bir kişi eklenemedi: " + e.getMessage());
} catch (OperationApplicationException e) {
Log.d(TAG, "Yeni bir kişi eklenemedi\n: " + e.getMessage());
}
}
private void insertDummyContactWrapper() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("GPS");
if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
permissionsNeeded.add("Kişileri Oku");
if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
permissionsNeeded.add("Kişileri Yaz");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "Erişim izni vermeniz gerekiyor " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
insertDummyContact();
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Gerekçe Seçeneğini Denetle
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
{
Map<String, Integer> perms = new HashMap<String, Integer>();
// ilk
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
// Sonuçları doldurun
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// ACCESS_FINE_LOCATION için kontrol et
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
// Tüm İzin Verildi
insertDummyContact();
} else {
// İzin reddedildi
Toast.makeText(MainActivity.this, "Bazı İzinler Reddedildi\n", Toast.LENGTH_SHORT).show();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("Evet", okListener)
.setNegativeButton("Hayır", null)
.create()
.show();
}
}
Yukarıdaki kod Android 6.0 Marshmallow’da mükemmel çalışıyor olmasına rağmen. Maalesef Android’in Marshmallow öncesi Android’inde çökmesine neden olacak, çünkü bu işlevler API Seviye 23’e eklenmiş.
Düz yol, Sürüm Sürümü’nü aşağıdaki kodla kontrol edebilmenizdir.
Ancak kod daha da karmaşık olacak. Bu yüzden , bu şey için hazırlanmış olan Support Library v4’ten biraz yardım almanızı öneririm . Bu işlevleri şununla değiştirin:
if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED){
//CALL_PHONE özelliği için kullanıcı zaten daha önceden yetki vermiştir. Bu yetki ile yapılmak istenen burada yapılır.
}
else {
// İzin için kullanıcıya açıkça sorulmalıdır.
}
Bu fonksiyon Android MarshMallow öncesi çağrılırsa, her zaman false geri döner.
shouldShowRequestPermissionRationale()
Kullanıcıya daha önceden android standart dialog’u gösterilmiş ve kullanıcı izni onaylamamışsa true döner
HER ZAMAN Support Library v4 deki checkSelfPermission, requestPermissions ve shouldShowRequestPermissionRationale fonksiyonlarını kullanmaya çalışın.
Bu şekilde uygulamanız aynı kod mantığına sahip herhangi bir Android sürümünde mükemmel bir şekilde çalışacaktır. Lütfen bu fonksiyonların bazı ek parametreler gerektirdiğini unutmayın: Context ya da Activity gibi.. Yapacak özel bir şey yok, sadece istediğini doğru bir şekilde iletin. İşte kaynak kod:
private void insertDummyContactWrapper() {
int hasWriteContactsPermission = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_CONTACTS);
if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_CONTACTS)) {
showMessageOKCancel("Rehber’e erişime izin vermeniz gerekir", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_ASK_PERMISSIONS);
}
});
return;
}
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_ASK_PERMISSIONS);
return;
}
insertDummyContact();
}
Şu anda bu yeni izin sisteminin büyük resmini net bir şekilde gördüğünüze inanıyorum. Ve bunun ne kadar büyük bir sorun olduğunu da anladığınıza inanıyorum.
Ancak başka seçeneğiniz yok. Çalışma Zamanı İzni zaten Android Marshmallow’da kullanılıyor. Geri dönüşü olmayan noktadayız. Şu anda yapabileceğimiz tek şey, uygulamamızı bu yeni izin sistemini tam olarak desteklemektir.
İyi haber şu ki, Çalışma Zamanı İzni akışı gerektiren yalnızca birkaç izin var. Sık kullanılan izinlerin çoğu, örneğin, İNTERNET, Normal İzin’dedir , otomatik olarak verilir ve onlarla hiçbir şey yapmanıza gerek kalmaz. Sonuç olarak, değiştirmeniz gereken kodun sadece bir kısmı vardır.
CoordinatorLayout, Android Tasarım Destek Kütüphanesi ile tanıtılan yeni bir düzendir. CoordinatorLayout, süper güçlü bir FrameLayout’tur ( resmi belgelere göre ). Daha önce bir FrameLayout kullandıysanız, CoordinatorLayout’u kullanırken çok rahat olmalısınız. FrameLayout kullanmadıysanız, endişelenmeyin, oldukça kolay.
Varsayılan olarak, bir FrameLayout’a birden fazla çocuk eklerseniz birbirleriyle örtüşürler. Bir FrameLayout, en sık tek bir çocuk görüntüsü elde etmek için kullanılmalıdır. CoordinatorLayout’un ana çekiciliği, içerisindeki görüşlerin animasyonlarını ve geçişlerini koordine edebilmesidir. Yalnızca xml kullanarak, örneğin bir FAB’ın gelen bir Snackbar’ın dışına çıktığını, ya da görünüşe göre başka bir widget’a eklenmiş ve ekranda görünen bir FAB’ın (ya da gerçekten başka herhangi bir Görünümün) bulunduğu bir düzen tanımlayabilirsiniz. widget.
Bu makale için, CoordinatorLayout’u kullanmanın, görünümlerin diğer görünümlerin düzenindeki veya konumundaki değişikliklere yanıt vermesini sağlayarak kodunuzu basitleştirebileceği üç farklı yol göstereceğiz. Daha sonra, bu davranışın kodda nasıl elde edildiğini tartışacağız ve kendi özel davranışlarınızı görünümler arasında nasıl uygulayacağınızı öğrendiğiniz dördüncü bir yöntemi göstereceğiz. Özel davranışlar uygulayarak, yalnızca hayal gücünüzle (ve kodlama yeteneğinizle: D) sınırlandırılan kolayca birbirine bağlı inanılmaz animasyonlar, geçişler ve efektler oluşturabilirsiniz.
Uygulamanızda CoordinatorLayout’u kullanmadan önce, uygulamanızın aşağıdaki bağımlılığını ekleyerek Android Destek Tasarım Kitaplığını projenize içe aktarmanız gerekir.
İlk aktivite için, Snackbar görüntülendiğinde otomatik olarak kaybolan bir FAB ile düzen oluşturmak istiyoruz. Bu, CoordinatorLayout için bir “HelloWorld” programı ve iyi bir sebeple. İşlevsellik tamamen basit bir düzen olan xml dosyasında uygulanmıştır ve sadece çalışır.
Düzen oldukça basittir. CoordinatorLayout, kök düzendir. İçinde, ekran üzerinde ortalanmış bir düğmeye ve malzeme tasarım kurallarına uymamızı sağlamak için ekranın sağ alt köşesine yerleştirilmiş bir FAB’a sahibiz.
Activity sınıfına yaptığımız tek ekleme, Snackbar’ı göstermek için Düğmeye OnClickListener uygulamaktır. Snackbar’ın kök Görünümünü CoordinatorLayout olarak ayarladık. Bu şekilde, CoordinatorLayout Snackbar ve FAB hakkında bilgi sahibi olur ve her iki widget’in çakışmadığından emin olmak için geçiş animasyonu otomatik olarak yürütülür.
package com.mobilprogramlar.floatbutton1;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.snackbar.Snackbar;
public class MainActivity extends AppCompatActivity {
private Button mShowSnackbarButton;
private CoordinatorLayout mCoordinatorLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);
mShowSnackbarButton = (Button) findViewById(R.id.showSnackbarButton);
mShowSnackbarButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(mCoordinatorLayout,
"Bu basit bir Snackbar", Snackbar.LENGTH_LONG)
.setAction("KAPAT", new View.OnClickListener() {
@Override
public void onClick(View v) {
// Custom action
}
}).show();
}
});
}
}
Aktiviteyi yürütün ve FAB’nin, gösterildiğinde, snackbar için otomatik olarak yukarı ve dışarı kaydığını ve snackbar görünümden çıkarken konumuna aşağı doğru kaydığını gözlemleyin.
String.xml
<resources>
<string name="app_name">Float ve Snackbar</string>
<string name="show_snackbar">Snackbarı Göster</string>
</resources>
Malzeme Tasarımında tanıtılan yeni bir bileşen Floating Action Button (nedir).Sağ alt kısımdaki UI’nin üzerinde yüzen yüksek dairesel bir görünüştür. Genellikle, ekranın en önemli eylemini vurgulayan farklı görseliyle dikkat çeker.
Bu nispeten basit eğitimde Web de genelde Lolipop öncesi örnekler mevcut ama Google ın getirdiği Api 26 zorunluluğu ile artık bütün apk ların yenilenmesi gerekmekte.
Floating action buttons (Kayan eylem düğmeleri) FAB, tanıtılan bir eylem için kullanılır. UI’nin üzerinde yüzen daire içine alınmış bir simge ile ayırt edilirler ve değişim, başlatma ve aktarma çapa noktası içeren hareket davranışları vardır. – Materyal Tasarımı kaynağı
Gradle ayarlarını aşağıdaki altı çizili yerlerden belirtilen değerlere göre ayarlayalım.
Ayrıca alttaki 3 resim dosyasını da drawable klasörü altına ekliyoruz.
farklı telefon boyutları için bu resimlerin faklı ebatlarını yazının sonunda ki dosyanın tamamını indirebileceğiniz linki verdiğimde oradan indirebilirsiniz.
Sonuç;
Anlatılanların tamamının Android Studio daki kaynak kod ve reimleri aşağıdaki linkten indirebilirsiniz.
Android uygulaması geliştirmek için yegane ihtiyacınız olacak yazılım Android Studio. 2014 senesinden önce Android için yazılım geliştirme aracı olarak Eclipse IDE kullanılıyordu. 2014’ten sonra Android resmi uygulama geliştirme yazılımı olarak Android Studio yazılımını duyurdu ve artık uygulama geliştirmek için bu yazılımı kullanıyoruz. Android Studio bizi bir çok kurulum ve entegrasyon yükünden kurtarıyor ve tümleşik olarak Android SDK (Yazılım Geliştirme Aracı) yazılımını barındırıyor. Peki Windows işletim sisteminde Android Studio kurulumu nasıl yapılır?
Öncelikle sistem gereksinimleri:
Microsoft® Windows® 8/7/Vista (32 ya da 64-bit)
En az 2 GB RAM, 4 GB RAM tavsiye edilmektedir.
Android SDK, Sanal cihaz sistem görüntüleri ve ön bellekleme için en az 2 GB hard disk alanı.
1280 x 800 en az ekran çözünürlüğü
En az Java Development Kit (JDK) 7
Opsiyonel olarak sanal cihaz hızlandırma için: Intel® VT-x, Intel® EM64T (Intel® 64), ve Execute Disable (XD) Bit fonksiyonlarını destekleyen Intel® işlemci
Android Studio kurulumuna başlamadan önce bilgisayarınızda Java ve Java SE Development Kit yüklü olması gerekiyor. Çünkü Android Studio, Java tabanlı bir yazılım. Hoş, Android için uygulama geliştirirken kullanacağımız programlama dili de Java olduğu için Java bizim olmazsa olmazımız.
Java kurulum dosyaları için buradaki kullanabilirsiniz
İşlemcinizle uygun Java sürümlerini bilgisayarınıza yükledikten sonra kurulumlarını “İleri” diyerek yapın. Benim tavsiyem hem 32 bit hem 64 bit Java sürümlerini kurun. Daha sonra web tarayıcınız için gerekli olabilir. Java kurulumlarını gerçekleştirdikten sonra Android Studio yazılımını bilgisayarınıza indirin.
ANDROİD İŞLETİM SİSTEMİ NEDİR ?
Android Google gibi büyük bir şirketin ve Open Handset Alliance gibi uluslararası birliğin mobil cihazlar için geliştirilmekte olan Linux tabanlı özgür ve ücretsiz bir işletim sistemidir. Açık kaynak kodlu olmasına rağmen ufak fakat önemli bir bölümü Google tarafından engellenmiştir. Lakin Bu durum herhangi bir sorun teşkil etmiyor. Biz Android Studio da yaptığımız uygulamaları gerek kendi telefonumuzda çalıştırabilir veya Google Play’ de yayınlayabilirsiniz.
Bilindiği üzere Android Dünya’da en çok tercih edilen işletim sistemi olmuştur. Peki bu Android ‘i kullanan şirketler kimler? Samsung,Xiomia,Lenovo,HTC ,Sony, LG,Huawei gibi kaliteli ve büyük firmalar Android’ i tercih ediyor.
ANDROİD STUDİO NASIL KURULUR ?
Android Studio’ yu https://developer.android.com/studio/index.html; linkinden kendi işletim sisteminize göre indirebilirsiniz. Android Studio Java tabanlı olduğu için JDK(Java Development Kit) kurulu olması gerekiyor.Bunu Oracle’nin kendi sitesinde bulabilirsiniz. Dilerseniz şimdi kuruluma geçelim.
Android ilk çıktığı zamanlar Android Geliştiricileri olarak geliştirmeler eclipse ide ile yapmaktaydık. Eclipse’te genel olarak Java geliştirmek için kullanılan bir ide’dir. Eclipse’e android plugin kurup yapılıyordu geliştirmeler.
Ancak Google 16 Mayıs 2013 tarihinde yaptığı Google I/O etkinliğinde Android Studio‘yu tanıttı ve sitesi üzerinden dağıtımına başladı.
Eclipse ide’ye göre Android Geliştiricileri için çok daha fazla kolaylık sağladığı için Android Studio artık Android geliştiricileri arasında en çok kullanılan ide’dir.
Android Studio, Java tabanlı olduğundan biz kodumuzu derlerken arkaplanda çalışacak JDK ( Java Development Kit) i indirip yüklememiz gerekiyor. Bunu Oracle’nin kendi sitesinde bulabilirsiniz.
Yeşil renkli “Download Android Studio for Windows” düğmesine tıklıyoruz.
İlk önce Andoid Studio sitesinden program kurulumunu indirerek başlayalım. İşletim sistemi 64 bit olan ve Android Studio 64 bit sürümünü kurmak isteyenler için 2 seçenek mevcut. Sitedeki EXE versiyonu indirip klasik bir kurulum yapmak veya ZIP versiyonu indirip kuruluma gerek kalmadan istediğiniz bir klasöre dosyaları çıkartıp, bin klasörü altındaki studio64.exe ile direk kullanmak.
İndirirken dikkat etmemiz gereken 2 nokta kullandığımız işletim sitemi ve kaç bit olduğu.
Açılan sayfada en üstte üstteki görüntü çıkar, indireceğiniz işletim sistemi 64 değil 32 bit ise ya da windows değil başka bir işletim sistemi ise sayfanın en altındaki aşağıdaki görüntüden size en uygun olan android Studio sürümünü seçin.
İlk olarak bu adresten Android Studio’yu indirelim ve aşağıdaki gibi Download Android Studio butonuna tıklayalım.
Sonra lisans sözleşmesi karşımıza gelecek. Sözleşmeyi okuduktan sonra, kabul etmek için “I Agree” düğmesine basmamız gerekiyor.
Sözleşmeyi onayladıktan sonra indirme işlemi otomatik olarak başlayacak.
İndirme işlemi tamamlandıktan sonra dosyamıza çift tıklıyoruz.
UAC etkinse, Windows öncelikle bizden cihaz üzerinde kurulu yönetimsel izinleri isteyecek.
Yönetici izni verildikten sonra, Android Studio kurulumu için ilk adım görülecek.
Next düğmesine basarak kurulum işlemine başlıyoruz.
Next düğmesi sonrası karşımıza çıkacak ekranda yüklemek istediğimiz bileşenleri seçiyoruz ve tekrar Next düğmesine basıyoruz.
Sözleşmeyi onayladıktan sonra karşımıza Android Studio’nun ve SDK’nın nereye yükleneceğini soran bir pencere gelecek. Uygun yerleri belirttikten sonra tekrar “Next” düğmesine basıyoruz.
Eğer Intel Donanım Hızlandırıcı‘ya sahipseniz, Bir sonraki adımda ise karşımıza Android uygulamanız için kullanabileceğiniz emülatörün kurulum ayarlarının bulunduğu ekran çıkacak.
Buradan emülatörün kullanabileceği bellek miktarını ayarlayabilirsiniz.
Intel Donanım Hızlandırıcı desteği bulunmayan bilgisayarlarda, bu pencere görüntülenmeyip, doğrudan bir sonraki adıma geçilmektedir.
Android Studio’nun “Başlat” çubuğunda kısayol olarak gözükmesini istemiyorsak “Do not create shortcuts” seçeneğini işaretliyoruz ve “Install” düğmesine basıyoruz.
Ardından kurulum işlemimiz başlıyor.
Kurulum bittikten sonra “Next” düğmesine tıklıyoruz.
Çıkan pencereden “Finish” düğmesine tıklıyoruz ve kurulumu sonlandırıyoruz.
Artık Android Studio’yu kullanmak için hazırsınız.
Android Studio indikten sonra inen dosyayı çift tıklayarak açıyoruz.
Programı çalıştırırsanız şu hatayı alırsanız.
no jvm installation found. please install a 64-bit jdk veya no jvm installation found. please install a 32-bit jdk
java eksik ya da yanlış yüklenmiş demektir.
İşletim sistemi 64 bit ise yükleyeceğiniz programlar da 64 bit olması, 32 bit ise 32 bit olması gerekir.
Java’nın nasıl yüklendiğini bu adresten bakabilirsiniz.
Önceden Android Studio’nuz varsa onun ayarlarını import etmek isteyip istemediğinizi soruyor. Biz yeni kurulum yaptığımız için ikinci seçeneği seçerek (I do not …) devam ediyoruz. OK tıklayarak devam ediyoruz.
ok deyip devam ediyoruz.
Kurulum tipinin seçildiği ikinci ekranda Standart ve Custom seçenekleri yer almaktadır. Standart seçilerek devam edildiğinde varsayılan paket ve parametrelerle bir kurulum gerçekleştirmektedir.
Biz burada Custom seçeneğini işaretleyerek devam edeceğiz.
Sonrasında karşımıza SDK bileşenlerinin seçildiği ekran gelmektedir. Burada, yaptığımız uygulamayı test etmemizi sağlayan Android Virtual Device ve Performans için Intel HAXM isimli bir yazılım için kurulum seçenekleri bulunmaktadır.
HAXM, Android Virtual Device (AVD)’ın yavaşlığını gidermek ve olabildiğince hızlandırmak için kullanılan bir yazılımdır. Bununla ilgili detaylı bilgi edinmek isteyenler Internet üzerinden arama yapabilirler. Bu ekrandaki tüm seçenekleri işaretliyoruz ve Next butonuna basarak bir sonraki ekrana geçiyoruz.
Emulator ayarları sayfasında ise emulator ve HAXM uygulaması için bilgisayarınızdan ayırmak istediğiniz maksimum RAM bellek boyutunu girmeniz isteniyor. Ben önerilen ayarda (512 MB) bırakıp devam ediyorum.
Eğer çok fazla kaynağınız varsa buradaki bellek miktarını artırıp emulator performansını artırabilirsiniz.
Standart seçersek android studio için gerekli paket yazılımlar yüklenir, custom seçersek bizim belirlediğimiz paket yazılımlar yüklenir.
Sonradan tekrar tekrar indirmemek için biz standartı seçelim ve ileri diyelim.
Android Studio için 2 temadan birini seçip devam diyoruz. Daha sonra tekrar diğer temayı yükleyebilirsiniz.
Bu ekranda bize başlangıç için indireceği SDK ve Tool’ları gösteriyor. Bunlar ilk uygulamamızı yazmamız için gereklidir.
Finish’e tıklayarak Gerekli dosyaları indirmesini bekliyoruz.
Yüklenecek olan yazılımların toplam boyutu, bitir diyelim.
Gerekli dosyalar internetten indiriliyor.
Yukarıdaki ekranı gördüğümüz zaman anlıyoruz ki indirme işlemi bitmiş. Bundan sonra Finish’e tıklıyoruz ve işlemleri bitiriyoruz. Artık Android Studio kullanıma hazır.
SDK Kurulumu
Android Studio’yu kurarken zaten bize en son SDK’yı indirtiyor. Bu blog yazılırken SDK 29 u Android Studio’yu kurarken indirdim, fakat SDK 25 i indirerek sadece son sürüme yani Android 9.0 a uygulama yazabiliriz. Daha düşük sürümlere de uygulama yazabilmek için gerekli olan SDK’ları da indirmek gerekiyor.
Örneğin ben yazdığım uygulamanın Android 5.0(SDK 21) üzeri desteklemesini istiyorsam ve o aradaki (SDK 21 – SDK 29) cihazlarda da test edeceksem, o aradaki SDK’larıda indirmemiz gerekir.
SDK indirmek için Applications altındaki Android Studio ikonumuza tıklayarak açıyoruz Android Studio’yu.
Açılış ekranında sağ altta Configure ‘a tıklayarak açılan listeden SDK Manager’ı seçiyoruz.
SDK Manager da bize gerekli olan SDK’ları seçerek OK butonuna basıyoruz.
Seçtiklerimiz listelenir.
Bir sonraki ekranda Accept seçeneğini seçip Next’e tıklayarak indirme işlemini başlatıyoruz.
Seçtiğinia Sdk lara göre işlem biraz uzun sürecektir….
Bu işlemi de yaptıktan sonra artık bize lazım olan SDK‘larıda indirmiş olduk.
Artık Android Studio Kurulumu ‘nuda yaptığımıza göre geliştirmeye hazırız.