<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mehmet Kirazlı</title>
	<atom:link href="https://www.mehmetkirazli.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.mehmetkirazli.com/</link>
	<description>Yazılımcı Notları</description>
	<lastBuildDate>Sun, 17 May 2020 10:19:34 +0000</lastBuildDate>
	<language>tr</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.10</generator>

<image>
	<url>https://www.mehmetkirazli.com/wp-content/uploads/2018/04/mehmetkirazlilogo.png</url>
	<title>Mehmet Kirazlı</title>
	<link>https://www.mehmetkirazli.com/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Android Firebase Event (not set) Hatası Çözümü</title>
		<link>https://www.mehmetkirazli.com/android-firebase-event-not-set-hatasi-cozumu/</link>
					<comments>https://www.mehmetkirazli.com/android-firebase-event-not-set-hatasi-cozumu/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Wed, 04 Mar 2020 07:05:57 +0000</pubDate>
				<category><![CDATA[Hata Çözümleri]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3246</guid>

					<description><![CDATA[<p>Merhaba. Firebase Events&#8217;e istatistik attığınızda not set şeklinde bir değer görüyorsanız olası çözümünü göstereceğim. Kod tarafında istatistikleri eğer bir HashMap oluşturup daha sonra bunu Bundle kullanarak gönderdiğinizde bu hatayı alma olasılığınız çok yüksektir. Aşağıda örnek bir kodu göstereceğim. [crayon-69b267179527b718803649/] Eğer yukarıdaki gibi HashMap kullanıldığında, hashmap&#8217;in içindeki değerleri dönerken sorun olabiliyor. Bunun yerine doğrudan Bundle&#8217;a set &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-firebase-event-not-set-hatasi-cozumu/">Android Firebase Event (not set) Hatası Çözümü</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Firebase Events&#8217;e istatistik attığınızda <strong>not set</strong> şeklinde bir değer görüyorsanız olası çözümünü göstereceğim.</p>



<span id="more-3246"></span>



<figure class="wp-block-image"><img decoding="async" loading="lazy" width="474" height="352" src="https://www.mehmetkirazli.com/wp-content/uploads/2020/03/radyo-not-set.png" alt="" class="wp-image-3248" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2020/03/radyo-not-set.png 474w, https://www.mehmetkirazli.com/wp-content/uploads/2020/03/radyo-not-set-300x223.png 300w" sizes="(max-width: 474px) 100vw, 474px" /></figure>



<p></p>



<p>Kod tarafında istatistikleri eğer bir <strong>HashMap </strong>oluşturup daha sonra bunu Bundle kullanarak gönderdiğinizde bu hatayı alma olasılığınız çok yüksektir.</p>



<p>Aşağıda örnek bir kodu göstereceğim.</p>



<pre class="crayon-plain-tag">HashMap hashMap = new HashMap&amp;lt;String, String&gt;();
hashMap.put(&quot;Baslik&quot;, &quot;test&quot;);
UtilHelper.sendEventName(mContext, &quot;EventAdi&quot;, hashMap);</pre>



<p>Eğer yukarıdaki gibi <strong>HashMap </strong>kullanıldığında, hashmap&#8217;in içindeki değerleri dönerken sorun olabiliyor. Bunun yerine doğrudan <strong>Bundle&#8217;a </strong>set ettiğinizde bu hatadan kurtulmuş olursunuz.</p>



<p>Yani yazmanız gereken kod bloğu şu şekilde olmalıdır.</p>



<pre class="crayon-plain-tag">Bundle bundle = new Bundle();
bundle.putString(&quot;Baslik&quot;, &quot;test&quot;);
mFirebaseAnalytics.logEvent(&quot;EventAdi&quot;, bundle);</pre>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-firebase-event-not-set-hatasi-cozumu/">Android Firebase Event (not set) Hatası Çözümü</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/android-firebase-event-not-set-hatasi-cozumu/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Namaz Vakitleri Uygulaması Yayında</title>
		<link>https://www.mehmetkirazli.com/namaz-vakitleri-uygulamasi-yayinda/</link>
					<comments>https://www.mehmetkirazli.com/namaz-vakitleri-uygulamasi-yayinda/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Mon, 13 May 2019 08:23:15 +0000</pubDate>
				<category><![CDATA[Market Uygulamalarım]]></category>
		<category><![CDATA[android namaz vakti]]></category>
		<category><![CDATA[android uygulama]]></category>
		<category><![CDATA[ezan saati uygulaması]]></category>
		<category><![CDATA[ezan vakitleri]]></category>
		<category><![CDATA[imsakiye uygulaması]]></category>
		<category><![CDATA[namaz vakitleri]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3202</guid>

					<description><![CDATA[<p>Merhaba. Android cihazlar için hazırladığım Namaz Vakitleri uygulaması ile 200&#8217;e yakın ülkede tüm namaz-ezan vakitlerini görebilirsiniz. Uygulamada birçok özellik mevcuttur ve çok yakında kıble bulma, alarm ve hatırlatıcı kurma gibi özellikler eklenecektir. Siz de indirip yorumlarınızı yaparsanız memnun olurum. Diğer uygulamalarım için geliştirici sayfasına göz atabilirsiniz. Buradan İndirebilirsinizGeliştirici Sayfası Uygulama Ekran Görüntüleri Uygulama Özellikleri ★ &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/namaz-vakitleri-uygulamasi-yayinda/">Namaz Vakitleri Uygulaması Yayında</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Android cihazlar için hazırladığım Namaz Vakitleri uygulaması ile 200&#8217;e yakın ülkede tüm namaz-ezan vakitlerini görebilirsiniz.</p>



<span id="more-3202"></span>



<p>Uygulamada birçok özellik mevcuttur ve çok yakında kıble bulma, alarm ve hatırlatıcı kurma gibi özellikler eklenecektir.</p>



<p>Siz de indirip yorumlarınızı yaparsanız memnun olurum.</p>



<p>Diğer uygulamalarım için geliştirici sayfasına göz atabilirsiniz.</p>



<p class="has-text-color has-luminous-vivid-orange-color"><a href="https://play.google.com/store/apps/details?id=com.mehmetkirazli.namazvakti" target="_blank" rel="noreferrer noopener" aria-label=" (yeni sekmede açılır)">Buradan İndirebilirsiniz</a><br><a rel="noreferrer noopener" aria-label="Geliştirici Sayfası (yeni sekmede açılır)" href="https://play.google.com/store/apps/dev?id=5691695932588617971" target="_blank">Geliştirici Sayfası</a></p>



<h2> Uygulama Ekran Görüntüleri </h2>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123147.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123147-147x300.png" alt="" class="wp-image-3203" width="147" height="300" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123147-147x300.png 147w, https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123147.png 503w" sizes="(max-width: 147px) 100vw, 147px" /></a></figure>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123521.png"><img decoding="async" loading="lazy" width="147" height="300" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123521-147x300.png" alt="" class="wp-image-3207" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123521-147x300.png 147w, https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123521.png 503w" sizes="(max-width: 147px) 100vw, 147px" /></a></figure>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123448.png"><img decoding="async" loading="lazy" width="147" height="300" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123448-147x300.png" alt="" class="wp-image-3206" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123448-147x300.png 147w, https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123448.png 503w" sizes="(max-width: 147px) 100vw, 147px" /></a></figure>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123357.png"><img decoding="async" loading="lazy" width="147" height="300" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123357-147x300.png" alt="" class="wp-image-3205" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123357-147x300.png 147w, https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123357.png 503w" sizes="(max-width: 147px) 100vw, 147px" /></a></figure>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123644.png"><img decoding="async" loading="lazy" width="147" height="300" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123644-147x300.png" alt="" class="wp-image-3210" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123644-147x300.png 147w, https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123644.png 503w" sizes="(max-width: 147px) 100vw, 147px" /></a></figure>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123554.png"><img decoding="async" loading="lazy" width="147" height="300" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123554-147x300.png" alt="" class="wp-image-3208" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123554-147x300.png 147w, https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123554.png 503w" sizes="(max-width: 147px) 100vw, 147px" /></a></figure>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123615.png"><img decoding="async" loading="lazy" width="147" height="300" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123615-147x300.png" alt="" class="wp-image-3209" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123615-147x300.png 147w, https://www.mehmetkirazli.com/wp-content/uploads/2019/05/device-2019-05-07-123615.png 503w" sizes="(max-width: 147px) 100vw, 147px" /></a></figure>



<h2> Uygulama Özellikleri </h2>



<p> ★ Yaklaşık 200 Ülkenin Tüm Bölgelerinde Namaz Vakitlerine Erişebilirsiniz.<br>★ Geri Sayım Aracı ile En Yakın Namaz Vaktine Ne Kadar Kaldığını Görebilirsiniz.<br>★ Miladi ve Hicri Takvimi Görebilir, Ayın Gün İçindeki Konumuna Bakabilirsiniz.<br>★ Birden Fazla Lokasyon Ekleyebilir, Silebilir ve Birincil Lokasyon Olarak Belirleyebilirsiniz.<br>★ Namaz Vakitlerini Aylık Olarak Liste ve İmsakiye Formatında Görüntüleyebilirsiniz.<br>★ Önümüzdeki 4 Yılın Dini Günlerini Görebilirsiniz.<br>★ Vakitler 30 Günlük Alındığı İçin 30 Günde Bir Vakitleri Tekrar Almalısınız. Bunu Tek Bir Tıklama ile Yapabilirsiniz.<br>★ İnternetsiz Çalışabilme Özelliğine Sahiptir.</p>



<p><strong>İZİNLER</strong><br>Uygulamada şuan için herhangi bir izin istenmemektedir. Mümkün olduğunca işlemlerin izinsiz yapılması için gerekli geliştirmeler yapıldı.</p>



<p><strong>5 YILDIZ ★★★★★ VERMEYİ UNUTMAYIN</strong><br>Daha fazla kişiye ulaşabilmek ve destek olmanız amacıyla 5 yıldız vermeyi unutmayın.</p>



<p>Uygulamamızla ilgili istek, tavsiye ve şikayetlerinizi, uygulamadaki &#8220;Bize Yazın&#8221; butonu ile de bize iletebilirsiniz. Görüşlerinize göre uygulamada gerekli güncellemelerin yapılmasına özen gösterilecektir.

</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/namaz-vakitleri-uygulamasi-yayinda/">Namaz Vakitleri Uygulaması Yayında</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/namaz-vakitleri-uygulamasi-yayinda/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Kaza Namazı ve Oruç Takip Uygulaması</title>
		<link>https://www.mehmetkirazli.com/kaza-namazi-ve-oruc-takip-uygulamasi/</link>
					<comments>https://www.mehmetkirazli.com/kaza-namazi-ve-oruc-takip-uygulamasi/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Mon, 22 Apr 2019 06:33:44 +0000</pubDate>
				<category><![CDATA[Market Uygulamalarım]]></category>
		<category><![CDATA[kaza namazı]]></category>
		<category><![CDATA[kaza namazı hesaplama]]></category>
		<category><![CDATA[kaza namazı takip]]></category>
		<category><![CDATA[kaza namazı ve oruç takip uygulaması]]></category>
		<category><![CDATA[namaz borcu hesaplama]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3180</guid>

					<description><![CDATA[<p>Selamlar. İnsanlar için faydalı olması amacıyla geliştirdiğim Kaza Namazı ve Oruç Takip Uygulamasını sizlere tanıtmak istiyorum. Uygulamanın amacı, kaza namazı veya oruç borcu olanların bunları otomatik hesaplayıp takibini yapabilmesidir. Bu amaçla uygulamaya alarm özelliği, grafiksel bitiş durumu, soru&#38;cevap gibi özellikler eklenmiştir. Akıllı hesaplayıcı, vereceğiniz yanıtlara bağlı olarak kaza borçlarınızı hesaplar. Mümkün olduğunda yakın bir sayı &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/kaza-namazi-ve-oruc-takip-uygulamasi/">Kaza Namazı ve Oruç Takip Uygulaması</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Selamlar. İnsanlar için faydalı olması amacıyla geliştirdiğim Kaza Namazı ve Oruç Takip Uygulamasını sizlere tanıtmak istiyorum.</p>



<span id="more-3180"></span>



<p>Uygulamanın amacı, kaza namazı veya oruç borcu olanların bunları otomatik hesaplayıp takibini yapabilmesidir. Bu amaçla uygulamaya alarm özelliği, grafiksel bitiş durumu, soru&amp;cevap gibi özellikler eklenmiştir.</p>



<p>Akıllı hesaplayıcı, vereceğiniz yanıtlara bağlı olarak kaza borçlarınızı hesaplar. Mümkün olduğunda yakın bir sayı verebilmek amacıyla tüm ihtimaller göz önünde bulundurulmaya çalışılmıştır.</p>



<p>Siz de indirip yorumlarınızı yaparsanız memnun olurum.</p>



<p>Diğer uygulamalarım için geliştirici sayfasına göz atabilirsiniz.</p>



<p class="has-text-color has-luminous-vivid-orange-color"><a href="https://play.google.com/store/apps/details?id=com.mehmetkirazli.kazanamaziveoructakip" target="_blank" rel="noreferrer noopener" aria-label="Buradan İndirebilirsiniz (yeni sekmede açılır)">Buradan İndirebilirsiniz</a></p>



<p class="has-text-color has-luminous-vivid-orange-color"><a rel="noreferrer noopener" aria-label="Geliştirici Sayfası (yeni sekmede açılır)" href="https://play.google.com/store/apps/dev?id=5691695932588617971" target="_blank">Geliştirici Sayfası</a></p>



<h3>Uygulama Ekran Görüntüleri</h3>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/1.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/1-503x1024.png" alt="" class="wp-image-3181" width="252" height="512" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/1.png 503w, https://www.mehmetkirazli.com/wp-content/uploads/2019/04/1-147x300.png 147w" sizes="(max-width: 252px) 100vw, 252px" /></a><figcaption>kaza namazı</figcaption></figure>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/2.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/2-503x1024.png" alt="" class="wp-image-3182" width="252" height="512" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/2.png 503w, https://www.mehmetkirazli.com/wp-content/uploads/2019/04/2-147x300.png 147w" sizes="(max-width: 252px) 100vw, 252px" /></a></figure>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/3.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/3-503x1024.png" alt="" class="wp-image-3183" width="252" height="512" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/3.png 503w, https://www.mehmetkirazli.com/wp-content/uploads/2019/04/3-147x300.png 147w" sizes="(max-width: 252px) 100vw, 252px" /></a></figure>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/5.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/5-503x1024.png" alt="" class="wp-image-3185" width="252" height="512" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/5.png 503w, https://www.mehmetkirazli.com/wp-content/uploads/2019/04/5-147x300.png 147w" sizes="(max-width: 252px) 100vw, 252px" /></a></figure>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/7.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/7-503x1024.png" alt="" class="wp-image-3187" width="252" height="512" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/04/7.png 503w, https://www.mehmetkirazli.com/wp-content/uploads/2019/04/7-147x300.png 147w" sizes="(max-width: 252px) 100vw, 252px" /></a></figure>



<h3>Uygulama Özellikleri</h3>



<p>★ Otomatik Namaz Borcu Hesaplama<br>★ Kaza Namazı ve Oruçlarınızı Sizin Yerinize Hesaplar.<br>★ Kıldığınız Namazların Bitiş Durumunu Grafiksel Olarak Görebilirsiniz.<br>★ Kaza Namazı ve Oruçla Alakalı Soru&amp;Cevap Bölümünde, Sık Sorulan Soruları Görebilirsiniz.<br>★ Yedekleme Aracıyla Hem Cihazınıza Hem Google Drive Hesabınıza, Veritabanınızı Yedekleyebilir ve Daha Sonra Yükleyebilirsiniz. Bu Sayede Cihazınız Değiştiğinde Veri Kaybına Uğramazsınız.<br>★ Kaza Namazları Dışında Sık Kılınan Sünnet Namazları da Girebilir ve Takibini Yapabilirsiniz.<br>★ Kaza Oruçları Dışında Sünnet ve Nafile Olan Oruçları da Girebilirsiniz.<br>★ Kaza Namazlarınızın Ne Zaman Biteceğine Dair Size Tahmini Bir Tarih Verilir.<br>★ Kadın ve Erkek İçin Ayrı Ayrı Hesaplama Formülü Kullanılır.<br>★ Sizin İçin En Doğru Sayıyı Bulmak İçin Birçok Bilgi İster.<br>★ Kaza Namazlarının Nasıl Kılınacağı ve Kaza Orucunun Nasıl Tutulacağı Hakkında Bilgiler Verir.<br>★ İnternetsiz Çalışabilme Özelliğine Sahiptir. </p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/kaza-namazi-ve-oruc-takip-uygulamasi/">Kaza Namazı ve Oruç Takip Uygulaması</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/kaza-namazi-ve-oruc-takip-uygulamasi/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>Android Volley Kullanımı ve JSON Parse İşlemleri</title>
		<link>https://www.mehmetkirazli.com/android-volley-kullanimi-ve-json-parse-islemleri/</link>
					<comments>https://www.mehmetkirazli.com/android-volley-kullanimi-ve-json-parse-islemleri/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Wed, 06 Feb 2019 07:39:06 +0000</pubDate>
				<category><![CDATA[Kütüphaneler]]></category>
		<category><![CDATA[android volley]]></category>
		<category><![CDATA[android volley json parse]]></category>
		<category><![CDATA[android volley kullanımı]]></category>
		<category><![CDATA[volley example]]></category>
		<category><![CDATA[volley get post işlemleri]]></category>
		<category><![CDATA[volley kütüphanesi]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3153</guid>

					<description><![CDATA[<p>Volley, Android uygulamalarımızda kullandığımız AsyncTask&#8217;ın alternatifi olarak ortaya çıkarılan, Google I/O 2013 sunumunda duyurulan bir Network(Http) kütüphanesidir. Volley kütüphanesi, hazırladığınız bir REST servisi ya da JSON dosyası varsa, servis URL&#8217;ine bağlanıp sonucu size daha hızlı bir şekilde döndürür. AsyncTask kullananlar bilir. doInBackground() metodunda ekran işlemleri yapılmazdı ve tasklar bazen diğerinden önce çalışırdı. Activity bittikten sonra &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-volley-kullanimi-ve-json-parse-islemleri/">Android Volley Kullanımı ve JSON Parse İşlemleri</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Volley, Android uygulamalarımızda kullandığımız AsyncTask&#8217;ın alternatifi olarak ortaya çıkarılan, Google I/O 2013 sunumunda duyurulan bir Network(Http) kütüphanesidir.</p>



<span id="more-3153"></span>



<p>Volley kütüphanesi, hazırladığınız bir REST servisi ya da JSON dosyası varsa, servis URL&#8217;ine bağlanıp sonucu size daha hızlı bir şekilde döndürür. <strong>AsyncTask </strong>kullananlar bilir. <strong>doInBackground() </strong>metodunda ekran işlemleri yapılmazdı ve tasklar bazen diğerinden önce çalışırdı. Activity bittikten sonra AsyncTask kapatılırsa hata alınırdı. Volley ile bu sorunlar ortadan kalkmış oldu. Tüm işlemler asenkron olarak yapıldığı için zaten bu işi yapan AsyncTask&#8217;lara da gerek kalmadı.</p>



<p class="has-text-color has-vivid-red-color">Volley kütüphanesi, performansı arttırmak için en önemli işlev olarak <strong>önbellekleme </strong>özelliğini kullanır. Eğer bilgi Cache&#8217;de varsa doğrudan sonuç gösterilir. Yoksa yeni bir istek oluşturulur.</p>



<p class="has-medium-font-size"><strong>Volley kütüphanesinin avantajları :</strong></p>



<ul><li>Ağ isteklerinin zamanlamasını otomatik olarak yapar.</li><li>Cache yapısı olduğundan hızlı işlem yapar. Özellikle resim indirme ve gösterme işlemlerinde disk ya da bellekte cache&#8217;leme yapılır.</li><li>Eş zamanlı olarak çoklu bağlantıya izin verir.</li><li>İstekleri asenkron olarak işleyebildiği için AsyncTask&#8217;taki sorunlar görülmez.</li><li> AsyncTask&#8217;taki gibi karışık ve zorlu kontrollere gerek yoktur.</li><li>JSON ve resim işlemlerinde güçlü desteği mevcuttur.</li><li> Yapılan bir istek, istenildiğinde iptal edilebilir. İşi biten istekler otomatik olarak iptal edilir. </li><li>Büyük boyuttaki veri çekme işlemleri için uygun değildir. Cache sistemi yüksek boyutta veri tutmaya yetmeyecektir.</li></ul>



<p class="has-medium-font-size"><strong>RequestQueue Sınıfı</strong></p>



<p>Volley bünyesindeki <strong>RequestQueue </strong>sınıfı, önbelleğe yazma ve önbellekten okuma işlemlerini, istekleri sıraya koyma ve istek sonuçlarını dönme gibi işlemleri yapar. Her ağ isteğinden önce, bu sınıftan bir nesne oluşturulması ve daha sonrasında istenilen bağlantının sağlanması gerekir. Yapılan her isteğin, istekten sonra bu nesneye <strong>add()</strong> ile eklenmesi gerekir. Böylece istek kuyruğuna isteği eklemiş oluruz ve bu sınıf bizim için kuyruktaki isteklerin yönetimini ve cache&#8217;lemelerini yapar. AsyncTask&#8217;a göre en önemli avantajı budur.</p>



<p class="has-text-color has-vivid-red-color">Her activity için <strong>RequestQueue </strong>sınıfından nesne oluşturmak yerine, tüm uygulama boyunca tek bir <strong>Singleton </strong>nesne oluşturup, onun üzerinden kuyruğa ekleme ve çıkarma işlemleri yapılması <strong>Google </strong>tarafından öneriliyor. Biz uygulamalarımızda Singleton nesne kullanacağız fakat manuel olarak RequestQueue nesnesi oluşturmayı da bilelim. Konunun sonunda <strong>UYARI </strong>başlığı altında bunun detayları anlatılacaktır.</p>



<p style="font-size:32px"><strong>Yeni Proje Oluşturma</strong></p>



<p><strong>Volley </strong>hakkında bilgi verdikten sonra ufaktan proje oluşturalım ve Volley kullanımını görelim. </p>



<p>Proje oluşturduktan sonra ilk olarak <strong>build.gradle</strong> dosyasında <strong>Volley </strong>kütüphanesini tanıtıyoruz. Kütüphane ilk çıktığında <strong>jar </strong>oluşturma işlemini manuel olarak yapıyorduk. Sağolsun <strong>maven </strong>imdadımıza yetişti.</p>



<pre class="crayon-plain-tag">dependencies {
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.volley:volley:1.1.0' // volley için bu satır eklenmeli
}</pre>



<p><strong>build.gradle</strong> dosyasının tamamı ise şu şekilde olacaktır.</p>



<pre class="crayon-plain-tag">apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.mehmetkirazli.volleykullanimi"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.volley:volley:1.1.0' // volley için bu satır eklenmeli
}</pre>



<p>Şimdi ise<strong> AppController</strong> sınıfını ekleyelim. Bu sınıf, tüm uygulama boyunca isteklerin takibini ve <strong>asenkron </strong>çalışmasını sağlar.</p>



<p><strong>Activity </strong>tabanlı değil de <strong>Application </strong>tabanlı bu sınıfı kullanmak, uygulamanın yaşam döngüsü boyunca yönetimin tek bir sınıftan ve tek bir <strong>RequestQueue </strong>nesnesi üzerinden olması amacıyla daha avantajlıdır. Bu şekilde sınıfı yazıp <strong>Manifest </strong>içinden de tanımını yapacağız.</p>



<p><strong>AsyncTask </strong>kullanırken <strong>cihaz döndürüldüğünde,&nbsp;</strong>Activity tekrar çalıştığı için <strong>AsyncTask </strong>da tekrar başlatılıyordu. Volley&#8217;de ise <strong>Application </strong>sınıfından türetilen <strong>AppController</strong> sınıfı üzerinden, yaşam döngüsü boyunca kuyruğa ekleme çıkarma işlemleri yapılır. Konu başında bundan bahsetmiştik.</p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.volleykullanimi;

import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class AppController extends Application {

    public static final String TAG = AppController.class.getSimpleName();
    private RequestQueue mRequestQueue;
    private static AppController mInstance;
    private ImageLoader mImageLoader;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized AppController getInstance() {
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
        return mRequestQueue;
    }

    // kuyruya istek eklemek için kullanılır (istek adıyla beraber)
    public &lt;T> void addToRequestQueue(Request&lt;T> request, String tag) {
        request.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(request);
    }

    // kuyruya istek eklemek için kullanılır (istek adı olmadan)
    public &lt;T> void addToRequestQueue(Request&lt;T> request) {
        request.setTag(TAG);
        getRequestQueue().add(request);
    }

    // resimleri yükleme ve cache işlemleri için çağrılır
    public ImageLoader getImageLoader() {
        getRequestQueue();
        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(this.mRequestQueue,
                    new BitMapCache());
        }
        return this.mImageLoader;
    }

    // volley isteğini iptal etmek için çağrılır
    public void cancelPendingRequests(Object obj) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(obj);
        }
    }
}</pre>



<p><strong>AppController </strong>sınıfı, <strong>Application </strong>sınıfından türetilir. Konunun sonunda resim indirme işlemi de yapacağımız için <strong>getImageLoader() </strong>metodunu da ekledik. Siz kullanmayacaksanız kaldırabilirsiniz.</p>



<p>Resim işlemleri için Cache&#8217;leme görevini yapacak olan <strong>BitMapCache </strong>sınıfımızı da ekleyelim. <strong>getImageLoader()&nbsp;</strong>metodunda bu sınıfı kullanıyoruz.</p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.volleykullanimi;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import com.android.volley.toolbox.ImageLoader;

public class BitMapCache extends LruCache&lt;String, Bitmap> implements ImageLoader.ImageCache {
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    public BitMapCache() {
        this(getDefaultLruCacheSize());
    }

    public BitMapCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}</pre>



<p>Daha sonra <strong>AndroidManifest.xml</strong> dosyasında <strong>İnternet </strong>izni ekliyoruz. Uygulamada kullanacağımız 3 adet aktiviteyi tanımlıyoruz. Son olarak da <strong>application </strong>tag&#8217;inde <strong>name </strong>kısmında <strong>AppController</strong>&#8216;i tanımlıyoruz.</p>



<p class="has-text-color has-vivid-red-color">AppController kullanmayıp her istek için RequestQueue kullansaydık bu name tanımını yapmayacaktık.</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mehmetkirazli.volleykullanimi">

    &lt;uses-permission android:name="android.permission.INTERNET" />

    &lt;application
        android:name="com.mehmetkirazli.volleykullanimi.AppController"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        &lt;activity android:name=".ActivityMain">
            &lt;intent-filter>
                &lt;action android:name="android.intent.action.MAIN" />
                &lt;category android:name="android.intent.category.LAUNCHER" />
            &lt;/intent-filter>
        &lt;/activity>

        &lt;activity android:name=".ActivityMarkalar"/>
        &lt;activity android:name=".ActivityKullanicilar"/>
        &lt;activity android:name=".ActivityResimler"/>
    &lt;/application>

&lt;/manifest></pre>



<p style="font-size:32px"><br><strong>Giriş Ekranı</strong></p>



<p><strong>activity_main.xml</strong> dosyasına 3 adet buton ekleyelim. 1.sinde basit olarak <strong>JSON </strong>dosyasını okuyup listeye basalım. 2.sinde biraz daha karışık olan <strong>JSON </strong>dosyasını <strong>parse </strong>edip sonuçları bir listede gösterelim. Son butonda da <strong>Volley </strong>ile çekilen resimleri <strong>ImageView </strong>üzerinde gösterelim. </p>



<p>Bu işlemler yeni Activity üzerinde yapılacak o yüzden her bir buton için yeni bir Activity oluşturacağız ve her tıklamada yeni Activity açacağız.</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    &lt;Button
        android:id="@+id/btnMarka"
        android:layout_width="183dp"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="180dp"
        android:text="Markaları Göster" />
    
    &lt;Button
        android:id="@+id/btnKullanici"
        android:layout_width="183dp"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="230dp"
        android:text="Kullanıcıları Göster" />

    &lt;Button
        android:id="@+id/btnResim"
        android:layout_width="183dp"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="280dp"
        android:text="Resimleri Göster" />

&lt;/RelativeLayout></pre>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volleykullanimi1.png"><img decoding="async" loading="lazy" width="419" height="731" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volleykullanimi1.png" alt="" class="wp-image-3154" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volleykullanimi1.png 419w, https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volleykullanimi1-172x300.png 172w" sizes="(max-width: 419px) 100vw, 419px" /></a></figure>



<p>Bu ekrana bağlı olan <strong>ActivityMain.java</strong> sınıfımız ise şu şekilde olacaktır.</p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.volleykullanimi;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class ActivityMain extends AppCompatActivity {
    Button btnKullanici, btnMarka, btnResim;

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

        btnKullanici = (Button) findViewById(R.id.btnKullanici);
        btnMarka = (Button) findViewById(R.id.btnMarka);
        btnResim = (Button) findViewById(R.id.btnResim);

        btnMarka.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(getApplicationContext(), ActivityMarkalar.class));
            }
        });

        btnKullanici.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(getApplicationContext(), ActivityKullanicilar.class));
            }
        });

        btnResim.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(getApplicationContext(), ActivityResimler.class));
            }
        });
    }
}</pre>



