Zoom Program Ayarlarının Ayrıntılı Anlatımı

Bu başlıkta genel zoom ayarlarına göz atacağız. Aslında zoom için birçok farklı kategoride farklı ayarlar bulunuyor. Biz bunlara genel hatlarıyla ve en çok ihtiyacımız olanlar açısından yaklaşacağız. Zoom ayarları, mobil cihaz, bilgisayar ve web sayfasından yapılabilmektedir.

Mobil cihaz ve bilgisayar ayarları daha kısıtlı iken, zoom.us web sayfasında oturum açıp My Account ve ardından settings bölümüne girildiğinde yapılan ayarlar tüm platformları etkileyen daha kapsamlı ayarlardır. Bu bölümde her üç noktadaki ayarları da kısaca ele alacağız.

iOS Zoom ayarları

Zoom uygulamasını iOS cihazımızda açtığımızda Settings sekmesi en sağ alt köşede görülebilir. Burada sırasıyla kendi ad soyadımızın yazdığı ve tıkladığımızda profil ayarlarımızı yapıp oturum kapatabileceğimiz düğme, Meetings, Contacts, Chat, General, Siri Shortcuts, about öğeleri, yani toplantı, kişiler, sohbet, genel, siri kısa yolları ve hakkında öğeleri bulunur.

Profil Ayarları

Ayarların en başında kendi adımızın yazdığı bir düğme görürüz. Buraya girdiğimizde ilk Olarak Profile Photo   düğmesi karşımıza çıkar. Burada başkalarının profilimizde göreceği bir fotoğrafımızı seçebiliriz. İkinci ayar ise Display Name, yani insanların bizi görüntülediklerinde görecekleri isim alanı vardır. Eğer burada kendi adımız soyadımız yazmıyorsa düğmeye çift dokunup değiştirebiliriz. Yine bu ekranda eğer ücretli bir kullanıcıysak Kişisel toplantı numaramızı değiştirebiliriz. Ayrıca oturumu kapatmak için de bu alan kullanılır.

Toplantı Kategorisi Ayarları

iOS cihazları için bence en çok bilmemiz gereken kategori toplantı ayarları. Meetings, toplantı ayar kategorisindeki bazı temel ayarları şöyle sıralayabiliriz:

  • Auto Connect to Audio Otomatik Sesli Bağlanma: bildiğiniz gibi her Zoom odasına bağlantı kurduktan sonra bir de call using internet Audio düğmesine basmamız gerekiyordu. İşte bu düğmeye tıklayıp ayarı Use Internet, yani interneti kullan yaptığımızda, artık bir odaya bağlandığımızda tekrar Call using internet audio düğmesine basmamıza gerek kalmayacaktır. Var sayılan olarak bu düğme Off yani kapalı durumundadır. İlgili seçeneği seçtikten sonra Done yani bitti düğmesine basmalıyız.
  • Always Mute My Microphone Mikrofonu her zaman sessize al: Bu anahtarı da açık yapmanızı öneririm. Böylece bir odaya girdiğinizde var sayılan olarak sesiniz kapalı olacaktır. Dilerseniz iki parmakça çift dokunarak veya sol alt köşedeki düğmeyi kullanarak sesi açıp kapayabileceğimizi öğrenmiştik.
  • Always Turn of My Video Videomu Her Zaman Kapat: Bu ayar da adından anlaşılacaktır. Toplantıya katıldığınızda videonuzun otomatik olarak kapalı veya açık olmasını buradan ayarlayabilirsiniz.
  • Show Name When Participants Join, Katılımcılar katıldığında isimleri göster: Bilgisayarda olmayan fakat iOS cihazlarda olan çok pratik ve yararlı bir ayardır. Var sayılan olarak açık olan bu anahtarı kapattığımızda, Zoom toplantısındayken odaya girip çıkanları sürekli bize Voice Over okumayacaktır. Maalesef bilgisayarda bunu doğrudan açıp kapatabileceğimiz bir ayar bulunmuyor henüz.
  • Use Original Sound, Orijinal Sesleri Kullan: Bu ayar TeamTalk programından aşina olduğumuz yankı iptaliyle ilgilidir. Anahtar açık olursa, gürültü bastırma ve yankı iptali gibi özellikler de devre dışı bırakılmış olur.
  • Show My Connected Time, Bağlanma süremi Göster: Özellikle Zoomu ücretsiz olarak kullanıyorsak yönettiğimiz toplantının süresi 40 dakikadır. Bu anahtarı açtığımızda toplantı ekranında toplantıda ne kadar süredir bulunduğumuzu da görebiliriz.

Toplantı ayarlarında bunun dışında da ayarlar olmakla beraber, diğerlerinin işlevlerini keşfetmeyi sizlere bırakıyorum.

Sohbet Kategorisi Ayarları

Chat yani sohbet ayarlarında ise daha çok hangi sohbet mesajlarından gelen bildirimleri görmek istediğimiz gibi ayarlar bulunuyor. Receive Notifications For, bölümünde tüm mesajlar, sadece bize gönderilen mesajlar ve hiçbiri seçeneklerinden birini seçebiliriz.

Unread Messages başlığı altında ise okunmamış mesajların sohbet alanının en üstünde görünüp görünmemesi gibi birkaç anahtarı açıp kapatabiliriz.

Buradaki ilginç bir ayar dikkat çekici: Receive Notifications for Keywords: Bu ayarı açıp belirli anahtar sözcükler ekleyerek yalnızca bu anahtar sözcükler bir sohbet mesajında geçiyorsa bize bildirim gelmesini sağlayabiliriz.

When Viewing Unread Messages in a Channel, Bir kanaldaki okunmamış mesajları görüntülerken başlığında mesajların baştan sona doğru mu yoksa sondan başa doğrumu görüneceğini ayarlayabiliriz.

When to Notify Me, Bildirim alma zamanı başlığında ise bildirimleri sadece zoom ekranında mı yoksa başka bir ekrandayken de alıp almamayı seçebiliriz.

How to Notify Me, Bildirim alma şekli başlığında ise gelen bildirim uyarılarını ses veya titreşimle almayı seçebiliriz

Diğer Ayarlar

Bunun dışında General bölümünde Blur Snapshot On task Switcher, Uygulama değiştirici görüntüsünü bulanıklaştır ayarı, özellikle birden fazla uygulama açıksa oradaki gizli bilgilerin gizlenebilmesi açısından önemlidir.