<p style="font-size:32px"><br><strong>Markalar Ekranı</strong></p>



<p>Buraya kadar <strong>Volley </strong>kullanarak bir <strong>Http </strong>isteği yapmadık. Bundan sonra istek gönderme işlemlerine başlıyoruz. İlk olarak elimizde markaları gösteren bir <strong>JSON </strong>dosyası olsun ve bu dosyayı çağırarak dönen sonucu bir listede gösterelim.</p>



<p>Önce <strong>markalar.json</strong> dosyasının içeriğini verelim sonra bunu <strong>Volley </strong>ile çağırıp dönen sonuçları <strong>Parse </strong>ederek gösterelim.</p>



<pre class="crayon-plain-tag">{
"markalar":[
    "Alfa Romeo",
    "Bmw",
    "Dacia",
    "Fiat",
    "Ford",
    "Honda",
    "Hyundai",
    "Jaguar",
    "Lada",
    "Mazda",
    "Mercedes",
    "Nissan",
    "Opel",
    "Peugeot",
    "Renault",
    "Seat",
    "Skoda",
    "Subaru",
    "Suzuki",
    "Tofaş",
    "Toyota",
    "Volkswagen",
    "Volvo"
    ]
}</pre>



<p>Şimdi <strong>ActivityMarkalar</strong> sınıfını kodlamaya başlayalım.</p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.volleykullanimi;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class ActivityMarkalar extends AppCompatActivity {
    ListView listViewMarka;
    ProgressDialog dialog;
    String urlMarkalar = "https://www.mehmetkirazli.com/Dosya/markalar.json";

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

        listViewMarka = (ListView) findViewById(R.id.lwMarka);

        // istek bitene kadar dialog gösterilir. istek sonuçlanınca dialog kapatılacak
        dialog = new ProgressDialog(this);
        dialog.setMessage("Veriler Okunuyor...");
        dialog.setCancelable(false);
        dialog.show();

         /* StringRequest yerine JsonObjectRequest veya JsonArrayRequest de kullanılabilir.
         Fakat StringRequest hepsini kapsadığı için bunu kullandık. */
        // VOLLEY İSTEĞİ BURADA YAPILIYOR.
        StringRequest request = new StringRequest(Request.Method.GET, urlMarkalar, new Response.Listener&lt;String>() {
            @Override
            public void onResponse(String string) { // sonuç başarılı dönerse onResponse çağrılır
                okunanlariParseEt(string);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) { // hata olursa volleyError nesnesinde hata sebebi yazar
                Toast.makeText(getApplicationContext(), "Veriler Okunurken Hata Oluştu", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });

        // isteği kuyruğa ekledik. "markalar" etiketini ise isteği iptal etmek istediğimizde kullanacağız. Zorunlu değildir
        AppController.getInstance().addToRequestQueue(request, "markalar"); 
    }

    void okunanlariParseEt(String okunanJson) { // dönen sonucu parse ediyoruz
        try {
            JSONObject jsonObj = new JSONObject(okunanJson);
            JSONArray arrayMarka = jsonObj.getJSONArray("markalar");
            ArrayList&lt;String> sonucList = new ArrayList&lt;>();

            for (int i = 0; i &lt; arrayMarka.length(); ++i) { // markaları tek tek listeye ekledik
                sonucList.add(arrayMarka.getString(i));
            }

            // oluşturduğumuz sonucList listesini, listview'ın adaptörüne verdik ve listede gösterilmesini sağladık
            ArrayAdapter&lt;String> adapter = new ArrayAdapter&lt;>(this, android.R.layout.simple_list_item_1, sonucList);
            listViewMarka.setAdapter(adapter);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        dialog.dismiss();
    }
}</pre>



<p>Burada yapılan işlemleri açıklama satırlarında anlatmaya çalıştım. Yine üzerinden geçelim.</p>



<p>Bir <strong>StringRequest </strong>nesnesi oluşturduk. İlk parametresi, <strong>isteğin tipidir</strong>. Biz <strong>GET </strong>isteğinde bulunduk. Sonraki parametre, bağlanacağımız <strong>URL</strong>&#8216;dir. Diğer 2 parametre ise başarılı ve başarısız sonuç döndüğünde çalışacak <strong>Listener</strong>&#8216;lardır.</p>



<p>Sonuç dönerse <strong>onResponse()</strong> metodu çalışır. Bu metotta dönen <strong>JSON </strong>değeri <strong>parse </strong>edilir ve değerler tek tek listeye eklenir. Son olarak liste, <strong>ListView</strong>&#8216;a <strong>adaptör </strong>olarak verilir ve ekranda gösterilir.</p>



<p class="has-text-color has-vivid-red-color">Eğer dönen <strong>JSON </strong>değeri, doğrudan bir <strong>JSON Array</strong>&#8216;i ise <strong>StringRequest </strong>yerine <strong>JsonArrayRequest </strong>de kullanabilirsiniz. O zaman Listener&#8217;a ait metotlar da değişecektir. <strong>JSON Objesi </strong>ise <strong>JsonObjectRequest </strong>sınıfı kullanılabilir. <strong>StringRequest </strong>ikisini de kapsadığı için ben bunu kullandım.</p>



<p>Bu sınıfa ait<strong> xml </strong>dosyasını da oluşturalım.</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    &lt;ListView
        android:id="@+id/lwMarka"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
&lt;/RelativeLayout></pre>



<p><strong>Markaları Göster</strong> butonuna tıkladığımızda ekran görüntüsü şu şekilde olacaktır.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi2.png"><img decoding="async" loading="lazy" width="344" height="587" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi2.png" alt="" class="wp-image-3155" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi2.png 344w, https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi2-176x300.png 176w" sizes="(max-width: 344px) 100vw, 344px" /></a></figure>



<p style="font-size:32px"><br><strong>Kullanıcılar Ekranı</strong></p>



<p><strong>ActivityKullanicilar.java</strong> sınıfında ise biraz daha detaylı bir <strong>JSON </strong>dosyası okuyacağız ve parse edip ListView&#8217;da göstereceğiz.</p>



<p>Öncelikle URL&#8217;imizde bulunan <strong>JSON </strong>dosyasının içeriğini paylaşalım. JSON dosyasında şu bilgiler bulunmaktadır.</p>



<pre class="crayon-plain-tag">[{
  "id": 1,
  "ad": "Mehmet",
  "soyad": "Kirazli",
  "sehir": "Istanbul",
  "cinsiyet": "Erkek",
  "ip_adres": "36.48.233.2"
}, {
  "id": 2,
  "ad": "Faruk",
  "soyad": "Kalkan",
  "sehir": "Edirne",
  "cinsiyet": "Erkek",
  "ip_adres": "212.111.4.222"
}, {
  "id": 3,
  "ad": "Salih",
  "soyad": "Aydin",
  "sehir": "Samsun",
  "cinsiyet": "Erkek",
  "ip_adres": "120.33.112.111"
}, {
  "id": 4,
  "ad": "Okan",
  "soyad": "Eren",
  "sehir": "Giresun",
  "cinsiyet": "Erkek",
  "ip_adres": "77.77.222.11"
}]</pre>



<p>Şimdi bu <strong>JSON </strong>dosyasına <strong>Volley </strong>ile erişip okuma işlemi yapalım.</p>



<p class="has-text-color has-vivid-red-color">Şuan elimde JSON bilgisi dönen bir servis olmadığı için hazır bir JSON dosyasına erişiyorum. Eğer JSON dönen <strong>www.mehmetkirazli.com/apis/getusers.php</strong> gibi bir servis olsaydı, URL kısmında bunu yazacaktım. Fakat siz test amaçlı olarak :<br><strong>https://maps.googleapis.com/maps/api/place/textsearch/xml?query=restaurants+in+Sydney&amp;key=API_KEY&nbsp;</strong><br>URL&#8217;ini test edebilirsiniz. Api key girerek servisten dönen JSON değerini görebilirsiniz.</p>



<p><strong>ActivitiyKulanicilar.java</strong></p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.volleykullanimi;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

import org.json.JSONArray;
import org.json.JSONException;

import java.util.ArrayList;

public class ActivityKullanicilar extends AppCompatActivity {
    ListView listViewMarka;
    String urlKullanicilar = "https://www.mehmetkirazli.com/Dosya/kullanicilar.json";
    ProgressDialog dialog;

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

        listViewMarka = (ListView) findViewById(R.id.lwMarka);

        // istek bitene kadar dilaog gösterilir. istek sonuçlanınca dialog kapatılacak
        dialog = new ProgressDialog(this);
        dialog.setMessage("Veriler Okunuyor...");
        dialog.setCancelable(false);
        dialog.show();

        /* StringRequest yerine JsonObjectRequest veya JsonArrayRequest de kullanılabilir.
         Fakat StringRequest hepsini kapsadığı için bunu kullandık. */
        // VOLLEY İSTEĞİ BURADA YAPILIYOR.
        StringRequest request = new StringRequest(Request.Method.GET, urlKullanicilar, new Response.Listener&lt;String>() {
            @Override
            public void onResponse(String sonuc) { // sonuç başarılı dönerse onResponse çağrılır
                ArrayList&lt;Kullanicilar> kullaniciList = okunanlariParseEt(sonuc); // parse metodu çağrıldı
                ArrayAdapter&lt;Kullanicilar> adapter = new ArrayAdapter&lt;>(ActivityKullanicilar.this, android.R.layout.simple_list_item_1, kullaniciList);
                listViewMarka.setAdapter(adapter);
            }
        }, new Response.ErrorListener() { // hata oluşursa burası çağrılır
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getApplicationContext(), "Veriler Okunurken Hata Oluştu", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });

        AppController.getInstance().addToRequestQueue(request, "kullanicilar");
    }

    ArrayList&lt;Kullanicilar> okunanlariParseEt(String okunanJson) {
        ArrayList&lt;Kullanicilar> kullaniciList = new ArrayList&lt;>();
        try {
            JSONArray arrayKullanici = new JSONArray(okunanJson);
            for (int i = 0; i &lt; arrayKullanici.length(); ++i) {
                kullaniciList.add(new Kullanicilar(Integer.valueOf(arrayKullanici.getJSONObject(i).get("id").toString()), arrayKullanici.getJSONObject(i).get("ad").toString(),
                        arrayKullanici.getJSONObject(i).get("soyad").toString(), arrayKullanici.getJSONObject(i).get("sehir").toString(),
                        arrayKullanici.getJSONObject(i).get("cinsiyet").toString(), arrayKullanici.getJSONObject(i).get("ip_adres").toString()));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        dialog.dismiss();
        return kullaniciList;
    }
}</pre>



<p>Genel olarak <strong>Markalar </strong>sınıfındaki benzer işlemleri yaptık. Parse işlemleri biraz daha karışık oldu. <strong>AppController </strong>sınıfında <strong>addToRequestQueue()</strong> metoduna, isteğimizi parametre olarak verdik ve kuyruğa ekledik. Yanında bir de <strong>&#8220;kullanicilar&#8221; </strong>metnini verdik. Bunu, isteği iptal etmek istediğimizde kullanacağız ve bu isimle iptal edeceğiz. Bunu kendisi yapıyor fakat örnek olması açısından yazdım. Bu parametreyi yazmak zorunlu değildir.</p>



<p>Burada <strong>Markalar </strong>sınıfından farklı olarak, dönen JSON&#8217;ı parse edip <strong>Kullanicilar </strong>adında bir <strong>model </strong>sınıfına ekledik. <strong>Kullanicilar </strong>sınıfını da verelim.</p>



<p><strong>Kullanicilar Model sınıfı:</strong></p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.volleykullanimi;

public class Kullanicilar {
    private int id;
    private String ad;
    private String soyad;
    private String sehir;
    private String cinsiyet;
    private String ip_adres;

    public Kullanicilar(int id, String ad, String soyad, String sehir, String cinsiyet, String ip_adres) {
        this.id = id;
        this.ad = ad;
        this.soyad = soyad;
        this.sehir = sehir;
        this.cinsiyet = cinsiyet;
        this.ip_adres = ip_adres;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAd() {
        return ad;
    }

    public void setAd(String ad) {
        this.ad = ad;
    }

    public String getSoyad() {
        return soyad;
    }

    public void setSoyad(String soyad) {
        this.soyad = soyad;
    }

    public String getSehir() {
        return sehir;
    }

    public void setSehir(String sehir) {
        this.sehir = sehir;
    }

    public String getCinsiyet() {
        return cinsiyet;
    }

    public void setCinsiyet(String cinsiyet) {
        this.cinsiyet = cinsiyet;
    }

    public String getIp_adres() {
        return ip_adres;
    }

    public void setIp_adres(String ip_adres) {
        this.ip_adres = ip_adres;
    }

    @Override
    public String toString() {
        return ad + " " + soyad + "\n" + cinsiyet + "-" + sehir + "-" + ip_adres;
    }
}</pre>



<p>Bu model sınıfında en son <strong>toString()</strong> metodunu <strong>override</strong> ettik. Çünkü ListView&#8217;a bu modele ait listeyi parametre olarak verdiğimizde, her satırda görülmesi istenen metni yazdık. <strong>Custom </strong>bir <strong>Adapter</strong>&#8216;e gerek kalmadı.</p>



<p><strong>activity_kullanicilar.xml</strong> dosyası :</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    &lt;ListView
        android:id="@+id/lwMarka"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
&lt;/RelativeLayout></pre>



<p><strong>&#8220;Kullanıcıları Göster&#8221;</strong> butonuna tıkladığımızda <strong>ActivityKullanicilar </strong>ekranı açılacak ve sonuç alınıp ekrana aşağıdaki gibi bilgiler yazılacak. Tabi bu arada <strong>ProgressBar </strong>da dönecek ve sonuç döndüğünde progress kapanacak.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi3.png"><img decoding="async" loading="lazy" width="341" height="589" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi3.png" alt="" class="wp-image-3156" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi3.png 341w, https://www.mehmetkirazli.com/wp-content/uploads/2019/02/VolleyKullanimi3-174x300.png 174w" sizes="(max-width: 341px) 100vw, 341px" /></a></figure>



<p style="font-size:32px"><br><strong>POST İSTEĞİ GÖNDERME</strong></p>



<p>Bu zamana kadar örneklerde <strong>GET </strong>isteği gönderdik. <br></p>



<pre class="crayon-plain-tag">StringRequest request = new StringRequest(Request.Method.GET, urlKullanicilar, new Response.Listener&lt;String>() {</pre>



<p>Satırında da <strong>GET </strong>isteği gönderdiğimizi belirttik. Hazırladığınız servisin özelliğine göre <strong>POST </strong>isteği de göndermek isteyebilirsiniz. <strong>POST </strong>isteklerinde servise parametre gönderirsiniz ve size sonuç döner. <strong>URL </strong>kısmında ise gönderdiğiniz parametreler yazmaz. <strong>GET </strong>isteğinde ise bu parametreler yazar. Parametreden kastımız örnek olarak <strong>id = 1</strong> gönderirsiniz ve <strong>id </strong>değeri 1 olan kayıtlar serviste okunur ve sonuç <strong>JSON </strong>olarak size döner. </p>



<p class="has-text-color has-vivid-red-color">Yani GET işleminde URL&#8217;de parametreleri yazarız (Örneklerimizde parametre yoktu). POST işleminde ise parametreleri URL&#8217;e yazmayız, arkaplanda göndeririz.</p>



<p><strong>Volley </strong>ile <strong>POST </strong>isteği oluşturduğunuzda, her şey aynı sadece <strong>StringRequest</strong>&#8216;i oluşturduğunuz satırda aşağıdaki gibi ufak bir değişiklik yapıyorsunuz.</p>



<pre class="crayon-plain-tag">StringRequest request = new StringRequest(Request.Method.POST, urlKullanicilar, new Response.Listener&lt;String>() {</pre>



<p>Daha sonra da isteğin sonuna parametreleri ekliyorsunuz. Parametre ekleme metodu olan <strong>getParams()</strong> metodundaki süslü parantezlerin sırasına dikkat ediniz. Çünkü bu bölüm biraz karışık. Kod bloğumuz son olarak şu şekilde olur:</p>



<pre class="crayon-plain-tag">StringRequest request = new StringRequest(Request.Method.POST, urlKullanicilar, new Response.Listener&lt;String>() {
            @Override
            public void onResponse(String string) {
                ArrayList&lt;Kullanicilar> kullaniciList = okunanlariParseEt(string);
                ArrayAdapter&lt;Kullanicilar> adapter = new ArrayAdapter&lt;>(ActivityResimler.this, android.R.layout.simple_list_item_1, kullaniciList);
                listViewMarka.setAdapter(adapter);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getApplicationContext(), "Veriler Okunurken Hata Oluştu", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        }) {
            @Override
            protected Map&lt;String, String> getParams() {
                Map&lt;String, String> params = new HashMap&lt;>();
                params.put("id", "2");
                return params;
            }
        };

        AppController.getInstance().addToRequestQueue(request);</pre>



<p>Burada id değeri 2 ye eşit olan kaydı bize getirir. Tabi servisin de buna uygun kontrolleri yapmış olması gerekiyor. Örnek olarak eğer servisimiz PHP ile hazırlanmışsa şu şekilde kontrol olacaktır.</p>



<pre class="crayon-plain-tag">if($_SERVER['REQUEST_METHOD']=="POST"){
	$id= @$_POST['id'];
}</pre>



<p>Bunu <strong>GET </strong>ile yapsaydık <strong>urlKullanicilar </strong>URL&#8217;inin sonunda <strong>?id=2</strong> gibi bir ekleme yapılacaktı ve <strong>getParams() </strong>olmayacaktı.</p>



<p style="font-size:26px"><strong>Header Ekleme</strong></p>



<p>Eğer <strong>POST </strong>isteğinize bir <strong>Header </strong>bilgisi eklemek istiyorsanız, isteğinizi aşağıdaki gibi güncellemeniz gerekmektedir.</p>



<pre class="crayon-plain-tag">StringRequest request = new StringRequest(Request.Method.POST, urlKullanicilar, new Response.Listener&lt;String>() {
            @Override
            public void onResponse(String string) {
                ArrayList&lt;Kullanicilar> kullaniciList = okunanlariParseEt(string);
                ArrayAdapter&lt;Kullanicilar> adapter = new ArrayAdapter&lt;>(ActivityResimler.this, android.R.layout.simple_list_item_1, kullaniciList);
                listViewMarka.setAdapter(adapter);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getApplicationContext(), "Veriler Okunurken Hata Oluştu", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        }) {
            @Override
            public Map&lt;String, String> getHeaders() throws AuthFailureError {
                HashMap&lt;String, String> headers = new HashMap&lt;>();
                headers.put("Content-Type", "application/json");
                headers.put("apiKey", "abcdefghijklmn");
                return headers;
            }
        };</pre>



<p style="font-size:24px" class="has-text-color has-vivid-red-color"><br><strong>ÖNEMLİ BİR UYARI</strong><br></p>



<p>Konu başında belirtmiştim. <strong>Volley </strong>isteği oluşturduktan sonra isteği, <strong>AppController </strong>üzerinden kuyruğa ekliyoruz. Bu işlem şu şekilde de yapılabiliyor fakat önerilmiyor.</p>



<p><strong>İsteği oluşturmadan önce :</strong></p>



<pre class="crayon-plain-tag">RequestQueue rQueue = Volley.newRequestQueue(ActivityMarkalar.this);</pre>



<p>Kod bloğu ile bir kuyruk oluşturuluyor. İstek oluşturulduktan sonra da aşağıdaki gibi isteğimiz kuyruğa ekleniyor.</p>



<p><strong>İsteği oluşturduktan sonra :</strong></p>



<pre class="crayon-plain-tag">rQueue.add(request);</pre>



<p><strong>Eğer uygulamada çokça Volley isteği olacaksa</strong>, bu işlemlerin tek bir <strong>SingletonClass </strong>üzerinden yapılması (<strong>AppController</strong>) daha doğrudur ve Google da bunu önermektedir. Fakat az sayıda istek olması durumunda manuel olarak her istek için <strong>RequestQueue </strong>nesnesi de oluşturulabilir. Bu şekilde bir yapı kullanılacaksa, <strong>RequestQueue </strong>nesnesi, istek yapılmadan önce oluşturulmalıdır.</p>



<p style="font-size:32px"><strong>Resim İşlemleri</strong></p>



<p>Son olarak <strong>Volley </strong>ile resim bilgisini okuyup <strong>ImageView </strong>üzerinde gösterim işlemini yapalım. Okunan resim bilgisini <strong>Bitmap</strong>&#8216;e çevirip ImageView içerisine <strong>set </strong>edeceğiz.</p>



<p>İlk olarak xml tarafını yazalım. Basit bir <strong>ImageView </strong>olması yeterli. <strong>activity_resimler:</strong></p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    &lt;ImageView
        android:id="@+id/imgView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true" />
&lt;/RelativeLayout></pre>



<p>Şimdi de <strong>ActivityResimler </strong>sınıfını kodlayalım.</p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.volleykullanimi;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;

public class ActivityResimler extends AppCompatActivity {
    String urlResimler = "https://www.mehmetkirazli.com/wp-content/uploads/2017/03/islami-hafiza-oyunu-310x165.png";
    ProgressDialog dialog;
    ImageView imgView;

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

        imgView = (ImageView) findViewById(R.id.imgView);

        dialog = new ProgressDialog(this);
        dialog.setMessage("Veriler Okunuyor...");
        dialog.setCancelable(false);
        dialog.show();

        ImageLoader imageLoader = AppController.getInstance().getImageLoader();
        // resim indirilirken ve hata olması durumunda gösterilecek resimleri ayarladık.
        imageLoader.get(urlResimler, ImageLoader.getImageListener(imgView, R.drawable.yukleniyor, R.drawable.hata));
        // resim alınıyor
        imageLoader.get(urlResimler, new ImageLoader.ImageListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                dialog.dismiss(); // hata olursa dialog kapansın ve hata mesajı loga basılsın
                Log.d("hata",error.toString());
            }

            @Override
            public void onResponse(ImageLoader.ImageContainer response, boolean arg1) {
                if (response.getBitmap() != null) {
                    imgView.setImageBitmap(response.getBitmap()); // bitmap'e çevirip set ettik
                }
                dialog.dismiss();
            }
        });
    }
}</pre>



<p>Burada resim indirilirken aşağıdaki <strong>YÜKLENİYOR </strong>resmi ImageView&#8217;da gösterilecek.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/yukleniyor.png"><img decoding="async" loading="lazy" width="200" height="200" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/yukleniyor.png" alt="" class="wp-image-3160" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/yukleniyor.png 200w, https://www.mehmetkirazli.com/wp-content/uploads/2019/02/yukleniyor-150x150.png 150w" sizes="(max-width: 200px) 100vw, 200px" /></a></figure>



<p>Eğer resim indirilirken hata alınırsa da ImageView&#8217;da aşağıdaki hata resmi gösterilecek. <strong>Volley </strong>ile bunları ayarlayabilmek iyi oluyor.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/hata.png"><img decoding="async" loading="lazy" width="200" height="200" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/hata.png" alt="" class="wp-image-3159" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/hata.png 200w, https://www.mehmetkirazli.com/wp-content/uploads/2019/02/hata-150x150.png 150w" sizes="(max-width: 200px) 100vw, 200px" /></a></figure>



<p>Ekran çıktımız ise şu şekilde olacaktır.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volley4.png"><img decoding="async" loading="lazy" width="344" height="587" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volley4.png" alt="" class="wp-image-3161" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volley4.png 344w, https://www.mehmetkirazli.com/wp-content/uploads/2019/02/volley4-176x300.png 176w" sizes="(max-width: 344px) 100vw, 344px" /></a></figure>



<p style="font-size:26px"><br><strong>Cache Okuma&nbsp;ve&nbsp;Silme</strong></p>



<p>Volley kütüphanesinde <strong>Cache </strong>mekanizması olduğunu ve bu yüzden hız konusunda avantaj sağladığını söylemiştik. Cache&#8217;de tutulan bilgileri görmek, eğer cache boşsa yeni bir istek yapmak isteyebiliriz. Bunun kullanımı ise şu şekildedir.</p>



<pre class="crayon-plain-tag">Cache cache = AppController.getInstance().getRequestQueue().getCache();
        Cache.Entry entry = cache.get("https://www.mehmetkirazli.com/Dosya/markalar.json");
        if (entry != null) {
            try {
                String cacheBilgisi = new String(entry.data, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else {
            // cache boş. yeni istek yapılabilir
        }</pre>



<p>Daha önce gidilmiş bir <strong>URL </strong>varsa, <strong>Cache</strong>&#8216;de tutulan dönüş bilgisini bu şekilde görebiliriz. Debug yapıldığında, <strong>cacheBilgisi </strong>değişkeninde, henüz istek yapılmadan JSON değeri görülür.</p>



<p>Url&#8217;deki <strong>JSON </strong>bilgisinin değiştiğini düşünürsek, <strong>Cache </strong>bilgisini silmek için ise aşağıdaki kod kullanılabilir.</p>



<pre class="crayon-plain-tag">AppController.getInstance().getRequestQueue().getCache().remove("https://www.mehmetkirazli.com/Dosya/markalar.json");</pre>



<p style="font-size:26px"><br><strong>İstek İptal Etme</strong></p>



<p>Örneklerde kuyruğa eklerken bir parametre daha eklemiştik hatırlarsanız. Bunu daha sonra istek iptal etmek istediğimizde <strong>KEY </strong>olarak kullanacağımızı söylemiştik.</p>



<p>Eğer kullanıcıları aldığımız isteği herhangi bir sebeple iptal etmek istersek:</p>



<pre class="crayon-plain-tag">AppController.getInstance().getRequestQueue().cancelAll("kullanicilar");</pre>



<p>Komutunu kullanmalıyız. <strong>Volley </strong>bunu bizim için yapıyor fakat bir yerde işleyişe müdahale etmek istediğimizde işimize yarayacaktır.</p>



<p>Volley kütüphanesinin kullanımı bu şekildedir. Uzun bir yazı oldu umarım anlatabilmişimdir. </p>



<p>Geliştiriciler için Volley bir nimettir. En azından AsyncTask belasından kurtulmuş olduk <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Görüşmek üzere&#8230;</p>



<p class="has-text-color has-medium-font-size has-vivid-red-color"><strong><a href="https://www.mehmetkirazli.com/KaynakKodlar/VolleyKullanimi.rar">KAYNAK KODLAR</a></strong></p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-volley-kullanimi-ve-json-parse-islemleri/">Android Volley Kullanımı ve JSON Parse İşlemleri</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/android-volley-kullanimi-ve-json-parse-islemleri/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Android ButterKnife Kütüphanesi Kullanımı</title>
		<link>https://www.mehmetkirazli.com/android-butterknife-kutuphanesi-kullanimi/</link>
					<comments>https://www.mehmetkirazli.com/android-butterknife-kutuphanesi-kullanimi/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Mon, 04 Feb 2019 10:42:03 +0000</pubDate>
				<category><![CDATA[Kütüphaneler]]></category>
		<category><![CDATA[android butterknife]]></category>
		<category><![CDATA[android butterknife kullanımı]]></category>
		<category><![CDATA[butterknife]]></category>
		<category><![CDATA[butterknife kütüphanesi nedir]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3136</guid>

					<description><![CDATA[<p>Merhaba. Bu yazımda Android platformunda kullanıma sunulan, bazı kod bloklarını basitleştiren ve okunabilirliği arttıran ButterKnife kütüphanesinden bahsedeceğim. ButterKnife, Square firmasında Jake Wharton tarafından geliştirilmiş kullanışlı bir kütüphanedir. ButterKnife ile Xml yani tasarım tarafında oluşturduğumuz bazı elemanları, Java tarafına geçirmemizi ve kullanabilmemizi sağlar. Xml tarafından kastım Button, TextView, ListView, Drawable, Color, Strings vs. ButterKnife kütüphanesinin kullanımını &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-butterknife-kutuphanesi-kullanimi/">Android ButterKnife Kütüphanesi Kullanımı</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Bu yazımda Android platformunda kullanıma sunulan, bazı kod bloklarını basitleştiren ve okunabilirliği arttıran <strong>ButterKnife </strong>kütüphanesinden bahsedeceğim.</p>



<span id="more-3136"></span>



<p>ButterKnife, Square firmasında <a rel="noreferrer noopener" aria-label="Jake Wharton (yeni sekmede açılır)" href="https://github.com/JakeWharton" target="_blank">Jake Wharton</a> tarafından geliştirilmiş kullanışlı bir kütüphanedir. </p>



<p>ButterKnife ile <strong>Xml </strong>yani tasarım tarafında oluşturduğumuz bazı elemanları, Java tarafına geçirmemizi ve kullanabilmemizi sağlar. Xml tarafından kastım Button, TextView, ListView, Drawable, Color, Strings vs.</p>



<p>ButterKnife kütüphanesinin kullanımını basit bir örnek üzerinde gösterelim.</p>



<p>İlk olarak <strong>build.gradle</strong> dosyamızı hazırlayalım. <strong>ButterKnife </strong>kütüphanesini kullanabilmek için <strong>build.gradle</strong> dosyasında en tepeye aşağıdaki satır eklenir.</p>



<pre class="crayon-plain-tag">apply plugin: 'com.android.application'</pre>



<p>En altta <strong>dependencies</strong> kısmına ise şu 2 satır kod eklenmelidir. Son hali:</p>



<pre class="crayon-plain-tag">apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.mehmetkirazli.butterknife"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'

    // butterknife için bu satırlar eklenmelidir
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}</pre>



<p>Örnek olarak ekranımıza basit bir buton ekleyelim ve tıklama olayına 1-2 satırlık kod yazalım. </p>



<p><strong>Normalde </strong>klasik olarak butonun tıklama eventi için önce butonu <strong>findViewById </strong>ile bağlıyoruz ve bir <strong>Listener </strong>kullanarak işlemi yapıyoruz. </p>



<p>Şu anki yapıda, klasik olarak bildiğimiz kod şu şekildedir:</p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.butterknife;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button btnTest;

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

        btnTest = findViewById(R.id.button);

        btnTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "Butona Basıldı", Toast.LENGTH_SHORT).show();

                // butonun metni ve arka planı değiştirildi
                btnTest.setText("Tıklandı");
                btnTest.setBackgroundColor(Color.RED);
            }
        });
    }
}</pre>



<p>Basit olarak bir adet butonumuz var ve tıklandığında mesaj verip, görselle ilgili değişiklikler yaptık.</p>



<p><strong>ButterKnife </strong>kullandığımızda ise biraz daha anlaşılabilir ve kısa bir kod yapısı karşımıza çıkıyor. <strong>findViewById </strong>yerine <strong>BindView </strong>annotationunu kullanıyoruz. Üzerinde işlem yaptığımız bileşen bir <strong>View </strong>bileşeni olduğu için <strong>BindView </strong>yazıyoruz. <strong>Drawable </strong>dosyası için olsaydı <strong>BindDrawable </strong>yazacaktık.</p>



<p>Aynı kodu <strong>ButterKnife </strong>ile yazarsak:</p>



<pre class="crayon-plain-tag">package com.mehmetkirazli.butterknife;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

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

        // bind işlemi yapıldı
        ButterKnife.bind(this);
    }

    // buton tanımlandı
    @BindView(R.id.button) Button btnTest;

    // click eventi yazıldı
    @OnClick(R.id.button) void tikla() {
        Toast.makeText(this, "Butona Basıldı", Toast.LENGTH_SHORT).show();

        // butonun metni ve arka planı değiştirildi
        btnTest.setText("Tıklandı");
        btnTest.setBackgroundColor(Color.RED);
    }
}</pre>



<p>2 YÖNTEMDE DE ORTAK OLAN ÇIKTIMIZ:</p>



<p>Butona tıklamadan önce:</p>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/butterknife-1.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/butterknife-1.png" alt="" class="wp-image-3137" width="99" height="55"/></a></figure>



<p>Butona tıklandıktan sonra:</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/butterknife-2.png"><img decoding="async" loading="lazy" width="204" height="274" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/butterknife-2.png" alt="" class="wp-image-3138"/></a></figure>



<p>Burada dikkat ettiyseniz şu anki yapıda(<strong>findViewById</strong>), butonu oluşturma ve tıklama kodlarımızı <strong>onCreate()</strong> metodu içerisine yazıyoruz. <strong>ButterKnife </strong>kullandığımızda ise bu kodları <strong>onCreate()</strong> <strong>dışına </strong>yazıyoruz. </p>



<p>Aynı şekilde sadece görsel bileşenleri değil de <strong>strings.xml</strong>, <strong>colors.xml</strong> gibi dosyalar için tanımlama yaparsak :</p>



<pre class="crayon-plain-tag">@BindDrawable(R.drawable.icon) Drawable icon; // drawable 
@BindString(R.string.age) String yas; // string 
@BindColor(R.color.yellow) int renk; // color</pre>



<p>Şeklinde kullanmamız gerekir. Oluşturduğunuz değişken adını da istediğiniz yerde kullanabilirsiniz. Örnek kullanım:</p>



<pre class="crayon-plain-tag">tvBaslik.setTextColor(renk);
imvProfil.setImageDrawable(icon);</pre>



<p>Örnekte sadece buton üzerinden gösterdik fakat TextView, EditText gibi bileşenler de tamamen aynı şekilde kullanılır. Bununla ilgili de basit bir örnek verelim.</p>



<pre class="crayon-plain-tag">public class MainActivity extends AppCompatActivity {

    // bileşenler tanımlandı
    @BindView(R.id.btnArttir) Button btnSayiArttir;
    @BindView(R.id.btnAzalt) Button btnSayiAzalt;
    @BindView(R.id.edtSayi) EditText edtSayi;

    @OnClick(R.id.btnArttir)
    void arttir() {
        edtSayi.setText(String.valueOf(Integer.valueOf(edtSayi.getText().toString()) + 1));
    }

    @OnClick(R.id.btnAzalt)
    void azalt() {
        edtSayi.setText(String.valueOf(Integer.valueOf(edtSayi.getText().toString()) - 1));
    }

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

        ButterKnife.bind(this);
    }
}</pre>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/butterknife-3.png"><img decoding="async" loading="lazy" width="204" height="180" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/02/butterknife-3.png" alt="" class="wp-image-3147"/></a></figure>



<p>Örneğimizde 2 adet buton kullanarak, <strong>EditText </strong>içerisine girilen sayıyı arttırıp azaltma işlemi yaptık. İki butonun da tanımlamalarını ve click eventini ayrı ayrı yaptık. </p>



<p class="has-medium-font-size"><strong><a href="http://www.mehmetkirazli.com/KaynakKodlar/ButterKnifeKullanimi.rar">KAYNAK KOD İNDİR</a></strong></p>



<h2>Nasıl Çalışır ?</h2>



<p>ButterKnife, <strong>Annotation tabanlıdır</strong> ve Annotation&#8217;lar da <strong>CompileTime</strong> (derleme zamanında) dikkate alınıp çalıştırılır. Bunu sağlayan yapı <strong>Annotation Processor</strong>&#8216;dur. Siz de <strong>AbstractProcessor </strong>sınıfından türetilen(<strong>extends</strong>) bir <strong>Processor </strong>ve bunun Binding&#8217;lerini yazarsanız, siz de kendinize özel bir <strong>ButterKnife </strong>benzeri bir kütüphane oluşturabilirsiniz ve açık kaynak olarak kullanıma sunabilirsiniz <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Hazırlanan bu tarz kütüphanelere <strong>ViewInjector </strong>kütüphanesi denir.</p>



<p>Projeyi derlediğinizde (henüz çalıştırmadan), Annotation&#8217;un bulunduğu satırlar, şuan bildiğimiz ve uyguladığımız Java kodlarına(<strong>findViewById</strong>) dönüştürülür. Bunu sağlayan yapı, kütüphane içindeki <strong>Annotation Prosessor</strong>&#8216;dür. Hangi bileşenin hangi koda dönüştürüleceği ise bu kütüphanede tanımlanmıştır.</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-butterknife-kutuphanesi-kullanimi/">Android ButterKnife Kütüphanesi Kullanımı</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/android-butterknife-kutuphanesi-kullanimi/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Admob TikTok Reklamları Engelleme</title>
		<link>https://www.mehmetkirazli.com/admob-tiktok-reklamlari-engelleme/</link>
					<comments>https://www.mehmetkirazli.com/admob-tiktok-reklamlari-engelleme/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Wed, 09 Jan 2019 13:35:00 +0000</pubDate>
				<category><![CDATA[İpuçları]]></category>
		<category><![CDATA[adsense reklam engelleme]]></category>
		<category><![CDATA[android reklam engelleme]]></category>
		<category><![CDATA[android tiktok engelleme]]></category>
		<category><![CDATA[tiktok]]></category>
		<category><![CDATA[tiktok reklamı engelleme]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3111</guid>

					<description><![CDATA[<p>Merhaba. Bu yazımda artık baş belası olmuş TikTok reklamlarını, Android uygulamalarımızdaki Admob reklamlarından nasıl kaldıracağımızı anlatacağım. Bir gençliğin nasıl çökertilebileceğini bizlere gösteren, çoğu zaman ahlak sınırlarını aşan TikTok uygulamasının, kendi uygulamalarımda reklam olarak gösterildiğini farkettim. Bunu nasıl engelleyebileceğimi araştırdım ve kendimce bulduğum çözümleri derledim. Bu reklamları engellemenin birkaç yolu var. Ben tümünü birden gösterip uygulayacağım. &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/admob-tiktok-reklamlari-engelleme/">Admob TikTok Reklamları Engelleme</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Bu yazımda artık baş belası olmuş <strong>TikTok </strong>reklamlarını, Android uygulamalarımızdaki <strong>Admob </strong>reklamlarından nasıl kaldıracağımızı anlatacağım.</p>



<span id="more-3111"></span>



<p>Bir gençliğin nasıl çökertilebileceğini bizlere gösteren, çoğu zaman ahlak sınırlarını aşan <strong>TikTok</strong> uygulamasının, kendi uygulamalarımda reklam olarak gösterildiğini farkettim. Bunu nasıl engelleyebileceğimi araştırdım ve kendimce bulduğum çözümleri derledim. </p>



<p>Bu reklamları engellemenin birkaç yolu var. Ben tümünü birden gösterip uygulayacağım. Şuan için işe yaramış görünüyor. Şimdi bunları listeleyelim.</p>



<h2>Video Engelleme</h2>



<p>Aslında en <strong>garanti </strong>yol budur. Fakat <strong>TikTok </strong>haricinde gösterilmesini istediğiniz video reklamlar varsa, bu seçenek size göre değil. Ben tüm video reklamlarını bir şekilde sakıncalı bulduğum için bu şekilde ayarlama yaptım. Tercih sizin.</p>



<p>Bunun için ilk olarak <strong>Admob </strong>panelimize geliyoruz ve soldaki <strong>Uygulamalar </strong>menüsünden uygulamamızı seçiyoruz ve <strong>Reklam Birimleri </strong>sekmesini açıyoruz. </p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme.png"><img decoding="async" loading="lazy" width="827" height="379" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme.png" alt="" class="wp-image-3112" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme.png 827w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme-300x137.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme-768x352.png 768w" sizes="(max-width: 827px) 100vw, 827px" /></a></figure>



<p>Burada uygulamamıza eklediğimiz reklam türleri var. Ben <strong>banner </strong>ve <strong>tam ekran</strong> reklamları eklemiştim. İlk olarak <strong>Banner </strong>seçeneğine tıklayın ve <strong>Gelişmiş Ayarlar</strong> menüsünden <strong>Video </strong>seçeneğini aşağıdaki gibi kaldırın. </p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme2.png"><img decoding="async" loading="lazy" width="974" height="569" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme2.png" alt="" class="wp-image-3113" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme2.png 974w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme2-300x175.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme2-768x449.png 768w" sizes="(max-width: 974px) 100vw, 974px" /></a></figure>



<p></p>



<p><strong>Geçiş reklamı için:</strong></p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme3.png"><img decoding="async" loading="lazy" width="972" height="570" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme3.png" alt="" class="wp-image-3114" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme3.png 972w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme3-300x176.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme3-768x450.png 768w" sizes="(max-width: 972px) 100vw, 972px" /></a></figure>



<p>Bu seçeneği kaldırmak gelirinizi azaltabilir. Çünkü video reklamlar daha çok kazandırır. Fakat videolarda illa ki ahlaken sakıncalı bir reklam geldiği için ben bu şekilde tamamen video reklamları engelledim.</p>



<p class="has-text-color has-vivid-red-color"><strong>N</strong>ot: Bu işlemi tüm uygulamalar ve tüm reklam tipleri (Banner, Tam Ekran vs.) için ayrı ayrı yapmalısınız.</p>



<h2>Reklam Ağları</h2>



<p>Eğer video reklam açık kalsın sadece <strong>TikTok </strong>reklamları engellensin istiyorsanız başka bir seçeneğiniz var. Bunun için yine <strong>Admob </strong>panelinden soldaki <strong>Engelleme Kontrolleri</strong> menüsünü açın ve gelen ekranda <strong>Reklam Ağları </strong>sekmesine tıklayın. </p>



<p>Arama penceresine &#8220;<strong>TouTiao&#8221; </strong>yazın ve arama butonuna basın. Karşınıza gelen sonuçtaki switch&#8217;e tıklayın ve bu ağdan gelen reklamları engelleyin.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme4.png"><img decoding="async" loading="lazy" width="1024" height="375" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme4-1024x375.png" alt="" class="wp-image-3115" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme4-1024x375.png 1024w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme4-300x110.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme4-768x281.png 768w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme4.png 1242w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p class="has-text-color has-vivid-red-color">Not : Bu şekilde yapılan engelleme, admob hesabınızdaki tüm uygulamalar için geçerli olacaktır. Tek tek her biri için ayarlamaya gerek yoktur. </p>



<p class="has-text-color has-vivid-red-color">Not 2 : Bu şekilde yapılan engelleme hem video hem de tam ekran reklamı engelleyecektir diye umuyorum. Çünkü TikTok için reklam ağı aynıdır.</p>



<h2>Reklam İçeriği Derecelendirme </h2>



<p><strong>TouTiao </strong>engellemesi yapılsa bile başka kanallardan bu reklamın gelme ihtimaline karşı bir ayar daha yapacağız.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme5.png"><img decoding="async" loading="lazy" width="1024" height="428" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme5-1024x428.png" alt="" class="wp-image-3116" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme5-1024x428.png 1024w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme5-300x125.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme5-768x321.png 768w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme5.png 1025w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Burada uygulamanızda gösterilecek reklamları, kime hitap ettiğine göre kısıtlayabiliyorsunuz. Eğer en sağdaki &#8220;<strong>MA&#8221;</strong> seçiliyse, yaş kısıtlaması olmaksızın her kullanıcıya reklamlarınız gösterilir. Alkol, cinsel içerik vs. türündeki reklamların gösterilme olasılığı fazladır. </p>



<p>Eğer en soldaki <strong>&#8220;G&#8221;</strong> seçeneğini işaretlerseniz, aile ve çocuklar için uygun içerikler gösterilir. Bunu seçmenizde fayda var. Google&#8217;nin, <strong>TikTok</strong> videolarını bu kategoride göstermeyeceğini düşünüyorum.</p>



<h2>Reklam Veren URL&#8217;leri</h2>



<p>Url bazında da engelleme yapabilirsiniz. <strong>TikTok </strong>reklamına tıkladığınızda adres çubuğunda çıkan Url&#8217;e kısıtlama koyabilir, bu URL&#8217;den verilen reklamları engelleyebilirsiniz.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-1.png"><img decoding="async" loading="lazy" width="968" height="295" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-1.png" alt="" class="wp-image-3126" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-1.png 968w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-1-300x91.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-1-768x234.png 768w" sizes="(max-width: 968px) 100vw, 968px" /></a></figure>



<h2>Uygulama Yükleme Reklamları</h2>



<p>En sağlam engellemelerden birisi de budur. Burada uygulama bazında engelleme yapabilirsiniz. Tam ekran verdiğiniz reklamlarda, <strong>TikTok </strong>yüklemek için Google Play reklamı gösteriliyorsa, buradan engelleme yapılabilir.</p>



<p>Arama çubuğuna <strong>TikTok </strong>yazıp aşağıdaki gibi karşınıza gelen sonuçlara tıklarsanız, tek tek engelleme yapabilirsiniz.</p>



<figure class="wp-block-image is-resized"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-3.png"><img decoding="async" loading="lazy" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-3.png" alt="" class="wp-image-3129" width="542" height="440" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-3.png 723w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-3-300x243.png 300w" sizes="(max-width: 542px) 100vw, 542px" /></a></figure>



<p>Uygulamanın <strong>Google Play</strong> sayfasının reklamını yapılmasını istemediğimiz uygulamalar aşağıda listelenmiştir. </p>



<p class="has-text-color has-vivid-red-color">Burada <strong>video </strong>bazında değil de Google Play&#8217;de yapılan reklamlar engellenir.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-2.png"><img decoding="async" loading="lazy" width="890" height="762" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-2.png" alt="" class="wp-image-3128" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-2.png 890w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-2-300x257.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelle-2-768x658.png 768w" sizes="(max-width: 890px) 100vw, 890px" /></a></figure>



<h2>Reklam İnceleme Merkezi </h2>



<p>İçiniz yine de rahat etmediyse son olarak uygulamanızda çıkan tüm reklamları görebildiğiniz <strong>Reklam İnceleme Merkezi </strong>üzerinden engelleme yapabilirsiniz.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme6.png"><img decoding="async" loading="lazy" width="1024" height="404" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme6-1024x404.png" alt="" class="wp-image-3117" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme6-1024x404.png 1024w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme6-300x118.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme6-768x303.png 768w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme6.png 1192w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Sağdaki arama kısmında yine <strong>TouTiao </strong>yazarak, uygulamanızda ne kadar <strong>TikTok </strong>reklamı hangi tarihlerde gösterilmiş görebiliyorsunuz. Arattığınızda karşınıza reklamlar gelecektir. Reklamın sol altındaki <strong>engelleme </strong>butonuna tıklayıp engelleme yapabilirsiniz. Ya da aşağıdaki gibi reklamın üzerine tıklayıp detayına gittikten sonra, hem<strong> Hesabı Engelle </strong>hem de <strong>Reklamı Engelle</strong> butonu ile reklamı engelleyebilirsiniz.</p>



<p></p>



<p><strong>Reklam Detayı :</strong></p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme7.png"><img decoding="async" loading="lazy" width="253" height="469" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme7.png" alt="" class="wp-image-3118" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme7.png 253w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/tiktokengelleme7-162x300.png 162w" sizes="(max-width: 253px) 100vw, 253px" /></a></figure>



<h2>Sonuç</h2>



<p>Bu TikTok öyle bir illet ki insan nasıl engelleyeceğini şaşırıyor. Bunun için farklı uygulamalar vardır elbet fakat bunu kullanıcı isterse telefonuna yükler ve engelleme yapar. Biz bunu uzaktan ve tüm kullanıcılara uygulamak istediğimiz için bu şekilde yaptık.</p>



<p>Sadece TikTok değil, tüm reklamları bu şekilde engelleyebilir ve gösterilmesini istemediğiniz reklamları kısıtlayabilirsiniz.</p>



<p class="has-text-color has-vivid-red-color">Not : <strong>Adsense </strong>kullanıyorsanız yine bu şekilde <strong>Adsense Panelinden</strong> engellemeler yapabilirsiniz.</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/admob-tiktok-reklamlari-engelleme/">Admob TikTok Reklamları Engelleme</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/admob-tiktok-reklamlari-engelleme/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Google API OVER_QUERY_LIMIT Hatası ve Cloud Hesabı Tanımlama</title>
		<link>https://www.mehmetkirazli.com/google-api-over_query_limit-hatasi-ve-cloud-hesabi-tanimlama/</link>
					<comments>https://www.mehmetkirazli.com/google-api-over_query_limit-hatasi-ve-cloud-hesabi-tanimlama/#respond</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Wed, 09 Jan 2019 06:36:43 +0000</pubDate>
				<category><![CDATA[Hata Çözümleri]]></category>
		<category><![CDATA[android api key çalışmıyor]]></category>
		<category><![CDATA[Bu kart bilgilerini düzeltin veya farklı bir kart deneyin]]></category>
		<category><![CDATA[Google Cloud Platform fatura hesabı]]></category>
		<category><![CDATA[OR-CCSEH-05 hatası çözümü]]></category>
		<category><![CDATA[OVER_QUERY_LIMIT]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3100</guid>

					<description><![CDATA[<p>Merhaba. Play Store&#8217; da yüklü olan En Yakın uygulamamda, yakınlardaki mekanları bulma ve rota çizme, yorumları getirme gibi işlemlerde Google&#8217; dan kaynaklı olarak OVER_QUERY_LIMIT hatası aldım. Bu yazımda hatanın çözümünden bahsedeceğim. Eğer Google Map kullanan bir uygulamanız varsa ve bu uygulamada, konumunuza yakın yerleri bulmak, sokak görünümüne geçmek, rota çizmek, yorumları almak gibi işlemler yapıyorsanız &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/google-api-over_query_limit-hatasi-ve-cloud-hesabi-tanimlama/">Google API OVER_QUERY_LIMIT Hatası ve Cloud Hesabı Tanımlama</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Play Store&#8217; da yüklü olan En Yakın uygulamamda, yakınlardaki mekanları bulma ve rota çizme, yorumları getirme gibi işlemlerde Google&#8217; dan kaynaklı olarak <strong>OVER_QUERY_LIMIT </strong>hatası aldım. Bu yazımda hatanın çözümünden bahsedeceğim.</p>



<span id="more-3100"></span>



<p>Eğer Google Map kullanan bir uygulamanız varsa ve bu uygulamada, konumunuza yakın yerleri bulmak, sokak görünümüne geçmek, rota çizmek, yorumları almak gibi işlemler yapıyorsanız bir <strong>Google API Key</strong> gerekir. Bunu kullananlar bilir. Birkaç ay önce Google, <strong>Cloud Platform</strong>&#8216;a geçtiği için elinizdeki API key ile bu işlemleri yalnızca 1 defa yapabiliyorsunuz. Sonrasında ise <strong>OVER_QUERY_LIMIT</strong> hatası alırsınız ve API çalışmaz. Ancak bir müddet sonra denediğinizde tekrar 1 defalığına çalışır.</p>



<p>Uzun uğraşlar ve araştırmalar sonucunda sebebin, <strong>Google Cloud Platform</strong>&#8216;da bir fatura hesabının açılması gerektiğini öğrendim. Fatura hesabı açtığınızda <strong>1 yıllık 300$</strong> değerinde kredi veriliyor. 1 sene sonunda isterseniz ücretli kullanıma devam edebiliyorsunuz. Elinizdeki API key&#8217; i değiştirmeniz gerekmiyor. Böylece <strong>OVER_QUERY_LIMIT</strong> hatasını artık almamış oluyorsunuz.</p>



<h2>Google Cloud Fatura Hesabı Tanımlama</h2>



<p>Bunun için öncelikle bir <strong>gmail </strong>adresinizin olması gerekiyor. <a href="https://cloud.google.com/" target="_blank" rel="noreferrer noopener" aria-label=" (yeni sekmede açılır)">Bu adresten</a> platformu ücretsiz denemeye başlayabilirsiniz.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud.png"><img decoding="async" loading="lazy" width="300" height="265" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud-300x265.png" alt="" class="wp-image-3103" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud-300x265.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud.png 537w" sizes="(max-width: 300px) 100vw, 300px" /></a></figure>



<p>Kabul ettikten sonra açılan sayfada kullanıcı ve adres bilgilerini girerek son olarak kredi kartı bilgileri de girmeniz gerekiyor. </p>



<p>Kart tanımlaması yaparken banka kartı ekleme çalıştım fakat &#8220;Bu kart bilgilerini düzeltin veya farklı bir kart deneyin&#8221; hatası (<strong>OR-CCSEH-05</strong>) aldım. Bunun için de bir müddet çözüm aradım. Acaba adres mi yanlış yoksa 3D ödemeyi mi kapatmak gerekiyor vs. diye. Sonunda çözümü buldum. Kart tanımı yaparken KREDİ KARTI olması gerekiyor ve SANAL KART ile tanımlama yapılmalı. Sanal kart olmadan doğrudan kredi kartı ile olur mu bilmiyorum. Sonuç olarak kredi kartı özelliği olmayan kartlarda kesinlikle olmuyor. Olayın 3D veya kartı yurt dışına açma ile de alakası yok.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud2.png"><img decoding="async" loading="lazy" width="237" height="300" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud2-237x300.png" alt="" class="wp-image-3104" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud2-237x300.png 237w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud2.png 542w" sizes="(max-width: 237px) 100vw, 237px" /></a></figure>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud3.png"><img decoding="async" loading="lazy" width="300" height="141" src="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud3-300x141.png" alt="" class="wp-image-3105" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud3-300x141.png 300w, https://www.mehmetkirazli.com/wp-content/uploads/2019/01/google-cloud3.png 538w" sizes="(max-width: 300px) 100vw, 300px" /></a></figure>



<p>Kart bilgilerini de doğru girdikten sonra Google Cloud Platformuna giriş yapabilirsiniz ve artık API Key&#8217;iniz çalışacaktır. Fakat senelik <strong>300$</strong> kotanız olduğu için uygulamanızda kısıtlama koymalısınız. Herkes istediği kadar istek göndermemeli ve kota hızlıca dolmamalı.</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/google-api-over_query_limit-hatasi-ve-cloud-hesabi-tanimlama/">Google API OVER_QUERY_LIMIT Hatası ve Cloud Hesabı Tanımlama</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/google-api-over_query_limit-hatasi-ve-cloud-hesabi-tanimlama/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Uygulamanın Play Store&#8217;da Tabletler için Görünmemesi</title>
		<link>https://www.mehmetkirazli.com/uygulamanin-play-storeda-tabletler-icin-gorunmemesi/</link>
					<comments>https://www.mehmetkirazli.com/uygulamanin-play-storeda-tabletler-icin-gorunmemesi/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Mon, 31 Dec 2018 13:40:53 +0000</pubDate>
				<category><![CDATA[Hata Çözümleri]]></category>
		<category><![CDATA[android.hardware.telephony]]></category>
		<category><![CDATA[android:required]]></category>
		<category><![CDATA[Google play de bazı uygulamalar gözükmüyor]]></category>
		<category><![CDATA[Google Play Store Uygulamaları Görmeme Sorunu]]></category>
		<category><![CDATA[tablette uygulama görünmüyor]]></category>
		<category><![CDATA[uses-feature]]></category>
		<category><![CDATA[uygulamanın markette tabletler için görünmemesi]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3094</guid>

					<description><![CDATA[<p>Merhaba. Geliştirdiğiniz bir uygulamayı Play Store&#8217;a attıktan sonra uygulamanızı bir tabletten arattığınızda göremiyorsanız bunun birkaç çözümü vardır. Normalde geliştirdiğiniz bir uygulama tabletler için de uyumlu olsun, markette tabletler tarafından aratıldığında sonuçlarda çıksın isteniliyorsa, yapılması gereken belli başlı şeyler vardır. 1 &#8211; Google Play Console&#8217;da Mağaza Girişi ekranında, 7 ve 10 inç tabletler için de ekran &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/uygulamanin-play-storeda-tabletler-icin-gorunmemesi/">Uygulamanın Play Store&#8217;da Tabletler için Görünmemesi</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Geliştirdiğiniz bir uygulamayı Play Store&#8217;a attıktan sonra uygulamanızı bir tabletten arattığınızda göremiyorsanız bunun birkaç çözümü vardır.</p>



<span id="more-3094"></span>



<p>Normalde geliştirdiğiniz bir uygulama tabletler için de uyumlu olsun, markette tabletler tarafından aratıldığında sonuçlarda çıksın isteniliyorsa, yapılması gereken belli başlı şeyler vardır.</p>



<p><strong>1 &#8211;</strong> Google Play Console&#8217;da <strong>Mağaza Girişi</strong> ekranında, 7 ve 10 inç tabletler için de <strong>ekran görüntüsü</strong> eklenir</p>



<p><strong>2 &#8211;</strong> Uygulamanın <strong>manifest </strong>dosyasına aşağıdaki kod eklenir.</p>



<pre class="crayon-plain-tag">&lt;supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="true"
        android:resizeable="true"
        android:smallScreens="true"
        android:xlargeScreens="true" /></pre>



<p><strong>3 &#8211;</strong> Uygulamanızın <strong>&#8220;res&#8221;</strong> klasörü altındaki <strong>&#8220;drawable&#8221;</strong> dosyaları, 4 farklı ekran çözünürlüğü için ayrı ayrı oluşturulur ve ilgili resim dosyaları boyutlandırılarak bu klasörlere atılır</p>



<p>Bunları yaptığınız halde uygulamanız <strong>telefonlarda aratıldığında markette arama sonuçlarında çıkıyor</strong> <strong>fakat tabletlerde arattığınızda çıkmıyorsa</strong> son olarak yapmanız gereken şudur.</p>



<h3>Çözüm</h3>



<p>Uygulamanızın <strong>Manifest </strong>dosyasında izinler eklediğinizi düşünelim. Örnek olarak:</p>



<pre class="crayon-plain-tag">&lt;uses-permission android:name="android.permission.CALL_PHONE" /></pre>



<p>Uygulamanız bu izne bakarak, uygulama içinden telefon aramasına izin verecektir. Fakat &#8230; !!!</p>



<p>Bir tablette telefonla arama özelliği olmadığı zaman uygulamanız markette arama sonuçlarında çıkmaz. <strong>Sim kart destekli</strong> bir tablet olması gerekir. Çoğu tablet de bunu desteklemez. </p>



<p>Başka bir örnek verirsek:</p>



<pre class="crayon-plain-tag">&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /></pre>



<p>Konum alma izni verdiğinizde, tabletinizde <strong>Gps </strong>modülü DONANIMSAL olarak mevcut olmadığında yine arama sonuçlarında uygulamanız çıkmaz. (Tabletler için)</p>



<p>Çözüm olarak, bu 2 izni verdiğinizi var sayarsak aşağıdaki kod bloğunu da <strong>AndroidManifest.xml</strong> dosyanıza eklemeniz gerekir.</p>



<pre class="crayon-plain-tag">&lt;uses-feature android:name="android.hardware.telephony" android:required="false" tools:node="replace" />
    &lt;uses-feature android:name="android.hardware.location.gps" android:required="false" tools:node="replace" /></pre>



<p><strong>android:required</strong> özelliğinde, cihazda bu modülün olma mecburiyeti yoktur deriz. <strong>Hardware </strong>yani donanım özelliklerinde <strong>Gps </strong>ya da <strong>telefonla arama modülleri</strong> olmasa bile Play Store&#8217; da arama sonuçlarında çıksın diyebiliriz.</p>



<p>Bu kod bloğu olmadığı zaman, donanımsal olarak bazı istenen özellikleri olmayan cihazları <strong>Google Play</strong> <strong>filtreler </strong>ve uygulamayı, bu cihazlar üzerinden yapılan arama sonuçlarında göstermez. </p>



<p class="has-text-color has-vivid-red-color"><strong>Not : </strong>Eğer donanımsal olarak ihtiyaç olmayan <strong>internet, okuma yazma</strong> gibi işlemler için bu eklemeleri yapmanız gerekmez.</p>



<p>Kendi uygulamamda böyle bir sorunla karşılaştığım için kendime de not düşmek amacıyla bu yazıyı yazdım. Umarım sorununuzu çözmüştür.</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/uygulamanin-play-storeda-tabletler-icin-gorunmemesi/">Uygulamanın Play Store&#8217;da Tabletler için Görünmemesi</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/uygulamanin-play-storeda-tabletler-icin-gorunmemesi/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Android 6.0 (Marshmallow) İzin Ayarları &#8211; Runtime Permissions</title>
		<link>https://www.mehmetkirazli.com/android-6-0-marshmallow-izin-ayarlari/</link>
					<comments>https://www.mehmetkirazli.com/android-6-0-marshmallow-izin-ayarlari/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Mon, 24 Dec 2018 14:00:05 +0000</pubDate>
				<category><![CDATA[Android Dersleri]]></category>
		<category><![CDATA[android 6.0 izin ekleme]]></category>
		<category><![CDATA[android marshmallow izin kontrolü]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3072</guid>

					<description><![CDATA[<p>Merhaba. Şuan 9.0 versiyonu çıkmış olsa da Android 6.0 (Marshmallow)&#8217;da gelen ve birçok uygulamanın hata vermesine sebep olan bir yenilikten bahsedeceğim. Android 6.0 (Marshmallow) öncesinde, Google Play&#8217; den uygulama indirirken izinler, indirme esnasında toptan kabul ediliyordu ve bunların arasından erişmesini istemediğimiz izinleri iptal etme gibi bir lüksümüz yoktu. Başta kabul edildiğinde artık izinler kaldırılamıyordu. 4.4.2 &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-6-0-marshmallow-izin-ayarlari/">Android 6.0 (Marshmallow) İzin Ayarları &#8211; Runtime Permissions</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Şuan 9.0 versiyonu çıkmış olsa da Android 6.0 (Marshmallow)&#8217;da gelen ve birçok uygulamanın hata vermesine sebep olan bir yenilikten bahsedeceğim.</p>



<span id="more-3072"></span>



<p>Android 6.0 (Marshmallow) öncesinde, Google Play&#8217; den uygulama indirirken izinler, <strong>indirme esnasında toptan kabul ediliyordu</strong> ve bunların arasından erişmesini istemediğimiz izinleri iptal etme gibi bir lüksümüz yoktu. Başta kabul edildiğinde artık izinler kaldırılamıyordu. </p>



<p><strong>4.4.2 versiyonlu bir cihazda, indirilmiş bir uygulamanın izinleri:</strong></p>



<ul class="is-layout-flex wp-block-gallery-3 wp-block-gallery columns-1 is-cropped"><li class="blocks-gallery-item"><figure><a href="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin1.png"><img decoding="async" loading="lazy" width="591" height="699" src="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin1.png" alt="" data-id="3075" data-link="https://www.mehmetkirazli.com/?attachment_id=3075" class="wp-image-3075" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin1.png 591w, https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin1-254x300.png 254w" sizes="(max-width: 591px) 100vw, 591px" /></a><figcaption>İzinleri iptal etme şansınız yoktur</figcaption></figure></li></ul>



<p>Versiyonu <strong>6.0 ve üzeri</strong> olan cihazlarda ise artık uygulamayı indirirken değil <strong>uygulama açıkken,</strong> ihtiyaç olduğu sürece izin isteniyor ve dilerseniz izin vermeyebiliyorsunuz.</p>



<p>Mesela indirdiğiniz bir uygulama kameranızı açmak istiyor diyelim. O an bir <strong>uyarı penceresi</strong> ile uygulamanın kameranıza erişmek istediği söyleniyor. İzin verirseniz kamera açılıyor, vermezseniz açılmıyor. İzin vermediğinizde uygulama tam olarak işlevini görmüyor fakat en azından hangi izne nerede ve niçin erişmek istediğini bilebiliyorsunuz ve tüm izinleri, 6.0&#8217;dan önceki gibi peşinen kabul etmemiş oluyorsunuz. 6.0 altındaki cihazlarda ise uygulama içinde izin pencereleri açılmaz. Uygulamayı indirirken verdiğiniz izinler <strong>uygulama boyunca</strong> kullanılır.</p>



<h3><strong>Android 6.0 İzin İşlemi &#8211; Örnek</strong></h3>



<p>Örnek üzerinde gösterelim. Örneğimizde butona tıklandığında kameranın açılmasını isteyelim. Cihazın API versiyonu 23 ve üzeriyse (Android 6.0&#8217;a denk gelir) izin istesin. Değilse, izinsiz doğrudan kamera açsın.</p>



<p><strong>AndroidManifest.xml</strong> dosyamıza ilk olarak kamera izni ekleyelim.</p>



<pre class="crayon-plain-tag">&lt;uses-permission android:name="android.permission.CAMERA" /></pre>



<p>Daha sonra <strong>activity_main.xml</strong> layout dosyasına bir <strong>buton </strong>ekleyelim.</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout 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"
    tools:context=".MainActivity">

    &lt;Button
        android:id="@+id/btnKameraAc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:text="Kamera Aç" />
    
&lt;/RelativeLayout></pre>



<p>Şimdi ise bu tasarıma bağlı olan <strong>MainActivity.java</strong> dosyasına gelerek, butonun <strong>click eventini</strong> dolduralım.</p>



<pre class="crayon-plain-tag">public class MainActivity extends AppCompatActivity {
    Button btnKameraAc;

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

        btnKameraAc = findViewById(R.id.btnKameraAc);
        btnKameraAc.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M
                if (Build.VERSION.SDK_INT &gt;= 23) {
                    String[] KAMERA_IZNI = {Manifest.permission.CAMERA};
                    if (!izinKontrol(MainActivity.this, KAMERA_IZNI)) { // izin verilmiş mi
                        requestPermissions(KAMERA_IZNI, 100); // verilmediyse, izin isteme penceresi a&ccedil;
                    } else
                        kameraAc(); // zaten izin verilmişse kamera a&ccedil;
                } else
                    kameraAc(); // api 6.0 altındaysa izne bakmadan doğrudan kamera a&ccedil;
            }
        });
    }
}</pre>



<p>Kamera açan bir uygulamanız var ve butona basıldığında ya da herhangi bir işlemden sonra doğrudan kamera açmak istiyorsunuz. Yukarıdaki gibi kontrol koymanız gerekiyor. Cihazın Android versiyonu 6.0 altında ise doğrudan kamera açılır. <strong>6.0 ve üzeri</strong> ise önce izin verilmiş mi bakılır. İzin verilmemişse izin istenir (16.satırdaki ünlem işaretine dikkat!!). Verilmişse yine doğrudan kamera açılır. </p>



<p>Burada <strong>izin isterken</strong> 100 değeri gönderdik. Aşağıdaki gibi bir izin penceresi açıldı. </p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin2.jpg"><img decoding="async" loading="lazy" width="640" height="152" src="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin2.jpg" alt="" class="wp-image-3076" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin2.jpg 640w, https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin2-300x71.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /></a></figure>



<p>Bu izin penceresinde bir seçeneğe tıklayacağız. Tıkladıktan sonra istek gönderirken verdiğimiz <strong>100 </strong>değeri ile yanıtımızı <strong>handle </strong>edeceğiz. Handle yani kontrol etmek için ise <strong>onRequestPermissionsResult </strong>metodu kullanılır. 100 yerine herhangi bir sayı veya sabit verilebilir.</p>



<pre class="crayon-plain-tag">@Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 100:
                if (grantResults.length &gt; 0) {
                    boolean kameraIzniVerildiMi = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    if (kameraIzniVerildiMi) {
                        kameraAc();
                    } else {
                        Toast.makeText(getApplicationContext(), &quot;İzin verilmediği i&ccedil;in kamera a&ccedil;ılamıyor&quot;, Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), &quot;İzin verilmediği i&ccedil;in kamera a&ccedil;ılamıyor&quot;, Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }</pre>



<p>Pencerede <strong>Reddet </strong>veya<strong> İzin Ver</strong> butonlarından birine tıklayınca <strong>onRequestPermissionsResult </strong> metodu çalışır. Metod içerisinde, önce kamera iznine ait olan <strong>100 </strong>değeri <strong>switch </strong>içerisine yazılır. İzin verildiyse yine <strong>kameraAc()</strong> metodu çağrılır. Verilmediyse ekrana uyarı mesajları verilir.</p>



<p class="has-text-color has-medium-font-size has-vivid-red-color">ÖNEMLİ!!!</p>



<p>Eğer bir sefer izin verirsek, 2.tıklamada artık <strong>requestPermissions() </strong>metodu çağrılmayacak doğrudan kamera açılacaktır. Çünkü izin verilmediyse izin isteği gönderiyorduk. İzin verildikten sonra kişi eğer huylanır da cihazın <strong>Ayarlar </strong>sekmesinden uygulama izinlerini <strong>manuel </strong>olarak iptal ederse, uygulamaya girip butona tıkladığında tekrar <strong>requestPermissions()</strong> metodu çağrılır. O yüzden her tıklamada izin verilmiş mi kontrolü yapılmalı yoksa uygulama hata vererek durur. </p>



<p>Aşağıdaki gibi kişinin manuel olarak izinleri kapatma ihtimali vardır.</p>



<figure class="wp-block-image"><a href="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin3.jpg"><img decoding="async" loading="lazy" width="640" height="189" src="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin3.jpg" alt="" class="wp-image-3081" srcset="https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin3.jpg 640w, https://www.mehmetkirazli.com/wp-content/uploads/2018/12/marshmallowizin3-300x89.jpg 300w" sizes="(max-width: 640px) 100vw, 640px" /></a></figure>



<p>Dikkat ettiyseniz değinmediğimiz bir metot var. O da <strong>izinKontrol()</strong> metodu. Bu metot şu işe yarar: </p>



<p>-Bu uygulama için istenilen izinler kullanıcı tarafından verilmiş mi ? </p>



<p>Bu metot, aynı anda <strong>birden fazla izin alacağımız durumlarda</strong> işimize yarayacaktır. Tek izin için de <strong>işimizi görür</strong>. Hemen o metodu da yazalım.</p>



<pre class="crayon-plain-tag">public static boolean izinKontrol(Context context, String... izinler) {
        if (context != null &amp;&amp; izinler != null) {
            for (String izin : izinler) {
                if (ActivityCompat.checkSelfPermission(context, izin) != PackageManager.PERMISSION_GRANTED)
                    return false;
            }
        }
        return true;
    }</pre>



<h3><strong>Aynı Ekranda 2.İzni İsteme</strong></h3>



<p>Örneğimizde 1 adet izin istedik. Şimdi ise aynı activity içinde 2.buton ekleyip, bu buton ile de <strong>cihazın konumunu</strong> alalım.</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout 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"
    tools:context=".MainActivity">

    &lt;Button
        android:id="@+id/btnKameraAc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:text="Kamera Aç" />

    &lt;Button
        android:id="@+id/btnKonumAl"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnKameraAc"
        android:text="Konum Al" />

&lt;/RelativeLayout></pre>



<p><strong>Manifest</strong> dosyamıza izinleri de ekleyelim.</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mkirazli.izinayarlari">

    &lt;uses-permission android:name="android.permission.CAMERA" />
    &lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    &lt;application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        &lt;activity android:name=".MainActivity">
            &lt;intent-filter>
                &lt;action android:name="android.intent.action.MAIN" />

                &lt;category android:name="android.intent.category.LAUNCHER" />
            &lt;/intent-filter>
        &lt;/activity>
    &lt;/application>

&lt;/manifest></pre>



<p><strong>MainActivity.java </strong>dosyasına, konum alma butonu için <strong>click eventi </strong>oluşturalım.</p>



<pre class="crayon-plain-tag">btnKonumAl = findViewById(R.id.btnKonumAl);
        btnKonumAl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M
                if (Build.VERSION.SDK_INT &gt;= 23) {
                    String[] KONUM_IZNI = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
                    if (!izinKontrol(MainActivity.this, KONUM_IZNI)) { // izin verilmiş mi
                        requestPermissions(KONUM_IZNI, 200); // verilmediyse, izin isteme penceresi a&ccedil;
                    } else
                        konumAl(); // zaten izin verilmişse konum al
                } else
                    konumAl(); // api 6.0 altındaysa izne bakmadan doğrudan konum al
            }
        });</pre>



<p>Cihazlarda 2 tür konum olduğu için 2 tür izin istemek zorundayız. İzin isterken bu defa 100 değil <strong>200 </strong>değeri gönderdik ve aşağıdaki <strong>onRequestPermissionsResult()</strong> metodunda da 200 için ayrı bir <strong>case </strong>oluşturarak, konum izni verildiğinde yapılacakları yazdık.</p>



<pre class="crayon-plain-tag">@Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 100:
                if (grantResults.length > 0) {
                    boolean kameraIzniVerildiMi = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    if (kameraIzniVerildiMi) {
                        kameraAc();
                    } else {
                        Toast.makeText(getApplicationContext(), "İzin verilmediği için devam edilemiyor", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "İzin verilmediği için devam edilemiyor", Toast.LENGTH_SHORT).show();
                }
                break;

            case 200:
                if (grantResults.length > 0) {
                    boolean konumIzniVerildiMi1 = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean konumIzniVerildiMi2 = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                    if (konumIzniVerildiMi1 &amp;&amp; konumIzniVerildiMi2) {
                        konumAl();
                    } else {
                        Toast.makeText(getApplicationContext(), "İzin verilmediği için konum alınamıyor", Toast.LENGTH_SHORT).show();
                        finish();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "İzin verilmediği için konum alınamıyor", Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
        }
    }</pre>



<p>Buradaki <strong>grantResults[0]</strong> ve <strong>grantResults[1]</strong> içerisinde, lokasyon için istediğimiz izinler vardır. İlkinde <strong><em>ACCESS_COARSE_LOCATION,</em>&nbsp;</strong>ikincisinde<em>&nbsp;</em>de<strong><em> ACCESS_FINE_LOCATION</em></strong> izni için bilgiler bulunmaktadır. Yani izin verildi mi bilgisi tutulur.</p>



<p>Sonuç olarak eğer izin gerektiren bir işlem yaptırmak istiyorsak, hem cihaz için <strong>API 23</strong> kontrolü yapmalıyız hem de izin verilmediyse izin penceresi açarak, seçilen seçeneğe göre aynı işlemleri orada da yapmalıyız. Yani her tıklamada ve izin penceresi açıldığı her durumda&#8230;</p>



<p>Son olarak şunu da söyleyelim. Android SDK&#8217;sı, <strong>tehlikeli</strong> bulduğu izinler için bu işlemi yapar. Yani bir <strong>internet </strong>ve <strong>bluetooth </strong>açma işlemi için <strong>API 23</strong> kontrolüne gerek yoktur. Sadece <strong>AndroidManifest.xml</strong> dosyasına izin eklenir ve kodda doğrudan işlem yapılır. Dosya okuma yazma, kamera açma, mikrofon açma, konum alma gibi işlemler için kullanıcıdan izin isteme <strong>mecburiyeti </strong>vardır. Bu yaptıklarımız da <strong>tehlikeli olan izinler</strong> içindir. </p>



<p>Tehlikeli ve normal izinlerin listesine <a href="https://developer.android.com/guide/topics/permissions/overview" target="_blank" rel="noreferrer noopener" aria-label="buradan  (yeni sekmede açılır)">buradan </a>ulaşabilirsiniz.</p>



<p class="has-text-color has-medium-font-size has-luminous-vivid-orange-color"><strong><a href="https://www.mehmetkirazli.com/KaynakKodlar/MarshmallowIzin.rar">KAYNAK KODLARI İNDİR</a></strong></p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-6-0-marshmallow-izin-ayarlari/">Android 6.0 (Marshmallow) İzin Ayarları &#8211; Runtime Permissions</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/android-6-0-marshmallow-izin-ayarlari/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Android Oreo (8.0) Resim Ekleme Sorununun Çözümü</title>
		<link>https://www.mehmetkirazli.com/android-oreo-8-0-resim-ekleme-sorunu/</link>
					<comments>https://www.mehmetkirazli.com/android-oreo-8-0-resim-ekleme-sorunu/#comments</comments>
		
		<dc:creator><![CDATA[Mehmet Kirazlı]]></dc:creator>
		<pubDate>Mon, 24 Dec 2018 07:45:16 +0000</pubDate>
				<category><![CDATA[Hata Çözümleri]]></category>
		<category><![CDATA[android api 26 kamera hatası]]></category>
		<category><![CDATA[android oreo resim ekleme sorunu]]></category>
		<category><![CDATA[exposed beyond app geturi]]></category>
		<guid isPermaLink="false">https://www.mehmetkirazli.com/?p=3058</guid>

					<description><![CDATA[<p>Merhaba. Hazırladığım bir uygulamada Android Oreo (8.0) ve üzeri cihazlarda kameradan ya da galeriden resim eklemeye çalışıldığında hata alındığını farkettim. API 26 ve üzerinde alınan hatanın çözümünü anlatacağım. Öncelikle hata alınan örnek bir kod bloğu gösterelim. [crayon-69b267179c747385273812/] Bu kod aşağıdaki gibi bir hata verecektir [crayon-69b267179c74d684268057/] Burada Uri.fromFile() metodu hata verecektir ve eğer Try-Catch mekanizmanız yoksa &#8230;</p>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-oreo-8-0-resim-ekleme-sorunu/">Android Oreo (8.0) Resim Ekleme Sorununun Çözümü</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Merhaba. Hazırladığım bir uygulamada Android Oreo (8.0) ve üzeri cihazlarda kameradan ya da galeriden resim eklemeye çalışıldığında hata alındığını farkettim. <strong>API 26</strong> ve üzerinde alınan hatanın çözümünü anlatacağım.</p>



<span id="more-3058"></span>



<p>Öncelikle hata alınan örnek bir kod bloğu gösterelim.</p>



<pre class="crayon-plain-tag">Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(),
      &quot;/DCIM/Camera/&quot; + timeStamp + &quot;.jpg&quot;);
SingletonClass.setimageUri(Uri.fromFile(photo));
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
Uri imageUri = Uri.fromFile(photo);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);</pre>



<p>Bu kod aşağıdaki gibi bir hata verecektir</p>



<pre class="crayon-plain-tag">android.os.FileUriExposedException: file:///storage/emulated/0/DCIM/Camera/beyan.jpg exposed beyond app through ClipData.Item.getUri()</pre>



<h2></h2>



<p>Burada <strong>Uri.fromFile()</strong> metodu hata verecektir ve eğer <strong>Try-Catch</strong> mekanizmanız yoksa resim eklerken uygulama durdurulacaktır.</p>



<p>Çözümü için ilk olarak <strong>6.satırı</strong> aşağıdaki gibi satırı güncelliyoruz.</p>



<pre class="crayon-plain-tag">Uri imageUri = FileProvider.getUriForFile(MyActivity.this, BuildConfig.APPLICATION_ID + &quot;.provider&quot;,photo);</pre>



<p>Daha sonra <strong>AndroidManifest </strong>dosyamızın en altına <strong>application </strong>etiketinden hemen önce şu satırları ekliyoruz.</p>



<pre class="crayon-plain-tag">&lt;provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    &lt;meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
&lt;/provider></pre>



<p>Daha sonra <strong>res </strong>klasörü altında <strong>xml </strong>adında bir klasör oluşturup bu klasörün içine de <strong>provider_paths</strong> adında bir <strong>xml </strong>dosyası oluşturarak içerisine şu kodları yazıyoruz.</p>



<pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?>
&lt;paths xmlns:android="http://schemas.android.com/apk/res/android">
&lt;external-path
    name="storage/emulated/0"
    path="." />
&lt;/paths></pre>



<p>Son olarak bu işlemleri yaptığınız class içerisineki <strong>setContentView() </strong>metodundan sonra aşağıdaki kodları yazıyoruz.</p>



<pre class="crayon-plain-tag">StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());</pre>
<p>The post <a rel="nofollow" href="https://www.mehmetkirazli.com/android-oreo-8-0-resim-ekleme-sorunu/">Android Oreo (8.0) Resim Ekleme Sorununun Çözümü</a> appeared first on <a rel="nofollow" href="https://www.mehmetkirazli.com">Mehmet Kirazlı</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.mehmetkirazli.com/android-oreo-8-0-resim-ekleme-sorunu/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