Integrated Calling, bütünleşik arama ise, zoom aramalarının bir telefon araması gibi görünüp kilitli ekrandan da açılıp kapanmasına imkan verir.

Siri Kısa yolları bölümünde ise, dilerseniz yeni toplantı başlatma, bugünkü toplantılarınız görme gibi kısayolları Siri’ye ekleme ve kişiselleştirme şansınız bulunmakta.

iOS faslını kapamadan önce Settings sekmesindeki ayarların genel olarak tüm oturumları etkilediğini hatırlatalım. Daha önce bahsettiğimiz bir toplantıya özel ayarlar, yalnızca o toplantıyı ilgilendirecektir.

Bilgisayar Zoom Ayarları

İlk bakışta bilgisayardaki zoom ayarları mobil ayarlarına göre değişiklikler gösteriyor. iOS’dan farklı olarak bilgisayarda Meetings, toplantı ayarları yok. Bunu toplantı ekranlarına ve web sayfasına bırakmış gibi görünüyorlar. Buna karşın Video, Audio, Share Screen, Virtual Background,  Recording, Profile, Statistics, Feedback, Keyboard Shortcuts, Accessibility, yani video, ses, ekran paylaşımı, sanal arka planlar, kayıt, profil, istatistik, geri bildirim, klavye kısayolları ve erişilebilirlik gibi yeni ayar kategorilerine rastlıyoruz.

Bilgisayarda zoom ayarlarına ulaşmak için Zoom programını açıyoruz ve Home sekmesinin seçili olduğundan emin oluyoruz. Tab ile ilerlediğimizde Setting ayar düğmesine bastığımızda istediğimiz ekrana ulaşıyoruz. Bu ekranda ayar kategorileri alt alta sıralanmış. Aralarında aşağı yukarı yön tuşlarıyla dolaşıp birini seçmek için girişe basmamız gerekiyor.

General, Genel Ayarlar

Ayarların en başındaki bu bölmede şu kontrollere dikkat çekelim.

  • Start Zoom When I Start Windows, Windows’u başlattığımda Zoomu da başlat: çok açıklama gerektirmeyen kendini anlatan bir ayar. Windows ile  birlikte Zoom’un da başlaması noktasını ayarlayabiliyoruz.
  • When Closed, minimize window to the notification area instead of Taskbar, kapatıldığında pencereyi görev çubuğu yerine bildirim alanına küçült: Ekran okuyucularımızın ayarlarına benzer şekilde program penceresinin alt+tab ile dolaştığımız pencereler arasında değil de sistem tepsisinde görünmesini ayarladığımız bir onay kutusu.
  • Enter Full Screen Automatically when starting or joining a meeting, Bir toplantı başlatıldığı veya toplantıya katılındığında, otomatik olarak tam ekran moduna gir: Tam ekranın tam olarak bize ne sağladığı görsel bir nokta olmakla beraber, bunun otomatik olarak başlamasını buradan ayarlıyoruz.
  • Ask me to Confirm when I Leave a Meeting, Bir toplantıdan ayrılırken bana sor: Alt+Q ile toplantıdan ayrılmak istediğimizde Zoom bize var sayılan olarak bunu sorar. Sormamasını istersek bu onay kutusunun işaretini kaldırabiliriz.
  • Show my connected time, Bağlantı süremi göster: işaretlediğimizde toplantı ekranında tab ile gezerken o anki süremizi de görürüz. Eğer 40 dakikalık bir süremiz varsa, işaretli olmasını önerdiğim bir onay kutusu.
  • Diğer Genel ayarlar, ekran koruyucu devreye girdiğinde videonun ve sesin kapatılması, toplantılardan 5 dakika önce anımsatma gelmesi, ikili ekran kullanımı gibi ayarlardır ve en sonda View More Settings Open in Your Default Web Browser, Daha fazla ayarı gör varsayılan web tarayıcısını aç bağlantısıyla  karşılaşırız. Bu daha fazla ayara yazının en sonunda değineceğiz.

Video ve Ses Ayarları

Video ve Audio ses, iki ayrı kategori olarak zoom ayarlarında yerini almıştır, ancak işlevleri benzer. Videoda varsa birden fazla kamera içinde seçim yapmak, seste ise farklı ses giriş ve çıkışlarını seçmemiz mümkündür.

Video ayarlarında başlangıçta videomuzun açık olup olmaması, Galeri görünümünde 49 kişiye kadar kişiyi görebilme, kamerayı 90 derece döndürme, HD etkinleştirmesi, toplantıya katılırken Video Preview video ön izlemesinin görünüp görünmemesi gibi ayarları yapabiliyoruz.

Ses ayarlarında ise hoparlör ve mikrofon seçimi ve testlerini yapabiliyoruz. İlk olarak Speaker başlığı altında ses çıkış cihazımızı seçme, test etme, ses düzeyini ayarlama gibi bölümleri görebiliriz.

Microphone bölümünde ise mikrofonumuzu seçme, test etme veya ses düzeyini el ile ya da otomatik olarak ayarlama seçeneklerini bulabiliriz.

Ses bölümünde bunlara ek olarak şu ayarları da görme mümkün:

  • Automatically join audio by computer when joining a Meeting, Bir toplantıya katılırken otomatik olarak bilgisayar sesiyle katıl: Bilgisayardan zoom toplantılarına katılırken her seferinde Join Audio dememek için bu onay kutusunu işaretleyin.
  • Mute my microphone when joining a meeting, toplantıya katıldığımda mikrofon sesimi kapat: iOS ayarlarında da bulunan toplantıya girdiğimizde sessize kalmanızı düzenleyen bu onay kutusunu da işaretlemenizi öneriyorum.
  • Press and hold space key to temporarily Unmute yourself, Sesinizi geçici olarak açmak için boşluk tuşuna basılı tutun: Burada da Team Talk tarzı ekranlardaki bas konuş işlevini görüyoruz. Boşluk çubuğuna basarsak basılı tuttuğumuz müddetçe sesimiz açılır ve konuşabiliriz. Fakat ekran okuyucu kullanıyorsak, bu işlevi verimli kullanmak için tuş yinelemesini hiç biri yapmanızı öneririm. Ayrıca buradan hareketle şunu belirtelim. Zoom ekranlarında boşluk çubuğu yerine onay işlemlerinizi giriş tuşuna basarak yapmanız bu nedenle önemli.

Chat Sohbet Ayarları

Sohbet ayarları da aslında iOS ekranındaki ayarlara oldukça benzer özellikler taşıyor. Bazılarına göz atalım.

  • Change my status to away when I am inactive, Etkin değilken durumu uzakta olarak değiştir. Buranın bir tab altında bir yazma alanı da görürüz böylece kaç dakika sonra uzakta olarak görüneceğimizi seçebiliriz.
  • Keep Unread Messages on Top, Okunmamış mesajları en üstte tut.
  • Show unread message badge for channels, kanallarda okunmamış mesaj kümesi göster: Bu ayar okunmamış mesajların ayrı bir kümede gösterilmesini sağlar.
  • Move messages with new replies to the bottom of chat,  Yanıtlanan mesajları sohbetin en altına taşı: Bu da sohbet ekranlarını daha kolay yönetmek açısından yararlı olabilir.
  • When Viewing unread messages in a channel, okunmamış mesajları görme şekli: burada yön tuşlarıyla görebileceğimiz iki seçenek vardır. Start at the first unread seçildiğinde ilk okunmamış mesaj en başta görünür. Start at the latest seçilirse ise en son okunmamış mesaj en başta görünür.
  • Push notifications, burada hangi durumlarda bildirim alacağımızı seçiyoruz. All Messages, Private messages, none arasından seçim yaparak tüm sohbet mesajları, yalnızca bize gönderilenler veya hiçbirinde bildirim alma ya da almama durumunu seçebiliriz.
  • Diğer sohbet ayarlarında saat akşam 5, sabah 9 arasında rahatsız edilmeme, mesaj geldiğinde ses çalma, toplantılardayken sohbet bildirimleri alama gibi ayarlar yer alır.

Recording Kayıt ayarları

Kayıt ayarlarında bilgisayar kayıtlarımızın tutulacağı yeri değiştirebiliriz. Varsayılan olarak belgelerim içindeki zoom klasörüne atılır ve her kaydımız için o tarihe öze bir klasör oluşturulur. Bu klasör için kaydın hem ses dosyası hem de görüntü dosyası kaydedilir. Son sürümle birlikte sohbet mesajları da TXT olarak burada yer alır.

Choose a Location for the recorded files when the meeting ends onay kutusu işaretlenirse toplantı bitiminde kayıt dosyalarının konumunu seçmemiz istenecektir.

Record a separate audio file for each participant who speaks seçildiğinde, tek bir kayıt yerine konuşan her bir katılımcı için ayrı bir ses kayıt dosyası oluşturulur.

Kayıt ayarlarında ayrıca eğer hesabımız müsaade ediyorsa bulut ayarlarımızı da yönetmemiz mümkün. Bunun yanında video düzenleyiciler için kaydı optimize etmek, orijinal kayıt dosyalarını saklamak gibi seçenekleri de burada bulabiliriz.

Diğer Kategoriler

Zoomda detaylı değinmediğimiz erişilebilirlik, istatistik, geri bildirim, profil gibi kategoriler de yer alır. Erişilebilirlik kategorisi altyazıların ve sohbet mesajlarının boyutlarını ayarlamamızı sağlar. Profil ayarlarımızı web sayfası üzerinden değiştirmemiz istenmektedir. Feedback, geri bildirim bölümünde ise programa geri bildirim gönderebileceğimiz bir alan bulunmakta. Bu bölüme uygulamanın Türkçe dilinde de hizmet vermesi için şu adımları izleyebiliriz:

  1. Zoom programında Home sekmesinde olduğumuzdan emin olalım. Açılışta genellikle bu sekme aktiftir ama değilse tab ile ilerleyerek Home, Meetings, Chat, contacts sekmelerinin olduğu yerde sağ sol yön tuşuyla home üzerine gelelim.
  2. Tab ile ilerleyip Setting bölümünü bulalım ve giriş tuşuna basalım.
  3. Kategoriler arasında aşağı yukarı yön tuşlarımızla dolaşarak Feedback kategorisini bulup girişe basalım.
  4. Bir kez tab tuşuna basalım ve Geri bildirim yazma alanına gelelim.
  5. Buraya şuna benzer bir şey yazalım: Please Add Turkish Language to Zoom. Then, I can use it more comfortably. Best Wishes.
  6. Bir kez taba basalım ve Submit Feedback Send Feedback geri bildirim gönder düğmesine basalım. Hepsi bu. Çok daha fazla geri bildirim, çok daha fazla ses anlamına gelecektir.

Web Zoom Ayarları

Zoom aslında hem bilgisayar, hem mobil cihaz hem de web sayfası üzerinden yönetilebilen bir platform. Esas Zoom hesabımızı aldığımız web sayfası zoom.us adresi ve bu sayfaya girilip bir çok ayar yapılabilir. Burada yapılan ayarlar hem bilgisayar, hem mobil uygulamayı etkileyecektir. Zoom web sayfasındaki ayarlara gitmek için iki yolumuz var.

Birincisi bilgisayar Zoom uygulamasının Setting bölümü üzerinden. Burada Generel, genel kategorisi seçilir ve tab ile ilerleyerek View More Settings Open in Your Default Browser, Daha fazla ayar gör varsayılan web tarayıcınızda açılır düğmesine basılır.

İkinci yol ise şu adımlarla yapılabilir.

  1. https://zoom.us/ adresine girilir
  2. Bağlantı listesi yapılarak Sign In bağlantısı bulunur, içine girilir ve zoom kullanıcı adı ve şifresiyle oturum açılır.
  3. Burada yön tuşları veya Ctrl+F tuşlarına basılarak arama alanına Settings yazılır ve Settings menüsü bulunarak giriş tuşuna basılır.
  4. Eğer oturum zaten açıksa, web sayfasına girişin ardından önce My Accounts bağlantısına girilir sonrasında Settings bölümüne ulaşılır.

Settings yani ayarlar ana bölümünde 3 temel sekme bizi karşılar: Meeting, Recording, Telephone, yani toplantı, kayıt ve telefon sekmeleri. Burada en kritik ayarlar varsayılan olarak seçili gelen Meeting yani toplantı sekmesindedir. Ayarlar arasında gezinmek için H ve Shift+H tuşlarına basılabilir. Klavye üzerinden kullanım yapıyorsanız doğrudan 4’e basarak başlık seviyesi 4 içinde bulunan tüm ayarları görebilirsiniz. Başlıkla bir ayar üzerine geldikten sonra aşağı yön tuşuyla ilerlenerek ayar kontrolüne ulaşılır. Eğer bu kontrol seçiliyse ekran okuyucumuz “Basıldı” seçili değilse, “basılı değil” diyecektir. Ayarı değiştirmek için girişe basabiliriz.

Bazı ayarları değiştirdiğimizde, Zoom bizden doğrulama isteyebilir. Bu durumlarda ayarı açıyorsak Turn On,, kapatıyorsak Turn Of düğmesine basmalıyız. H ile ayarı bulduktan sonra aşağı yukarı yön tuşuyla ayarla ilgili diğer kontroller arasında gezmemiz gerekecektir. Bir tek basılı düğme değil, zaman zaman seçebileceğimiz çeşitli onay kutuları da bu bölümde yer alır.

Bu ayarları yönetme bilgisinden sonra gelin burada bizi ilgilendirebilecek bazı ayarlara bir göz atalım.

  • Require a Password: Toplantılar için şifre gerektirmesi 3 başlık altında ayrı ayrı ayarlanabilmektedir. When Scheduling new Meetings, Instant Meetings, Personal Meeting ID PMI. Yani toplantı planlarken, anlık toplantı başlatırken ve Kişisel Toplantı ID’si kullanırken. Her 3 durum için toplantılara katılımda şifre gerekip gerekmeyeceğini ayarlayabiliriz.
  • Autosaving chats: Bu anahtar açıldığında toplantıdaki yazışmalar otomatik olarak kaydedilir.
  • File Transfer: Bu anahtar açıldığında eğer zoom sürümümüz destekliyorsa zoom yazışma alanına dosya gönderebiliriz. Varsayılan olarak kapalı olan bu anahtarı ben açık hale getirdim. Ardından Zoom uygulamasında Alt+H ile açılan Chat bölümünde Shift+Tab ile ilerlerken File düğmesi belirir buna basıp bilgisayarımızdan bir dosya seçerek katılımcılara gönderebiliriz.
  • Co-host: Varsayılan olarak kapalı gelen ve açtığım bir anahtar da Eş yönetici anlamına gelen Co-host anahtarıdır. Bu anahtar açık hale getirildiğinde, Bir toplantı başlattığınızda dilediğiniz bir katılımcıya eş yöneticilik verebilirsiniz. Örneğin, öğretmensiniz ve bir sunum yaparken  parmak kaldıran, söz isteyen kişileri görmesi için bir öğrencinizi görevlendirmek istiyorsunuz. Bu durumda geçici olarak öğrencinize eş yöneticilik yetkisi vererek ders sürecinin yükünü paylaşabilirsiniz.
  • Breakout Room: Bir sınıfta öğrencilerinizi alt gruplara ayırıp bir grup çalışması yapmak istiyorsanız, bu anahtarı da açık hale getirin. Böylece toplantı ekranında bir toplantıyı küçük odalara bölüp katılımcıları buralara dağıtma şansınız olacak. Her ne kadar bu ayarı açık hale getirsem de, henüz erişilebilir ve pratik biçimde öğrencileri odalara gönderme işini yapamadığımı belirtmek isterim.
  • Show a “Join From Browser” Link: bu ayar kişilere zoom uygulamaları olmasa bile bir toplantıya doğrudan kendi web tarayıcıları üzerinden katılım imkanı sunan bir bağlantı da veriyor. Zoom bu şekilde katılımda bazı kısıtlar olduğunu söylüyor. Doğrudan test etmediğim bir ayar.
  • Allow Live Streaming Meetings: Bu anahtar açık hale getirildiğinde Zoom toplantılarının Facebook, Youtube gibi platformlardan canlı yayınlanmasının önü açılmış olur. Canlı yayın için lisanslı kullanıcı olmak gerekebilir. Bu anahtar açıldıktan sonra aşağı yön tuşuyla ilerlenerek Facebook, Youtube gibi onay kutularından dilenen işaretlenebilir. Ayarın açılması ardından bir toplantı başlatıldığında ekranda More Meeting Control adlı yeni bir bölüm belirecektir. Bu menü açıldığında toplantıyı odalara bölme ve canlı yayın başlatma gibi düğmeler burada görülür.
  • Toplantı sekmesinin altında bulunan Recording, kayıt sekmesinde ise Lokal ve bulut olarak kayda izin verilip verilmeyeceği, otomatik kayıt, bulut kayıtlarına kimlerin erişebileceği gibi ayarlar yapılabilir.

Zoom Toplantı Ayarları

Bilgisayar içinde yukarıda bahsettiğimiz üzere New Meeting Options içindeki Personal Meeting ID alt menüsünde bulunan PMI Settings içinden ulaşılan bazı ayarlar şunlardır:

  • Personal Meeting ID: Pro hesabınız varsa bu Numara değiştirilebilir.
  • Require Meeting Password: Bu alana toplantı odanız için şifre yazılıdır ve bunu değiştirebilirsiniz. Zoom 5 Nisan itibarıyla Oda şifresi koymayı zorunlu hale getirmiştir.
  • Video Host: Yönetici kişinin videosunun açık veya kapalı olacağını belirler.
  • Video Participants: katılımcıların videosunun açık veya kapalı olacağını belirler.
  • Liste kutusu: Burada Hangi ses kaynağıyla bağlantı kurulacağı belirlenir Bilgisayar Ses kartı, Telefon Ses kartı, üçüncü parti bir ses veya varsayılan şekilde gelen bilgisayar ve telefon bir arada seçenekleri vardır.
  • Dialing From: Zoomun çoğu kişi tarafından bilinmeyen bir özelliği de telefon kullanılarak da bağlantı kurulabilmesidir. Her ülke için tanımlı telefon numaraları vardır ve bu numara aranıp verilen Toplantı numarası ve şifresi girildikten sonra kareye basılarak toplantı odalarına bağlanılabilir. İşte burada davet mesajında gösterilecek ülkeler seçilebilir. Türkiye’de telefon kullanılan ülkeler arasındadır.
  • Advanced Meeting Options Gelişmiş Seçenekler açıldığında da şu öğeleri görürüz.
  • Enable Waiting Room: Bu onay kutusu işaretlenirse, Katılımcılar siz onları kabul edene kadar bir bekleme odasında bekletilir. Siz dilediğiniz katılımcıyı daha sonra odaya alabilirsiniz. Belirli grup çalışmaları yapılırken faydalı olabilir.
  • Enable Join Before Host: Bu da katılımcıların siz odaya gelmeden odaya girip giremeyeceklerini belirler. Eğer işareti kaldırırsanız katılımcılar sizden önce odaya giremez.
  • Mute Participants on Entry: Bu ayar oldukça önemlidir. İşaretlenirse Katılımcılar odaya geldiklerinde sesleri kapalıdır. Böylece ses açık yaşanan kazaların önüne geçilmiş olur. Katılımcıların kendi seslerini açıp açmama izni başka bir ayar yerinde olduğundan onu sonra anlatacağım.
  • Only Authenticated Users Can Join: Zoom içinde üye olmasanız bile size gönderilen bir davet bağlantısına tıklayıp zoom ile odalara girebilirsiniz. Ancak bu onay kutusu işaretlenirse Zoom üyesi olmayanlar odanıza giremez.
  • Automatically Record Meeting: Toplantı sahibi olarak isterseniz toplantınızı başladığınız an otomatik olarak kaydedebilirsiniz.

iOS cihazlarda benzer toplantı seçeneklerine ulaşmak için Meetings sekmesine girip Buradaki toplantı numaranızın yanında bulunan Edit düğmesine basmanız gerekir. Bilgisayara göre ayarlar daha kısıtlıdır. Buradaki ayarlar şunlardır.

Host Video ve participant video: Bu anahtarlar yönetici ve katılımcıların video durumlarını kontrol Eder.

Audio Option: Buraya girildiğinde hem telefonla aranacak ülke seçimi yapılabilir, hem de hangi ses sisteminin kullanılacağı seçilebilir. Bilgisayarla aynı şeyler bulunur.

Enable Waiting Room, Allow Join Before Host, Automatically Record Meeting anahtarları burada da vardır. Yani bekleme odası, yöneticiden önce toplantıya girme izni ve toplantının otomatik kaydedilmesi. iPhone ile toplantı ancak buluta kaydedilebilmektedir, bunun içinde pro hesabı gereklidir.

iOS cihazlardaki bilgisayarda göremediğim bir ayar ise Alternative Host düğmesidir. Zoom üyeliği olan birini toplantının alternatif yönetici olarak belirleyebilir ve siz yokken onun yönetici olmasını sağlayabilirsiniz.

Ayarlardaki son düğme ise Allow Join Meeting seçeneğidir ve var sayılan olarak Everyone yani herkes seçeneği işaretlidir. Yani buradan yalnızca zoom üyesi olanların da toplantıya katılmasını ayarlayabilirsiniz.

  • Görüşmeye başladıktan sonra sesinizin karşı tarafa gitmesini istemediğiniz durumlar için mikrofon işaretine yani “Mute” seçeneğine tıklayabilirsiniz. Sesi tekrar açmak istediğinizde de yine aynı yere tıklamanız gerekiyor. Birçok kullanıcı Zoom’da ses gelmiyor yönünde şikayette bulunuyor. Eğer ses ile ilgili sorun yaşıyorsanız mikrofon ikonu yanındaki ok işaretine tıkladığınızda açılacak olan pencereden “audio settings”i seçerek mikrofon ve hoparlör ayarlarınızı kontrol edebilirsiniz.
  • Zoom uygulaması kamera kapatma seçeneği de sunuyor. Ses gibi görüntünüzü de “Stop Video” seçeneği ile kapatıp sonrasında yeniden açabilirsiniz. Dilerseniz görüşme boyunca kameranızı kapalı tutabilirsiniz.
  • Bir toplantıya katılacaksınız ancak bulunduğunuz ortam dağınık ya da karşı taraftan görünmeye pek uygun değil. Bu durumda Zoom arka plan değişikliği seçeneğini kullanabilirsiniz. Sol alt köşede bulunan video ikonu yanındaki ok işaretine tıkladığınızda açılan pencereden “Choose Virtual Background” seçeneği ile arka plan için bir görsel seçebilirsiniz.
  • Zoom ekran paylaşımı yapmanıza da imkan tanıyor. “Share Screen” seçeneği ile toplantı sırasında kendi ekranınızda açacağınız dosyaları katılımcıların görmesini sağlayabilirsiniz.
  • Sesli dosyalarda sesin karşı tarafa ulaşması için “Share computer sound” ibaresini işaretlemeyi unutmayın.
  • Ekran paylaşımı yaparken beyaz tahta da kullanıp anlatmak istediklerinizi anlık yazılı olarak karşı tarafa iletebilirsiniz. Çeşitli işaretlerle özellikle belirtmek istediğiniz noktalara dikkat çekebilirsiniz. Zoom çoklu ekran deneyimi sayesinde ekranınızdaki bilgileri paylaşırken katılımcıları da karşınızda görmeye devam edersiniz.

Chat seçeneği ile tüm kullanıcılara ya da seçeceğiniz kullanıcıya yazılı mesajlarınızı anlık olarak iletebilirsiniz.


Ayrıntılı Toast Kullanımı

Toast Mesajı Nedir?

Toast, Android uygulamalarda kullanıcılara uyarı veya bilgilendirme mesajları verilmesini sağlayan, bunun dışında uygulama test aşamasında işlemlerin gerçekleşip gerçekleşmediği hakkında bilgi edinmek amaçlı kullanılan mesaj türüdür.

Ayrıca, hata ayıklama amacıyla da kullanabilirsiniz. Bir tost, küçük bir açılır pencerede bir işlem hakkında basit geri bildirim sağlar.

Toast Message, Javascript’deki alert, Form Application’lardaki msgbox yada messagebox gibi anlayabiliriz. Ekrana veri yazdırmak için kullanılıyor.

Nasıl Kullanılır?

Toast mesajları tasarlanarak kullanılacağı gibi default yani varsayılan şekilde de gösterilebilir. Bunu basit anlamda aşağıdaki kod bloğunu sınıf içine yazarak kullanabiliriz.

makeText methoduna baktığımızda üç parametre aldığını göreceksiniz.

İlki uygulama içeriğini yani contexti , Hangi activity bu işleme erişecek bilgisi gibi bilgileri tutar.

ikincisi kullanıcıya gösterilecek kısa mesajı, parametre olarak String veri bekler.

üçüncüsü de Toast mesajının ekranda gösterilme süresini belirtiyor.

Toast Message süre olarak iki integer değer alabilir;

  • Uzun toast message süresi –> Toast.LENGTH_LONG
  • Kısa toast message süresi –>  Toast.LENGTH_SHORT

show (): Bu yöntem, Tost’u ekranda görüntülemek  için kullanılır. Bu yöntem, Toast’un makeText () yöntemini kullanarak oluşturduğumuz metni görüntüler.

Toast toast = Toast.makeText(getApplicationContext(), "Mesajımız..", Toast.LENGTH_LONG);
toast.show();

veya

Toast toast = Toast.makeText(getApplicationContext(), "Mesajımız..", Toast.LENGTH_LONG)show();

şeklinde gösterilir.

Toast nesnesi ise, android.widget paketi içerisinde sınıf olarak bulunur.

Toast.makeText(this, "Mesajımız..", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(),"Mesajımız..",Toast.LENGTH_LONG).show();

Yukarıdaki şekilde kullanıldığında mesaj, kısa süreli ekranda görünür. Ama eğer uzun süreli görünmesini istiyorsak Toast.LENGTH_SHORT kısmını Toast.LENGTH_LONG şeklinde değiştirebiliriz.

this yerine bazen getApplicationContext() olarak da görebilirsiniz, her ikiside çalışır.

Yapmış olduğumuz çalışma test amaçlı ve kodların işleyişini değinmek amaçlı, onCreate metodu içinde çalıştırdık.

Toast nesnenizin yerini belirleme

Ekranın alt kısmında, yatay olarak ortalanmış standart bir kısa mesaj bildirimi görünür. Bu konumu setGravity(int, int, int) yöntemini kullanarak değiştirebilirsiniz. Bu yöntem üç parametreyi kabul eder: Bir Gravity sabiti, bir x konumu ofseti ve bir y konumu ofseti.

Örneğin, durum mesajının sol üst köşede görünmesi gerektiğine karar verirseniz yerçekimi (gravity) değerini şu şekilde ayarlayabilirsiniz:

    toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0); 

Toast toast = Toast.makeText(getApplicationContext(), "Mesajımız...", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();

Toast mesajımızın yerini belirlemek için aşağıdaki konum sabitlerini kullanabilirsiniz.

  • TOP
  • BOTTOM
  • LEFT
  • RIGHT
  • CENTER
  • CENTER_HORIZONTAL
  • CENTER_VERTICAL

Aşağıdaki kod parçasını incelediğimizde ekran görüntüsünde de gördüğünüz gibi Toast mesajını en altta sola dayalı olarak konumlandırdık.

Toast toast = Toast.makeText(getApplicationContext(), "Mesajımız...", Toast.LENGTH_LONG);
toast.setGravity(Gravity.BOTTOM|Gravity.LEFT, 0, 0);
toast.show();

Toast mesajının kısa süre boyunca gözükmesi için :

Toast.makeText(getApplicationContext(), "Mesajımız…", Toast.LENGTH_SHORT).show();

Toast mesajının uzun süre boyunca gözükmesi için:

Toast.makeText(getApplicationContext(), "Mesajımız…", Toast.LENGTH_LONG).show();

Diyelim ki varsayılan şekilde kullanmak istemiyoruz. Toast mesajlarının daha güzel, kendimize ait bir tasarımla görünmesini istiyoruz. 

İlk önce uygulamanın açılış ekranındaki tasarımı yapalım.

toast_1.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/custom_toast_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@android:drawable/ic_delete" />
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Toast YAZILI MESAJ"
            android:textColor="#FFF" />
</LinearLayout>

Java kodumuzda aşağıdadır. Yukarıda oluşturduğumuz görsel bileşeni, Toast mesajına setView yardımı ile verdik. Gördüğünüz gibi istediğimiz şekilde Toast mesajını oluşturmamız mümkün.

LayoutInflater inflater = getLayoutInflater();
                View layout = inflater.inflate(R.layout.toast_1,
                        (ViewGroup) findViewById(R.id.custom_toast_container));

                TextView text = layout.findViewById(R.id.text);
                text.setText("Bu bir Tost Mesajıdır ");
                Toast toast = new Toast(getApplicationContext());
                toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
                toast.setDuration(Toast.LENGTH_LONG);
                toast.setView(layout);
                toast.show();

Toast olarak sadece resim göstermek istersek

MainActivity.class

package com.ossmatematik.toastresimmesaji;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Button Btn1,Btn2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Btn1= findViewById(R.id.button1);
        Btn2= findViewById(R.id.button2);

        Btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                Toast.makeText(getApplicationContext(),"Bu bir Tost MEsajıdır",Toast.LENGTH_LONG).show();
            }
        });

        Btn2.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v)
              {
                  ImageView resim=new ImageView(getApplicationContext());
                  resim.setImageResource(R.drawable.reklam);
                  Toast toast=new Toast(getApplicationContext());
                  toast.setView(resim);
                  toast.setDuration(Toast.LENGTH_LONG);
                  toast.show();
              }
        });



    }
}

Toast Mesajının bizim istediğimiz kadar kalmasını istersek

    public void sureliTOAST(String msg, int millisec) {
        Handler handler = null;
        final Toast[] toast_sureli = new Toast[1];
        for(int i = 0; i < millisec; i+=2000) {
            toast_sureli[0] = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
            toast_sureli[0].show();
            if(handler == null) {
                handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        toast_sureli[0].cancel();
                    }
                }, millisec);
            }
        }
    }

Bütün kodları toparlarsak;

axtivity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.nuri.toastresimmesaji.MainActivity">
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="NORMAL TOAST MESAJI"
        android:textSize="30sp" />
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RESİMLİ TOAST"
        android:textSize="30sp" />
    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RESİM ve YAZILI TOAST"
        android:textSize="30sp" />
    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ZAMAN AYARLI TOAST(6 SANİYE)"
        android:textSize="30sp" />
</LinearLayout>

MainAcivity.java

package com.nuri.toastresimmesaji;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
    Button Btn1,Btn2,Btn3,Btn4;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Btn1= findViewById(R.id.button1);
        Btn2= findViewById(R.id.button2);
        Btn3= findViewById(R.id.button3);
        Btn4= findViewById(R.id.button4);

        Btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                Toast.makeText(getApplicationContext(),"Bu bir NORMAL Tost Mesajıdır",Toast.LENGTH_LONG).show();
            }
        });

        Btn2.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v)
              {
                  ImageView resim=new ImageView(getApplicationContext());
                  resim.setImageResource(R.drawable.reklam);
                  Toast toast=new Toast(getApplicationContext());
                  toast.setView(resim); //setView yani özel toast kullanımdan kaldırıldı. Bunun yerine SnackBar kullan
                  toast.setDuration(Toast.LENGTH_LONG);
                  toast.show();
              }
        });

        Btn3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                String Baslik = "DENEME";
                String mesajim = "Bu bir RESİMLİ Toast MESAJI";
                gosterTOAST(mesajim,Baslik);
            }
        });

        Btn4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                sureliTOAST("Bu bir Toast MESAJI",6000);
            }
        });
    }

    public void gosterTOAST(String Baslik, String msg)
    {
        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.toast_ekrani,
                (ViewGroup) findViewById(R.id.relativeLayout1));
        TextView baslikText = layout.findViewById(R.id.toast_baslik);
        TextView textMesaj = layout.findViewById(R.id.toast_mesaj);
        baslikText.setText(Baslik);
        textMesaj.setText(msg);
        Toast toast = new Toast(getApplicationContext());
        toast.setGravity(Gravity.BOTTOM, 0, 0);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setView(layout);  //setView yani özel toast kullanımdan kaldırıldı. Bunun yerine SnackBar kullan
        toast.show();
    }

    public void sureliTOAST(String msg, int millisec) {
        Handler handler = null;
        final Toast[] toast_sureli = new Toast[1];
        for(int i = 0; i < millisec; i+=2000) {
            toast_sureli[0] = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
            toast_sureli[0].show();
            if(handler == null) {
                handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        toast_sureli[0].cancel();
                    }
                }, millisec);
            }
        }
    }
}

toast_ekrani.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/relativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:gravity="center_horizontal">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_orange_dark"
        android:orientation="vertical"
        android:padding="5dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            tools:ignore="UseCompoundDrawables">

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="120dp"
                android:layout_height="60dp"
                android:layout_below="@+id/textView1"
                android:layout_margin="5dip"
                android:src="@drawable/toast_onemli_uyari"
                tools:ignore="ContentDescription,InefficientWeight,ObsoleteLayoutParam" />

            <TextView
                android:id="@+id/toast_baslik"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:padding="10dp"
                android:text=""
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@android:color/background_dark"
                android:textSize="18sp"
                tools:ignore="HardcodedText,InefficientWeight" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="10dp">

            <TextView
                android:id="@+id/toast_mesaj"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/imageView1"
                android:layout_weight="1"
                android:gravity="center"
                android:hint="Mesaj"
                android:textColor="@color/colorPrimary"
                android:textSize="14sp"
                tools:ignore="HardcodedText,InefficientWeight,ObsoleteLayoutParam" />
        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

Projenin tamamını

https://github.com/netmatematiknet/Toast

adresinden ücretsiz indirebilirsiniz.

Android Uygulama İzinleri için Geniş bir Araştırma

İ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 izinler vermenin 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 null dö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ı .

Normal ve tehlikeli izinlerin tam listesi Android Dokümantasyonunda bulunmaktadır .

Normal İzinler

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:

İşte bunların tam listesi:

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS 
android.permission.ACCESS_NETWORK_STATE 
android.permission.ACCESS_NOTIFICATION_POLICY 
android.permission.ACCESS_WIFI_STATE 
android.permission.ACCESS_WIMAX_STATE 
android.permission.BLUETOOTH 
android.permission.BLUETOOTH_ADMIN 
android.permission.BROADCAST_STICKY 
android.permission.CHANGE_NETWORK_STATE 
android.permission.CHANGE_WIFI_MULTICAST_STATE 
android.permission.CHANGE_WIFI_STATE 
android.permission.CHANGE_WIMAX_STATE 
android.permission.DISABLE_KEYGUARD 
android.permission.EXPAND_STATUS_BAR 
android.permission.FLASHLIGHT 
android.permission.GET_ACCOUNTS Instagram Hesabındaki Resim ve Videoları android.permission.FLASHLIGHT android.permission.GET_ACCOUNTS
android.permission.FLASHLIGHT
android.permission.INTERNET 
android.permission.KILL_BACKGROUND_PROCESSES 
android.permission.MODIFY_AUDIO_SETTINGS 
android.permission.NFC 
android.permission.READ_SYNC_SETTINGS 
android.permission.READ_SYNC_STATS 
android.permission.RECEIVE_BOOT_COMPLETED 
android.permission.REORDER_TASKS 
android.permission.REQUEST_INSTALL_PACKAGES 
android.permission.SET_TIME_ZONE 
android.permission.SET_WALLPAPER 
android.permission.SET_WALLPAPER_HINTS 
android.permission.SUBSCRIBED_FEEDS_READ 
android.permission.TRANSMIT_IR 
android.permission.USE_FINGERPRINT 
android.permission.VIBRATE 
android.permission.WAKE_LOCK 
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM 
com.android.launcher.permission.INSTALL_SHORTCUT 
com.android.launcher.permission.UNINSTALL_SHORTCUT

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.

Normal izinlerin TAM  listesi

 

İmza İzinleri

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

   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.

Tehlikeli izinlerin TAM  listesi

Özel İzinler

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.

Bu izinlerin nasıl isteneceği ile ilgili detaylar için bakınız SYSTEM_ALERT_WINDOWve WRITE_SETTINGSreferans girişleri.

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.

Tehlikeli izinler ve izin grupları.

İzin GrubuİzinlerAçıklamaAçıklama
CALENDAR(Takvim)Kullanıcının takvimi ile ilgili çalışma zamanı izinleri için kullanılır.

 

Manifest.permission.READ_CALENDAR (Takvim Etkinlikleri OKU)

Manifest.permission.WRITE_CALENDAR (Takvim Etkinlikleri YAZ)

android.permission-group.CALENDAR
CALL_LOG (Çağrı Geçmişi)İlişkili telefon özellikleri ile ilgili izinler için kullanılır.android.permission-group.CALL_LOG
CAMERA (Kamera)Kameraya erişmek veya cihazdan fotoğraf / video çekmekle ilgili izinler için kullanılır.

 

Manifest.permission.CAMERA (Kameraya Erişim)

android.permission-group.CAMERA
CONTACTS(İletişim)Bu cihazdaki kişiler ve profillerle ilgili çalışma zamanı izinleri için kullanılır.

 

Manifest.permission.READ_CONTACTS (Telefon Rehberini OKU)

Manifest.permission.WRITE_CONTACTS (Telefon Rehberine YAZ)

android.permission-group.CONTACTS
LOCATION (Yer)Cihaz konumuna erişime izin veren izinler için kullanılır.

 

Manifest.permission.ACCESS_FINE_LOCATION (Kesin Konum)

Manifest.permission.ACCESS_COARSE_LOCATION (Genel Konum)

android.permission-group.LOCATION
MICROPHONE(Mikrofon)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)

android.permission-group.MICROPHONE
PHONE(Telefonİlişkili telefon özellikleri ile ilgili izinler için kullanılır.

 

Manifest.permission.CALL_PHONE (Telefonla Arama)

android.permission-group.PHONE
SENSORS(Vücut Sensörleri)Gövde veya çevresel sensörlere erişim ile ilgili izinler için kullanılır.android.permission-group.SENSORS
SMS(SMS)Kullanıcının SMS mesajlarıyla ilgili çalışma zamanı izinleri için kullanılır.android.permission-group.SMS
STORAGE(Depolama)Paylaşılan harici depolama alanıyla ilgili çalışma zamanı izinleri için kullanılır.

 

Manifest.permission.READ_EXTERNAL_STORAGE (Sd veya Harici Diski OKU)

Manifest.permission.WRITE_EXTERNAL_STORAGE (Sd veya Harici Diske YAZ)

android.permission-group.STORAGE


Tehlikeli izinlerin TAM  listesi

Uygulama için İzin Alma

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.

android {
    compileSdkVersion 23
    ...

    defaultConfig {
        ...
        targetSdkVersion 23
        ...
    }

Sonraki adım, AndroidManifest.xml aynı eski yöntemle izin vermek

<uses-permission android:name="android.permission.WRITE_CONTACTS"/>

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.

(READ_CONTACTS ,   WRITE_CONTACTS ve GET_ACCOUNTS  aynı grupta olduğu için.) (ama AndroidManifest.xml dosyasında izin istemek zorundayız)

 1. Önce iznin verilip verilmediğini kontrol edelim

checkSelfPermission(Context context, String permission

Uygulama tarafından izin kontrolü ContextCompat.checkSelfPermission(Context context, String permission) metodu ile yapılır.

Bu metotta kullanıcı

izin verdiğinde PackageManager.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;
    }
  1. İzin grubu simgesi
  2. Uygulama ismi
  3. “Bir daha asla sorma” onay kutusu (Bir kullanıcı iki kez izin vermezse bu görüntülenir)
  4. Çoklu diyaloglar için gösterge
  5. 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

komutları kullanılır.

    @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.length > 0 && 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();
                }
                return;
            }
                default:
                    super.onRequestPermissionsResult(requestCode, permissions, 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.

ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CALL_LOG)

    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.

    Buraya kadar anlatılanların çalışır haldeki kodlarını buradan Github hesabından indirebilirsiniz.

Bir seferde birden fazla izin istemek

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.

Android.Manifest i unutmayalım;

    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

İşte revize edilmiş kod.

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();
    }


}

Sonuç;

Bu kısımda  anlatılanların çalışır haldeki kodlarını buradan Github hesabından indirebilirsiniz.

Android 6.0 Marshmallow Öncesi

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.

if (Build.VERSION.SDK_INT >= 23) {
            // Marshmallow+
        } else {
            // Pre-Marshmallow
        }

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

İzinleri kontrol et

ContextCompat.checkSelfPermission()

İzniniz olup olmadığını kontrol etmek için ContextCompat.checkSelfPermission()yöntemi kullanın.

Örneğin, bu pasaj, etkinliğin takvime yazma izni olup olmadığını kontrol etmeyi gösterir:

if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)!= PackageManager.PERMISSION_GRANTED) {
    // İzin verilmemiştir
}else {
    // İzin verilmiştir
}

Uygulama M üzerinde çalıştırılır veya çalıştırılmaz.

Bu metod kullanıcı izin verdiğinde PackageManager.PERMISSION_GRANTED dönerken,

izin vermediğinde ise PackageManager.PERMISSION_DENIED döner.

ActivityCompat.requestPermissions ()

ActivityCompat.requestPermissions ()

Bu fonksiyon M öncesi çağrılırsa, OnRequestPermissionsResultCallback, aniden doğru PERMISSION_GRANTED veya  PERMISSION_DENIED sonuç ile çağrılır  .

ActivityCompat.shouldShowRequestPermissionRationale ()

ActivityCompat.shouldShowRequestPermissionRationale ()

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

Floating Action Button Behavior

Floating Action Button Behavior

 

gradle a alttaki satır eklenmeli;

implementation 'com.getbase:floatingactionbutton:1.10.1'

tamamı

apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
    defaultConfig {
        applicationId "com.mobilprogramlar.floatingactionbuttonbehavior"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
    testİmplementation 'junit:junit:4.13-beta-3'
    androidTestİmplementation 'androidx.test:runner:1.3.0-alpha02'
    androidTestİmplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha02'
    implementation 'com.google.android.material:material:1.0.0'

    implementation 'com.getbase:floatingactionbutton:1.10.1'
}

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.getbase.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        app:fab_icon="@drawable/ic_done"
        app:layout_behavior="com.mobilprogramlar.floatingactionbuttonbehavior.FloatingActionButtonBehavior"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity ise

package com.mobilprogramlar.floatingactionbuttonbehavior;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import com.google.android.material.snackbar.Snackbar;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Merhaba Snackbar", Snackbar.LENGTH_LONG).show();
            }
        });
    }
}

 

FloatingActionButtonBehavior.class

package com.mobilprogramlar.floatingactionbuttonbehavior;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

public class FloatingActionButtonBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {

  public FloatingActionButtonBehavior(Context context, AttributeSet attrs) {
  }
  @Override
  public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
    return dependency instanceof Snackbar.SnackbarLayout;
  }
  @Override
  public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
    float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
    child.setTranslationY(translationY);
    return true;
  }
}

 

Son görünüm

 

Kodların tam çalışır halini Github hesabımdan indirebilirsinz.

 

CoordinatorLayout ile Float Button ve Snackbar

CoordinatorLayout ile Float ve Snackbar

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.

Module kısmında app ye ait  build.gradle

apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
    defaultConfig {
        applicationId "com.mobilprogramlar.floatbutton1"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    testİmplementation 'junit:junit:4.13-beta-3'
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'

}

 

Snackbar ve FAB

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

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.mobilprogramlar.floatbutton1.MainActivity">
    <Button
        android:id="@+id/showSnackbarButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@string/show_snackbar"/>
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:layout_marginEnd="@dimen/activity_horizontal_margin"
        android:src="@drawable/ic_done"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

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>

 

dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

 

Sonuç:

Kodların tam çalışır halini Github hesabımdan indirebilirsinz.