YazılımDersi programlama dili blogudur.http://yazilimdersi.info/Farklı yazılım dilleri ile alakalı makale ve yazıların paylaşıldığı platformdur. Popüler programlama dillerinin kullanıldığı makaleler ve yazılar sunulmaktadırTue, 19 Mar 2024 07:30:50 +0000tr-TRhourly1http://wordpress.org/?v=3.5.1 Google Gemini ve ChatGPT: Yapay Zekada Yeni Rekabet http://yazilimdersi.info/makaleler/detay/140/google-gemini-ve-chatgpt-yapay-zekada-yeni-rekabet Wed, 06 Dec 2023 00:00:00 +0000 mstfchelik Yapay zeka, günümüzde teknoloji dünyasının en heyecan verici alanlarından biri haline geldi. Google, bu alanda yeni bir adım atarak Google Gemini adlı bir ürünü duyurduğunda, yapay zeka tabanlı sistemler arasında rekabetin daha da kızıştığı bir süreci başlattı. Ancak Google Gemini, benzer işlevlere sahip olan ChatGPT gibi mevcut yapay zeka sistemleriyle nasıl karşılaştırılabilir? İşte bu sorunun cevabını araştıralım.

Google Gemini: Yeni Bir Yapay Zeka Deneyimi

Google Gemini, Google'ın son teknoloji ürünü yapay zeka sistemi olarak karşımıza çıkıyor. Konuşma tabanlı yapay zeka alanında etkileyici bir ilerleme sunan bu sistem, kullanıcılarla etkileşim kurarak doğal dil anlayışını kullanıyor. Sesli asistanlar, metin tabanlı sohbetler ve daha birçok alanda Google Gemini'nin potansiyeli oldukça geniş.

Bu yeni ürün, gerçek zamanlı çeviri, sesli komutlar üzerinden işlem yapma, derin öğrenme tekniklerini kullanarak kişiselleştirilmiş deneyimler sunma gibi özelliklerle dikkat çekiyor. Ayrıca, Google'ın geniş veri havuzunu kullanarak daha hızlı ve doğru cevaplar üretebileceği konuşuluyor.

Google official hesabı üzerinden paylaşılan videoda Google CEO'su Sundar Pichai, "Gemini, sıfırdan modüler olacak şekilde programlandı; Bu, metin, kod, ses, görüntü ve video dahil olmak üzere farklı türdeki bilgileri genelleştirebileceği ve kusursuz bir şekilde anlayabileceği, bunlar üzerinde çalışabileceği ve birleştirebileceği anlamına geliyor." söyledi.

ChatGPT: Yapay Zeka Dünyasının Öncülerinden

Öte yandan, OpenAI tarafından geliştirilen ChatGPT, doğal dil işleme ve anlama konusunda öncü bir yapay zeka sistemidir. Çeşitli dil becerilerine sahip olan bu sistem, metin tabanlı etkileşimlerde insan benzeri cevaplar üretebilir. ChatGPT, geniş veri setlerine dayalı olarak esneklik ve çok yönlülük konusunda dikkat çeker.

 

chatgpt

 

ChatGPT'nin gücü, geniş bir dil yelpazesi ve derin öğrenme modelleriyle kullanıcıların çeşitli konularda etkileşimde bulunabilmesine olanak tanımasıdır. İnsan benzeri sohbetler, metin üretimi ve hatta bazı durumlarda yaratıcı içerik oluşturma yetenekleri, ChatGPT'nin benzersiz özellikleri arasında yer alır.

Google Gemini ve ChatGPT Karşılaştırması: Hangisi Daha İyi?

Google Gemini ve ChatGPT, yapay zeka alanında farklı yaklaşımlar sunar. Google Gemini, Google'ın geniş veri havuzundan faydalanarak hızlı ve gerçek zamanlı çözümler sunma potansiyeline sahiptir. Öte yandan, ChatGPT, dilin derinliklerine inerek daha esnek ve geniş bir dil yelpazesi sunar.

Hangi sistem daha iyi olduğu, kullanım senaryolarına ve beklentilere bağlı olarak değişebilir. Google Gemini, belirli işlevlerde hızlı çözümler sunarken, ChatGPT daha geniş bir dil yelpazesi ve esneklik sunabilir. İşlevsellik, kişiselleştirme ve günlük kullanım bağlamında tercihler değişebilir.

Sonuç: Yapay Zeka Rekabetinde Yolculuk Devam Ediyor

Google Gemini ve ChatGPT gibi yapay zeka sistemleri, teknoloji dünyasında devrim niteliğinde adımlar atıyor. Bu sistemler, doğal dil işleme ve anlama konusunda insan benzeri yetenekler sunarak gelecekteki teknoloji trendlerini şekillendirme potansiyeline sahip.

Hangi sistem tercih edilirse edilsin, yapay zeka teknolojilerinin gelişimi ve rekabeti, kullanıcılar için daha iyi ve daha akıllı bir gelecek vaat ediyor. Bu rekabet, daha yenilikçi ve kullanıcı odaklı yapay zeka sistemlerinin ortaya çıkmasına olanak tanıyarak, teknoloji dünyasında heyecan verici bir yolculuğun başlangıcını işaret ediyor.

]]>
Havalimanı Sorgulama http://yazilimdersi.info/makaleler/detay/139/havalimani-sorgulama Tue, 05 Sep 2023 00:00:00 +0000 mstfchelikIATA (International Air Transport Association) tüm dünyadan tarifeli havayolu taşıyıcılarının temsil edildiği ticari bir kuruluştur. IATA’nın esas amacı hem yolcular hem de havayolu şirketleri için havayolu taşımacılığının mümkün olan en yüksek hızda, emniyette, güvenlikte, uygunlukta ve verimlilikte gerçekleşmesini sağlamaktır. Temel olarak tarife koordinasyonu (bilet fiyatları, oranlar, ücretler ve seyahat acente komisyon oranları) ile ilgilenmektedir. Hem organizasyon olarak hem de faaliyetleri açısından IATA ile işbirliği halindedir.

Havalimanı işletmelerinin tümünün üyesi olduğu bu kuruluşlarda unique olarak atanmış havalimanı kodları bulunmaktadır. Bu kodlar sayesinde havalimanı firmaları kimliklerini edinmiş ve tüm dünyada geçerliliği kabul görmüş kodlar ile işlemler gerçekleştirmektedir. Hazırladığımız arayüz sayesinde herhangi bir havalimanı işletme adı ile arama yaparak havalimanı koduna rahatlıkla erişebilirsiniz.]]>
EADDRINUSE: address already in use sorununun çözümü http://yazilimdersi.info/makaleler/detay/138/eaddrinuse-address-already-in-use-sorununun-cozumu Sat, 25 Feb 2023 00:00:00 +0000 mstfchelik "EADDRINUSE: address already in use" hatası, bir sunucunun belirli bir portu dinlemeye çalıştığında ve bu portun zaten başka bir işlem tarafından kullanımda olduğu durumlarda ortaya çıkar. Bu hatanın nedeni, sunucunun belirli bir portu kullanmak için izin almaya çalışırken, o portun zaten başka bir işlem tarafından kullanımda olmasıdır. Daha çok nodejs, java ile hazırlanmış projelerde karşımıza çıkan bu hatalar aslında en basit şekliyle işletim sistemi restart edilerek çözülebilir. Ancak production olarak çalışan sunucularda bu tarz shutdown işlemleri kabul görmemektedir.

Bu makalemizde, "EADDRINUSE: address already in use" hatası ile karşılaştığınızda sorunu Windows, Linux ve Mac işletim sistemlerinde çalışan cihazlarda nasıl giderebileceğinizi paylaşacağız.

MAC ve Linux İşletim Sisteminde:
Aşağıda yazılı olan fonksiyonu kullanarak hatayı aldığınız portu kullanan diğer işleme ait PID ( Process ID) verisine ulaşabilirsiniz:
  1. lsof -i tcp:port_number
    

Komutta kullanılan "port_number" belirli bir port numarası olmalıdır. Bu komut, belirli bir portu kullanan işlemi görüntüler. Terminalde sorgulama sonrası aşağıdaki şekilde bir çıktı terminalde görüntülenecektir.

  1. COMMAND PID   USER  FD  TYPE DEVICE             SIZE/OFF NODE NAME 
    node    12345 chen5 31u IPv4 0x8b1721168764e4bf 0t0 TCP *:strexec-s (LISTEN)
    

Listelenen satırda PID altında görüntülenen numarayı "process_id" alanına yazıp komutu çalıştırınız.

  1. kill -9 process_id
    

İşlemin hızlı bir şekilde sorunsuz kill edileceğinden emin olmak için -9 komutunu kullanabilirsiniz. Örneğin, "sudo kill -9 1234" komutunu kullanarak 1234 kimlik numaralı bir işlemi sonlandırabilirsiniz.

Windows İşletim Sisteminde:
Aşağıda yazılı olan adımları takip ederek terminali açıp ilgili processi komut satırı üzerinden kill edebilirsiniz:
  1. netstat -ano | findstr :port_number
    

Komutta kullanılan "port_number" belirli bir port numarası olmalıdır. Bu komut, belirli bir portu kullanan işlemi görüntüler. Terminalde sorgulama sonrası aşağıdaki şekilde bir çıktı terminalde görüntülenecektir.

  1. Proto Local Address Foreign Address State PID 
    TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 11223
    

Listelenen satırda PID altında görüntülenen numarayı "process_id" alanına yazıp komutu çalıştırınız.

  1. taskkill /F /PID process_id
    

Yukarda tanımlı komutta /F parametresi ile taskın kill edilmesini force etmekteyiz. /PID komutu ile de kill işleminin process id ile gerçekleştirmek istediğimizi belirtmekteyiz.

Örneğin, "sudo kill -9 1234" komutunu kullanarak 1234 kimlik numaralı bir işlemi sonlandırabilirsiniz.

Eğer Windows işletim sisteminde komut satırı üzerinden işlem yapmayı pek tercih etmiyorsanız aşağıda Görev Yöneticisi üzerinden de ilgili portun kill edilmesini sağlayabilirsiniz. Bunun için cihazınızda Görev Yöneticisini açmanız ve listelenen tasklarda size ait olanı bulup sağa tıklayıp Taskı Durdur seçeneğini seçmenizdir. 

]]>
Node.js ile date kullanımı http://yazilimdersi.info/makaleler/detay/137/nodejs-ile-date-kullanimi Tue, 22 Aug 2023 00:00:00 +0000 mstfchelik Node.js, JavaScript dilini kullanarak yazılmış bir açık kaynaklı platformdur. Web geliştirme alanında yaygın olarak kullanılan Node.js, aynı zamanda zaman ve tarih işlemleri gibi birçok farklı amaç için de kullanılabilir. Bu makalede, Node.js kullanarak Date nesnesini kullanmanın temellerini ve çeşitli tarih işlemlerini öğreneceksiniz.

Date Nedir?

JavaScript dilinde, tarih ve saat işlemleri için kullanılan Date nesnesi bulunur. Bu nesne, tarih ve saat bilgisini temsil eder ve bir dizi yöntem sunar, böylece tarihleri ve saatleri işleyebilirsiniz.

Date Nesnesi Oluşturma

Date nesnesi oluştururken iki farklı yol vardır. İlk olarak, şu anki tarih ve saati almak için kullanabilirsiniz:

var now = new Date(); 
console.log(now);

Bu kod, Date nesnesini kullanarak geçerli zamanı ve tarihi alır ve ekrana yazdırır.

İkinci olarak, belirli bir tarih ve saat için Date nesnesi oluşturabilirsiniz:

var customDate = new Date(2022, 11, 13, 10, 30, 0); // 13 Aralık 2022, saat 10:30 
console.log(customDate);

Temel Date Yöntemleri

Date nesnesi, tarih ve saat bilgisini almak ve işlemek için birçok yöntem sunar. İşte bazı temel yöntemler:

  • getFullYear(): Tarihin yıl bilgisini döndürür.
  • getMonth(): Tarihin ay bilgisini döndürür (0-11 arasında bir değer, 0 Ocak, 1 Şubat vb.).
  • getDate(): Tarihin ayın kaçıncı günü olduğunu döndürür.
  • getDay(): Tarihin haftanın kaçıncı günü olduğunu döndürür (0 Pazar, 1 Pazartesi vb.).
  • getHours(): Tarihin saat bilgisini döndürür.
  • getMinutes(): Tarihin dakika bilgisini döndürür.
  • getSeconds(): Tarihin saniye bilgisini döndürür.

Örnek olarak:

console.log(customDate.getFullYear()); // 2022
console.log(customDate.getMonth());    // 11
console.log(customDate.getDate());     // 13
console.log(customDate.getHours());    // 10
console.log(customDate.getMinutes());  // 30
console.log(customDate.getSeconds());  // 0

Tarih İşlemleri

Date nesnesi ayrıca tarih işlemleri yapmanıza olanak tanır. İki tarih arasındaki farkı hesaplamak veya tarihleri karşılaştırmak gibi işlemler yapabilirsiniz.

Örnek olarak, iki tarih arasındaki farkı hesaplama:

var startDate = new Date(2023, 0, 1);
var endDate = new Date(2023, 7, 1);
var timeDifference = endDate - startDate;

console.log(timeDifference / (1000 * 60 * 60 * 24)); // Gün cinsinden fark

Bu örnekte, iki tarih arasındaki gün farkını hesaplıyoruz.

Sonuç

Node.js kullanarak Date nesnesi, tarih ve saat işlemleri için güçlü bir araçtır. Bu makalede temel kullanımı ve temel yöntemleri öğrendiniz. Daha fazla bilgi ve örnekler için JavaScript belgelerine başvurabilirsiniz. Tarih ve saat işlemleri ile ilgili daha karmaşık senaryolar için bu temel bilgi size iyi bir başlangıç ​​noktası sağlayacaktır.

]]>
Facebook, şirket adını Meta olarak değiştiriyor http://yazilimdersi.info/makaleler/detay/135/facebook-sirket-adini-meta-olarak-degistiriyor Fri, 29 Oct 2021 00:00:00 +0000 mstfchelik Mark Zuckerberg, şirketin yıllık geliştirici konferansına ait açılış konuşmasında, "Bundan sonra Facebook değil, Metaverse olarak yolumuza devam edeceğiz" dedi. "İnsanların Meta markasını ve temsil edeceğimiz geleceği tanımasını umuyorum." şeklinde bir açıklamada bulundu.

Zuckerberg, şirketin geleceğinin, kullanıcıları farklı bir ortam aracılığıyla birbirine bağlayan sanal gerçeklik ürünleri oluşturmaya odaklanacağını söyledi. Önümüzdeki on yıl içerisinde bir milyar insanın Metaverse olarak adlandırdıkları sanal dünyaya dahil olacağını dile getirdi.

Şirket, Metaverse platformunu kullanıcıların kendilerini temsil eden avatarlar oluşturabilecekleri üç boyutlu bir sanal alan olarak tanımlıyor. Zuckerberg, yeni sanal gerçeklik dünyasının kullanıcıların oturma odalarından çıkmadan video oyunları oynamasına, film izlemesine, konserlere katılmasına, meslektaşlarıyla işbirliği yapmasına ve arkadaşlarıyla bir araya gelmesine olanak sağlayacağını söyledi.

Facebook Meta

Zuckerberg, 2004 yılında üniversitenin yurt odasından başlattığı Facebook'u "ikonik bir sosyal medya şirketi" olarak adlandırmıştı, ancak bu adın artık şirketin vizyonuna "yeterli olmadığını" da sözlerine ekledi.

Şirket ayrıca 1 Aralık'tan itibaren FB olan hisse senedini MVRS olarak değiştiriyor.

Hatırlarsanız Facebook uzun süredir sahibi olduğu sosyal medya uygulamalarındaki kullanıcılara sağladığı koruma eksikliği nedeniyle eleştirilerle karşı karşıya. Bu ayın başlarında, eski Facebook çalışanı Frances Haugen, şirket yöneticilerinin platformun yıllardır yanlış bilgilerin yayılmasına yardımcı olduğunu bildiklerini ancak olumsuz etkilerle mücadele etmek için yeterli çabayı göstermediğini gösteren binlerce belgeyi sızdırdıktan sonra kamuoyuna açıklama yaptı. Zuckerberg Perşembe günü yaptığı açıklamada, "gizlilik" ve "güvenlik" kontrollerinin ilk günden itibaren Metaverse'e yerleştirilmesi gerektiğini söyledi.

]]>
Nginx Nedir? Ne işe yarar? http://yazilimdersi.info/makaleler/detay/131/nginx-nedir-ne-ise-yarar Thu, 01 Apr 2021 00:00:00 +0000 mstfchelik "Engine-ex" olarak da adlandırılan Nginx, dünya çapında önemli trafikler alan sitelerin çalıştığı açık kaynak kodlu websunucusudur. Aslında ilk olarak web sunucusu hizmeti verirken şu anda reverse proxy, cache ve load balancer gibi farklı konulara da çözümler sunmaktadır.

Yüksek trafiğe sahip olan şirketlerden kastımız Microsoft, IBM, Google, Adobe, Atlassian, T-Mobile, GitLab, DuckDuckGo, Salesforce, LinkedIn, Cisco, Facebook, Target, Twitter, Apple, Intel vb. firmalara ait sistemler ve sitelerdir. Aslında Nginx'in hikayesi Ekim 2014 tarihinde Igor Sysoev un cıktıgı ilk release dayanıyor. Igor, mevcut web sunucularında 10K ve üzeri paralel işlemlerde performans problemi ile karşılaşıldığını gözlemledi ve bunun çözümüne yönelik Nginx isimli sistemi hayata geçirdi. Tamamen açık kaynak olarak hazırlanan sistem şu anda dünyada en popüler web sunucuları listesinde ilk sıralarda.

Nginx Nasıl Çalışır?

Nginx, düşük bellek kullanımı ile birlikte paralel işlemlerin sorunsuz şekilde çalışmasına yönelik bir yapı üzerine kurulmuştur. Web sunucuya gelen tüm requestlerde yeni bir process açmak yerine tek process üzerinden tüm işlemlerin paralel şekilde yürütülmesini hedeflemiş ve bu kurguda çalışmaktadır. Nginx sunucularında, bir ana process birden çok çalışan processi kontrol edebilmektedir. Nginx üzerinden bulunan herhangi bir istek, diğer istekleri engellemeden çalışan processler tarafından eşzamanlı olarak yürütülebilir.

Nginx üzerinde kullanılan önemli özellikler şunlardır;

  • IPv6
  • Cacheleme ile reverse proxy
  • Load balancing
  • FastCGI destekli cacheleme sistemi
  • WebSocketler

Nginx vs Apache Karşılaştırması

Apache, Nginx gibi tamamen açık kaynak kodlu popüler websunuculardan diğeridir. Hatta rakamlar karşılaştırıldığında Apache, %43,6 kullanım oranıyla Nginx'den daha fazla kullanılmaktadır. Nginx içinse oran %41.9 olarak tespit edilmiştir ancak her geçen yıl kullanım oranı Nginx yönünde artmaktadır.

Kullanım oranı olarak Apache önde gözüküyor olsa bile en fazla trafik olan sistemler karşılaştırıldığında Nginx in kullanım oranı daha fazladır. Yani popüler sistemlere ait sunuculara gelen trafiklerde Nginx tabanlı sunucular tercih edilmektedir. Netflix, NASA, Wordpress gibi popüler sistemlerde de Nginx tercih edilmektedir.

Nginx vs Apache

Websitesinin Apache'de mi yoksa Nginx'de mi çalıştığını nasıl anlarız?

Websitelerinde hangi websunucunun çalıştığını tespit etmek amacıyla server isimli HTTP Header mesajını gözlemlemeniz yeterli olacaktır. Bu mesajı gözlemlemek için Google Chrome uygulamasında Developer Tools alanına tıklayıp Network sekmesini açınız. Sonrasında F5 tuşuna basıp sayfayı yenilediğinizde websitesine ait header mesajlarının network alanında listelendiğini gözlemleyebilirsiniz.

Http Header

Yukarıdaki resimde yazilimdersi.info sitemizin çalıstığı websunucunun Apache olduğunu görebilirsiniz. Aynı şekilde facebook.com, google.com gibi farklı popüler sitelerinde sunucu bilgilerine bu yöntemle ulaşabilirsiniz. Ancak unutmamanız gereken konu bu bilgiler her zaman açık olarak paylaşılmamaktadır. Eğer sunuculardan sorumlu ekip, websitelerinde header bilgisi olarak sunucunun paylaşılmasını engellemek isterse, ilgili sunucu üzerinde bu bilgiyi saklayabilir.

]]>
Android Login-Register Ekran Yapımı (PHP, MySQL ve SQLite kullanarak) http://yazilimdersi.info/makaleler/detay/130/android-login-register-ekran-yapimi-(php-mysql-ve-sqlite-kullanarak) Sat, 30 Jan 2021 00:00:00 +0000 mstfchelik Android uygulamalarda önemli bir yere sahip olan login ve register ekranları birçok projelerde kullanılmaktadır. Projelerde önemli bir yere sahip olan bu yapıları bir kere kurguladığınız takdirde farklı farklı birçok projede gerçekleştirebilirsiniz. Makalemizde register sonrasında tutulacak olan kayıtlara ait verileri PHP ve MySQL kullanarak kayıt altına alacağız. Bunu gerçekleştirirken RESTful API yapısını kullanacağız. Mobil arayüz ile etkileşimi sağlamak amacıylada Android uygulamamızda SQLite sistemini kurgulayacağız.

Daha önce sizlerle paylaştığımız "Android'de örnek login ve registration sayfası dizaynı" başlıklı makalemizde uygulama arayüzünün nasıl oluşturulduğunu sizlerle paylaşmıştık. Bu makalemizde arayüzü sadece design olarak degil, fonksiyonel hale getirmeye başlayacağız.

API (Application Programming Interface)

Mobil uygulama ile veri alışverişini sorunsuz şekilde gerçekleştirmek, gelen verilerin MySQL veritabanına kaydedilmesini sağlamak amacıyla Rest API kurgusunu hazırlamamız gerekecektir. API, bu tip verilerin karşılıklı aktığı sistemlerde mobil uygulama ile sunucu arasında ortak bir protokol olarak da isimlendirilebilir. Biz bu makalede PHP ve MySQL kullanarak bu işlemi gerçekleştireceğiz. Eğer siz Nodejs veya Ruby konusunda daha yetkinseniz bunları da kullanmanızda herhangi bir mahsur yoktur. Hazırlayacağımız API yapacağı işlemler şu şekildedir;

  • GET/POST metodları üzerinden API çağrılarının alınması
  • Veritabanına yeni kullanıcı kaydının oluşturulması
  • Veritabanında kayıtlı olan kullanıcının bilgilerinin çekilmesi
  • API cevaplarının JSON formatta iletilmesi

WAMPServer Kurulumu

Öncelikle server tarafının çalışacağı webserverin belirlenmesi ve kurulması gerekmektedir. Projemizde pratik ve hızlı bir çözüm sunacağını düşündüğümüz WampServer'i tercih edeceğiz. Wampserver kurulumu ile birlikte Apache, PHP ve MySQL kurulumlarını tek seferde gerçekleştirmiş oluyoruz. Wampserver kurulumu için www.wampserver.com/en/ linkine tıklayınız. Programı indirip kurulumu gerçekleştirdikten sonra Start ⇒ All Programs ⇒ WampServer ⇒ StartWampServer seçeneğinden Wampserveri başlatabilirsiniz. Eğer MAC bilgisayarınız varsa WAMP yerine MAMP Server kurulumunu gerçekleştirebilirsiniz. MAMP Servere erişmek için https://www.mamp.info/en/downloads/ linkine tıklayınız.

Artık projenin sunucu tarafını http://localhost üzerinden test edebilirsiniz. Veritabanına erişim içinse http://localhost/phpmyadmin linkinden yararlanabilirsiniz.

Veritabanı İşlemleri

WAMPServer kurulumu sonrasında artık MySQL veritabanına erişimi kolaylıkla gerçekleştirebiliriz. Burada http://localhost/phpmyadmin linki üzerinden veritabanına erişim sağlayabilirsiniz. Öncelikle ornek_proje adında bir veritabanı oluşturalım. Sonrasında da bu veritabanına içerisinde kullanicilar adında bir tablo oluşturalım.

CREATE DATABASE ornek_proje
USE ornek_proje
 
CREATE TABLE kullanicilar(
   id int(11) primary key auto_increment,
   unique_id varchar(23) not null unique,
   name varchar(50) not null,
   email varchar(100) not null unique,
   encrypted_password varchar(80) not null,
   salt varchar(10) not null,
   created_at datetime,
   updated_at datetime null
);

PHP Projesi

MYSQL üzerinde veritabanı ve tabloları oluşturduktan sonra PHP dili kullanılarak API kısmının yazılmasında sıra. Burada öncelikle WAMPServeri kurduğunuz dizine gidip www dizini altında ornek_proje baslıgında bir dizin oluşturun. Bu dizin içerisine API yi hazırlarken kullanacağınız PHP kodlamalarını yerleştireceğiz. Projeye ait klasör yapısı aşağıdaki şekilde olacaktır.

Projede kullanılan PHP sınıfları;

config.php: Veritabanına bağlantısında kullanılacak config bilgilerin setlendiği sınıf.

db_connect.php: Veritabanı bağlantısının sağlandığı sınıf.

db_functions.php: Veritabanı üzerinde gerçekleştirilecek olan işlemlerde kullanılan sınıf.

login.php: Android uygulamadan login olmaya çalışılırken kullanılan sınıf.

register.php: Android uygulamadan register olmaya çalışırken kullanılan sınıf.

Projede config.php dosyasının içerisine aşağıdaki kodlamayı yapıştıralım.

<?php
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "rootsifre");
define("DB_DATABASE", "ornek_proje");
?>

Bu dosyada DB_USER ve DB_PASSWORD alanlarının karşısına veritabanını oluştururken kullandığınız kullanıcı adı ve şifre bilgilerini yerleştiriniz.

Sonrasında db_connect.php dosyasının içerisine aşağıdaki kodlamayı yapıştıralım.

<?php
class db_connect {
    private $conn;
 
    public function connect() {
        require_once 'include/config.php';
         
        $this-?>conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
         
        return $this-?>conn;
    }
}
?>

Şimdi veritabanı işlemlerini gerçekleştireğimiz db_functions.php dosyasını oluşturup içerisine aşağıdaki kodlamaları yapıştıralım. Bu sınıf içerisinde tanımlanan fonksiyonlar; yeni kullanıcı oluşturulması veya mevcut olan kullanıcıların veritabanından getirilmesinde kullanılacaktır. Sınıf içerisinde tanımlanan uniqid('', true) metodu ile her kullanıcıya uniq bir id tanımlanması hedeflenmektedir. base64_encode metodu ile de kullanıcı şifresinin hashlenmesi sağlanmaktadır. Burada güvenliği üst seviyede tutmak adına salt verisi ve hashlenmiş şifrelerin veritabanında tutulması sağlanmaktadır.

<?php

class db_functions {
 
    private $conn;
 
    function __construct() {
        require_once 'db_connect.php';
        $db = new db_connect();
        $this->conn = $db->connect();
    }
 
    function __destruct() {
         
    }
 
    public function storeUser($name, $email, $password) {
        $uuid = uniqid('', true);
        $hash = $this->hashSSHA($password);
        $encrypted_password = $hash["encrypted"];
        $salt = $hash["salt"];
 
        $stmt = $this->conn->prepare("INSERT INTO kullanicilar(unique_id, name, email, encrypted_password, salt, created_at) VALUES(?, ?, ?, ?, ?, NOW())");
        $stmt->bind_param("sssss", $uuid, $name, $email, $encrypted_password, $salt);
        $result = $stmt->execute();
        $stmt->close();
 
        if ($result) {
            $stmt = $this->conn->prepare("SELECT * FROM kullanicilar WHERE email = ?");
            $stmt->bind_param("s", $email);
            $stmt->execute();
            $user = $stmt->get_result()->fetch_assoc();
            $stmt->close();
 
            return $user;
        } else {
            return false;
        }
    }

    public function getUserByEmailAndPassword($email, $password) {
 
        $stmt = $this->conn->prepare("SELECT * FROM kullanicilar WHERE email = ?");
 
        $stmt->bind_param("s", $email);
 
        if ($stmt->execute()) {
            $user = $stmt->get_result()->fetch_assoc();
            $stmt->close();
 
            $salt = $user['salt'];
            $encrypted_password = $user['encrypted_password'];
            $hash = $this->checkhashSSHA($salt, $password);
            if ($encrypted_password == $hash) {
                return $user;
            }
        } else {
            return NULL;
        }
    }
 
    public function isUserExisted($email) {
        $stmt = $this->conn->prepare("SELECT email from kullanicilar WHERE email = ?");
 
        $stmt->bind_param("s", $email);
 
        $stmt->execute();
 
        $stmt->store_result();
 
        if ($stmt->num_rows > 0) {
            $stmt->close();
            return true;
        } else {
            $stmt->close();
            return false;
        }
    }
 
    public function hashSSHA($password) {
        $salt = sha1(rand());
        $salt = substr($salt, 0, 10);
        $encrypted = base64_encode(sha1($password . $salt, true) . $salt);
        $hash = array("salt" => $salt, "encrypted" => $encrypted);
        return $hash;
    }
 
    public function checkhashSSHA($salt, $password) {
        $hash = base64_encode(sha1($password . $salt, true) . $salt);
        return $hash;
    }
 
}


?>

Yeni Kullanıcı Kaydı

Yukarıda tanımladığımız Php sınıfı ile birlikte artık ihtiyacımız olan tüm yapılar hazır durumdadır. Şimdi birlikte yeni kullanıcı kaydı oluşturacak sınıfı yazalım. Kullanıcı kaydında name, email ve password gibi alanları kullanarak sistemimizi hazırlayalım. Bu veriler Android uygulamamız üzerinden POST metodu ile iletilecektir.

Şimdi Php projemizin olduğu dizinde register.php isminde dosya oluşturup aşağıdaki kodlamayı içerisine yapıştıralım.

<?php

require_once 'include/db_functions.php';
$db = new db_functions();
 
$response = array("error" => FALSE);
 
if (isset($_POST['name']) && isset($_POST['email']) && isset($_POST['password'])) {
 
    $name = $_POST['name'];
    $email = $_POST['email'];
    $password = $_POST['password'];
 
    // kullanıcı sistemde kayıtlı bir email ile hesap oluşturuyormu?
    if ($db->isUserExisted($email)) {
        // kullanıcı sistemde kayıtlı ise
        $response["error"] = TRUE;
        $response["error_msg"] = $email. " maili ile ilişkili bir hesap sistemde bulunmaktadır";
        echo json_encode($response);
    } else {
        // yeni kullanıcı oluşturalım
        $user = $db->storeUser($name, $email, $password);
        if ($user) {
            // kullanıcı başarılı şekilde kayıt edildi
            $response["error"] = FALSE;
            $response["uid"] = $user["unique_id"];
            $response["user"]["name"] = $user["name"];
            $response["user"]["email"] = $user["email"];
            $response["user"]["created_at"] = $user["created_at"];
            $response["user"]["updated_at"] = $user["updated_at"];
            echo json_encode($response);
        } else {
            // kullanıcı sisteme kayıt edilemedi
            $response["error"] = TRUE;
            $response["error_msg"] = "Hesap oluşturulurken bilinmedik bir sorun ile karşılaşıldı!";
            echo json_encode($response);
        }
    }
} else {
    $response["error"] = TRUE;
    $response["error_msg"] = "Lütfen zorunlu parametreleri(name, email ve password) eksiksiz girin!";
    echo json_encode($response);
}

?>

Başarılı Kullanıcı Kaydında API den dönecek cevap şu şekilde olacaktır;


{
  "error": false,
  "uid": "44fa7220a2c187.2191519",
  "user": {
    "name": "Yazılım Dersi",
    "email": "[email protected]",
    "created_at": "2021-03-28 15:26:26",
    "updated_at": null
  }
}

Kullanıcı Kaydında sorun yaşandığında API den dönecek cevap şu şekilde olacaktır;


{
    "error": 1,
    "error_msg": "Hesap oluşturulurken bilinmedik bir sorun ile karşılaşıldı!"
}

Kayıtlı kullanıcı kaydında API den dönecek cevap şu şekilde olacaktır;


{
  "success": 0,
  "error": 2,
  "error_msg": "[email protected] maili ile ilişkili bir hesap sistemde bulunmaktadır"
}

Kullanıcı Hesap Girişi

Register işleminin ardından sistemde kayıtlı olan kullanıcıların kontrol edilmesi için Login yani Giriş yapısının kurgulanması gerekecektir. Burada genel olarak kullanılan email ve password ile kullanıcı kontrolünün gerçekleştirilmesidir. İletilecek parametreler POST metodu ile Android uygulama üzerinden iletilecektir. Yapacağımız kontrolde eğer email ve password bilgileri uyuşan herhangi bir kayıt olursa bununla alakalı başarılı sistem cevabını API üzerinden sunacağız. Eğer kayıtlı herhangi bir kullanıcı ile eşleşmiyorsa, o zamanda fail olan mesajımızı API üzerinden ileteceğiz.

Şimdi Php projemizin olduğu dizinde login.php isminde dosya oluşturup aşağıdaki kodlamayı içerisine yapıştıralım.

<?php

require_once 'include/db_functions.php';
$db = new db_functions();
$response = array("error" => FALSE);
 
if (isset($_POST['email']) && isset($_POST['password'])) {
 
    // parametreler
    $email = $_POST['email'];
    $password = $_POST['password'];
 
    // email ve password bilgilerinin kontrol edilmesi
    $user = $db->getUserByEmailAndPassword($email, $password);
 
    if ($user != false) {
        // kullanıcı bulundu
        $response["error"] = FALSE;
        $response["uid"] = $user["unique_id"];
        $response["user"]["name"] = $user["name"];
        $response["user"]["email"] = $user["email"];
        $response["user"]["created_at"] = $user["created_at"];
        $response["user"]["updated_at"] = $user["updated_at"];
        echo json_encode($response);
    } else {
        // bu bilgilerle uyumlu kullanıcı bulunamadı
        $response["error"] = TRUE;
        $response["error_msg"] = "Kullanıcı bilgileri yanlıştır. Lütfen daha sonra tekrar deneyin!";
        echo json_encode($response);
    }
} else {
    // zorunlu parametreleri iletiniz
    $response["error"] = TRUE;
    $response["error_msg"] = "Lütfen zorunlu parametreleri(email ve password) eksiksiz girin!";
    echo json_encode($response);
}
 
?>

Başarılı Kullanıcı Giriş Kontrolünde API den dönecek cevap şu şekilde olacaktır;


{
  "error": false,
  "uid": "44fa7220a2c187.2191519",
  "user": {
    "name": "Yazılım Dersi",
    "email": "[email protected]",
    "created_at": "2021-03-28 15:26:26",
    "updated_at": null
  }
}

Başarısız kullanıcı kontrolünde API den dönecek cevap şu şekilde olacaktır;


{
  "tag": "login",
  "success": 0,
  "error": 1,
  "error_msg": "Kullanıcı bilgileri yanlıştır. Lütfen daha sonra tekrar deneyin!"
}

Şu ana kadar yapılan çalışma ile API kısmındaki düzenlemeler tamamlandı. Şimdi Android uygulamasını yazmaya başlayalım.

Android Uygulaması

Yapacağımız örnek projede json formatta response dönen API çağrısından ( Yukarıda adım adım paylaşılan API) veriyi parse edip login ve register kavramlarını uygulayacağız.

1. File => New Project seçeneğine tıklayalım. Sonrasında açılan ekranda Empty Activity seçeneğini seçip Next butonuna tıklayalım. 
2. Bir sonraki ekranda uygulamanın ismini, paket adını ve kayıt edileceği dizini belirleyelim. İsterseniz uygulamanın adını SampleApp, paket ismi olarak ise info.yazilimdersi.sampleapp olarak belirleyelim.
3. Bu işlemler sonrasında projemiz oluşturuldu. Şimdi sırada projemize ait genel klasörleme ve sınıf yapısının nasıl oluşturacağımız konusunda.
Yukarıda projemize ait ana yapıyı gözlemleyebilirsiniz. Bu sınıfları şimdilik içi boş olacak şekilde oluşturalım. Adım adım içlerine konulacak kodları aşağıda sizlerle paylaşacağız.
4. app dizini altında bulunan build.gradle dosyasını açıp Material Design, Volley ve AppCompat kütüphanelerini ekleyelim.
dependencies {
    .........

    // volley kütüphanesini ekleyelim
    implementation 'com.mcxiaoke.volley:library-aar:1.0.0'
    
    // appcompat ve material kütüphanelerini ekleyelim
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.4.0-alpha01'
}

5. Projemizde internet üzerinden API çağrısı yapılacağı için AndroidManifest.xml dosyasında INTERNET iznini almamız gerekmektedir kullanıcıdan. Ayrıca hazırlanan activitylerin manifest dosyası içerisinde aşağıdaki şekilde tanımlanması gerekecektir.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.yazilimdersi.sampleapp">

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

    <application
        android:name="info.yazilimdersi.sampleapp.core.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">
        <activity
            android:name=".LoginActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:windowSoftInputMode="adjustPan">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".RegisterActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:windowSoftInputMode="adjustPan" />
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop" />
    </application>

</manifest>

6. Projede tanımlanan labelleri strings.xml dosyası içerisinde tanımlayalım.
<?xml version="1.0" encoding="utf-8"?>
<resources>
 
    <string name="app_name">Android Uygulama</string>
    <string name="hint_email">Email</string>
    <string name="hint_password">Şifre</string>
    <string name="hint_name">İsim</string>
    <string name="btn_login">GİRİŞ</string>
    <string name="btn_register">HESAP OLUŞTUR</string>
    <string name="btn_link_to_register">Üye değilmisiniz? Hesap oluşturun.</string>
    <string name="btn_link_to_login">Hesabınız bulunmaktamı? Giriş Yapın.</string>
    <string name="welcome">Merhaba</string>
    <string name="btn_logout">ÇIKIŞ</string>
    <string name="name">İsim</string>
 
</resources>

7. Projede tanımlanan renkleri colors.xml dosyası içerisinde tanımlayalım.
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <color name="bg_login">#26ae90</color>
    <color name="bg_register">#2e3237</color>
    <color name="bg_main">#428bca</color>
    <color name="white">#ffffff</color>
    <color name="input_login">#222222</color>
    <color name="input_login_hint">#999999</color>
    <color name="input_register">#888888</color>
    <color name="input_register_bg">#3b4148</color>
    <color name="input_register_hint">#5e6266</color>
    <color name="btn_login">#26ae90</color>
    <color name="btn_login_bg">#eceef1</color>
    <color name="lbl_name">#333333</color>
    <color name="btn_logut_bg">#ff6861</color>

</resources>
8. Projede app=>core dizini altında AppConfig.java dosyası oluşturup aşağıdaki kodlamayı içerisinde tanımlayalım.
public class AppConfig {
    public static String URL_LOGIN = "http://192.168.1.3/api/login.php";

    public static String URL_REGISTER = "http://192.168.1.3/api/register.php";
}
9. Projede app=>core dizini altında AppController.java dosyası oluşturup aşağıdaki kodlamayı içerisinde tanımlayalım. Bu dosya Application sınıfını extend edip uygulamada tanımlanması gereken genel ayarları belirlemede kullanılacaktır.
import android.app.Application;
import android.text.TextUtils;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
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;

    @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;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}
10. Projemizde login olan kullanıcının olup olmadığını belirlemek adına hazırlanan SessionManager.java sınıfını aşağıdaki şekilde dolduralım. Hazırlanan sınıf sayesinde daha önceden herhangi bir kullanıcının login olup olmadığı SharedPreferences üzerinden kontrol edilip hazırladığımız fonksiyonlarla check edilecektir.
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;

public class SessionManager {
    private static String TAG = SessionManager.class.getSimpleName();
    SharedPreferences pref;
    Editor editor;
    Context _context;
    int PRIVATE_MODE = 0;

    private static final String PREF_NAME = "AndroidApp";

    private static final String KEY_IS_LOGGEDIN = "isLoggedIn";

    public SessionManager(Context context) {
        this._context = context;
        pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
        editor = pref.edit();
    }

    public void setLogin(boolean isLoggedIn) {
        editor.putBoolean(KEY_IS_LOGGEDIN, isLoggedIn);
        editor.commit();
        Log.d(TAG, "Kullanıcı sisteme giriş yaptı!");
    }

    public boolean isLoggedIn(){
        return pref.getBoolean(KEY_IS_LOGGEDIN, false);
    }
}
11. Projemizde login olan kullanıcı bilgilerinin telefonda tutulması adına hazırlanan SQLiteHandler.java sınıfını aşağıdaki şekilde hazırlayalım. Hazırlanan sınıf sayesinde login olan kullanıcının bilgilerinin SQLiteOpenHelper üzerinden kayıt altına alınması sağlanacaktır.
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.HashMap;

public class SQLiteHandler extends SQLiteOpenHelper {

    private static final String TAG = SQLiteHandler.class.getSimpleName();
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "androidapp";

    private static final String TABLE_USER = "user";

    private static final String KEY_ID = "id";
    private static final String KEY_NAME = "name";
    private static final String KEY_EMAIL = "email";
    private static final String KEY_UID = "uid";
    private static final String KEY_CREATED_AT = "created_at";

    public SQLiteHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_USER + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
                + KEY_EMAIL + " TEXT UNIQUE," + KEY_UID + " TEXT,"
                + KEY_CREATED_AT + " TEXT" + ")";
        db.execSQL(CREATE_LOGIN_TABLE);

        Log.d(TAG, "Veritabanı oluşturuldu");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER);
        onCreate(db);
    }

    /**
     * login olan kullanıcı bilgisinin kayıt altına alınması
     * */
    public void addUser(String name, String email, String uid, String created_at) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, name); // isim
        values.put(KEY_EMAIL, email); // email
        values.put(KEY_UID, uid); // email
        values.put(KEY_CREATED_AT, created_at); // oluşturulduğu tarih

        long id = db.insert(TABLE_USER, null, values);
        db.close();

        Log.d(TAG, "New user inserted into sqlite: " + id);
    }

    /**
     * veritabanından kullanıcı bilgilerinin getirilmesi
     * */
    public HashMap<String, String> getUserDetails() {
        HashMap<String, String> user = new HashMap<String, String>();
        String selectQuery = "SELECT  * FROM " + TABLE_USER;

        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        cursor.moveToFirst();
        if (cursor.getCount() > 0) {
            user.put("name", cursor.getString(1));
            user.put("email", cursor.getString(2));
            user.put("uid", cursor.getString(3));
            user.put("created_at", cursor.getString(4));
        }
        cursor.close();
        db.close();
        return user;
    }

    /**
     * veritabanında kayıtlı kullanıcıların silinmesi
     * */
    public void deleteUsers() {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_USER, null, null);
        db.close();
    }

}

Login Ekranının Hazırlanması

Projemizde kullanıcının ilk karşılaşacağı ekran olan LoginActivity ekranının hazırlanmasına geldi sıra. AndroidManifest.xml dosyasında default olarak bu Activity nin açılacağını belirlemiştik. res => layout dizini altında activity_login.xml dosyası oluşturup aşağıdaki kodu yapıştıralım.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/white"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="10dp" >



    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" >

        <ImageView
            android:id="@+id/yazilimdersiImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:src="@drawable/logo" />

        <EditText
            android:id="@+id/email"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:background="@color/bg_login"
            android:hint="@string/hint_email"
            android:inputType="textEmailAddress"
            android:padding="10dp"
            android:singleLine="true"
            android:textColor="@color/white"
            android:textColorHint="@color/white" />

        <EditText
            android:id="@+id/password"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:background="@color/bg_login"
            android:hint="@string/hint_password"
            android:inputType="textPassword"
            android:padding="10dp"
            android:singleLine="true"
            android:textColor="@color/white"
            android:textColorHint="@color/white" />


        <Button
            android:id="@+id/btnLogin"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dip"
            android:background="@color/btn_login_bg"
            android:text="@string/btn_login"
            android:textColor="@color/btn_login" />


        <Button
            android:id="@+id/btnLinkToRegisterScreen"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dip"
            android:background="@null"
            android:text="@string/btn_link_to_register"
            android:textAllCaps="false"
            android:textColor="@color/bg_register"
            android:textSize="15dp" />
    </LinearLayout>

</LinearLayout>

Bu arayüz ile ilişkili LoginActivity.java sınıfının içeriğini aşağıdaki şekilde belirleyelim. checkLogin() metodu ile kullanıcının bilgilerini API üzerinden talep edelim.


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

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

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

import java.util.HashMap;
import java.util.Map;
import info.yazilimdersi.sampleapp.core.AppConfig;
import info.yazilimdersi.sampleapp.core.AppController;
import info.yazilimdersi.sampleapp.helper.SQLiteHandler;
import info.yazilimdersi.sampleapp.helper.SessionManager;

public class LoginActivity extends Activity {
    private static final String TAG = RegisterActivity.class.getSimpleName();
    private Button btnLogin;
    private Button btnLinkToRegister;
    private EditText inputEmail;
    private EditText inputPassword;
    private ProgressDialog pDialog;
    private SessionManager session;
    private SQLiteHandler db;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        inputEmail = (EditText) findViewById(R.id.email);
        inputPassword = (EditText) findViewById(R.id.password);
        btnLogin = (Button) findViewById(R.id.btnLogin);
        btnLinkToRegister = (Button) findViewById(R.id.btnLinkToRegisterScreen);

        pDialog = new ProgressDialog(this);
        pDialog.setCancelable(false);

        db = new SQLiteHandler(getApplicationContext());
        session = new SessionManager(getApplicationContext());

        // kullanıcının daha önceden giriş yapıp yapmadığını sorgula
        if (session.isLoggedIn()) {
            // kullanıcı daha önceden giriş yapmıştı. MainActivity sınıfına yönlendir
            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
            startActivity(intent);
            finish();
        }

        // giriş butonu
        btnLogin.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                String email = inputEmail.getText().toString().trim();
                String password = inputPassword.getText().toString().trim();

                // herhangi eksik bilgi varmı kontrolü
                if (!email.isEmpty() && !password.isEmpty()) {
                    // kullanıcı girisi
                    checkLogin(email, password);
                } else {
                    // hata mesajı
                    Toast.makeText(getApplicationContext(),
                            "Lütfen tüm bilgileri eksiksiz giriniz!", Toast.LENGTH_LONG)
                            .show();
                }
            }

        });

        btnLinkToRegister.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                Intent i = new Intent(getApplicationContext(),
                        RegisterActivity.class);
                startActivity(i);
                finish();
            }
        });

    }

    /**
     * kullanıcı kontrolü
     * */
    private void checkLogin(final String email, final String password) {
        String tag_string_req = "req_login";

        pDialog.setMessage("Giriş yapılıyor...");
        showDialog();

        StringRequest strReq = new StringRequest(Method.POST,
                AppConfig.URL_LOGIN, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Login Response: " + response.toString());
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    // hata kodlarının kontrol edilmesi
                    if (!error) {
                        // kullanıcı basarılı sekilde giris yaptı
                        session.setLogin(true);

                        String uid = jObj.getString("uid");

                        JSONObject user = jObj.getJSONObject("user");
                        String name = user.getString("name");
                        String email = user.getString("email");
                        String created_at = user
                                .getString("created_at");

                        // kullanıcı kaydı oluşturuldu
                        db.addUser(name, email, uid, created_at);

                        // MainActivity çağrıldı
                        Intent intent = new Intent(LoginActivity.this,
                                MainActivity.class);
                        startActivity(intent);
                        finish();
                    } else {
                        String errorMsg = jObj.getString("error_msg");
                        Toast.makeText(getApplicationContext(),
                                errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Login Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                params.put("email", email);
                params.put("password", password);

                return params;
            }

        };

        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }
}

Yapılan düzenleme sonrası login ekranına ait ekran görüntüsü aşağıdaki şekilde olacaktır.

Register Ekranının Hazırlanması

Projemizde yeni kullanıcı kaydının oluşturulmasında kullanılacak olan RegisterActivity ekranının hazırlanmasına geldi sıra. Kullanıcıya ait name, email ve password bilgilerinin bu arayüz üzerinden girilmesi gerekmektedir.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/white"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="10dp" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingRight="20dp" >

        <ImageView
            android:id="@+id/yazilimdersiImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="20dp"
            android:src="@drawable/logo" />

        <EditText
            android:id="@+id/name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:background="@color/input_register_bg"
            android:hint="@string/hint_name"
            android:padding="10dp"
            android:singleLine="true"
            android:inputType="textCapWords"
            android:textColor="@color/white"
            android:textColorHint="@color/white" />

        <EditText
            android:id="@+id/email"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:background="@color/input_register_bg"
            android:hint="@string/hint_email"
            android:inputType="textEmailAddress"
            android:padding="10dp"
            android:singleLine="true"
            android:textColor="@color/white"
            android:textColorHint="@color/white" />

        <EditText
            android:id="@+id/password"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:background="@color/input_register_bg"
            android:hint="@string/hint_password"
            android:inputType="textPassword"
            android:padding="10dp"
            android:singleLine="true"
            android:textColor="@color/white"
            android:textColorHint="@color/white" />

        <Button
            android:id="@+id/btnRegister"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dip"
            android:background="#ea4c88"
            android:text="@string/btn_register"
            android:textColor="@color/white" />

        <Button
            android:id="@+id/btnLinkToLoginScreen"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dip"
            android:background="@null"
            android:text="@string/btn_link_to_login"
            android:textAllCaps="false"
            android:textColor="@color/bg_register"
            android:textSize="15dp" />
    </LinearLayout>

</LinearLayout>

Bu arayüz ile ilişkili RegisterActivity.java sınıfının içeriğini aşağıdaki şekilde belirleyelim. registerUser() metodu ile yeni kullanıcı kaydını gerçekleştirelim.

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

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

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

import java.util.HashMap;
import java.util.Map;

import info.yazilimdersi.sampleapp.R;
import info.yazilimdersi.sampleapp.core.AppConfig;
import info.yazilimdersi.sampleapp.core.AppController;
import info.yazilimdersi.sampleapp.helper.SQLiteHandler;
import info.yazilimdersi.sampleapp.helper.SessionManager;

public class RegisterActivity extends Activity {
    private static final String TAG = RegisterActivity.class.getSimpleName();
    private Button btnRegister;
    private Button btnLinkToLogin;
    private EditText inputFullName;
    private EditText inputEmail;
    private EditText inputPassword;
    private ProgressDialog pDialog;
    private SessionManager session;
    private SQLiteHandler db;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);

        inputFullName = (EditText) findViewById(R.id.name);
        inputEmail = (EditText) findViewById(R.id.email);
        inputPassword = (EditText) findViewById(R.id.password);
        btnRegister = (Button) findViewById(R.id.btnRegister);
        btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);

        pDialog = new ProgressDialog(this);
        pDialog.setCancelable(false);
        session = new SessionManager(getApplicationContext());

        db = new SQLiteHandler(getApplicationContext());

        // kullanıcının daha önceden giriş yapıp yapmadığını sorgula
        if (session.isLoggedIn()) {
            // kullanıcı daha önceden giriş yapmıştı. MainActivity sınıfına yönlendir
            Intent intent = new Intent(RegisterActivity.this,
                    MainActivity.class);
            startActivity(intent);
            finish();
        }

        // hesap oluştur butonu
        btnRegister.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String name = inputFullName.getText().toString().trim();
                String email = inputEmail.getText().toString().trim();
                String password = inputPassword.getText().toString().trim();

                if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                    registerUser(name, email, password);
                } else {
                    Toast.makeText(getApplicationContext(),
                            "Lütfen eksiksiz olarak tüm bilgileri giriniz!", Toast.LENGTH_LONG)
                            .show();
                }
            }
        });

        btnLinkToLogin.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                Intent i = new Intent(getApplicationContext(),
                        LoginActivity.class);
                startActivity(i);
                finish();
            }
        });

    }
    
    private void registerUser(final String name, final String email,
                              final String password) {
        String tag_string_req = "req_register";

        pDialog.setMessage("Hesap Oluşturuluyor...");
        showDialog();

        StringRequest strReq = new StringRequest(Method.POST,
                AppConfig.URL_REGISTER, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");
                    if (!error) {
                        String uid = jObj.getString("uid");

                        JSONObject user = jObj.getJSONObject("user");
                        String name = user.getString("name");
                        String email = user.getString("email");
                        String created_at = user
                                .getString("created_at");

                        // users tablosuna icerik ekleyin
                        db.addUser(name, email, uid, created_at);

                        Toast.makeText(getApplicationContext(), "Kullanıcı başarılı şekilde giriş yaptı. Şimdi giriş yapın!", Toast.LENGTH_LONG).show();

                        // login ekranına yönlendir
                        Intent intent = new Intent(
                                RegisterActivity.this,
                                LoginActivity.class);
                        startActivity(intent);
                        finish();
                    } else {
                        // hata mesajı
                        String errorMsg = jObj.getString("error_msg");
                        Toast.makeText(getApplicationContext(),
                                errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Registration Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                params.put("name", name);
                params.put("email", email);
                params.put("password", password);

                return params;
            }

        };

        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }
}

Yapılan düzenlemeler sonrası register ekranına ait ekran görüntüsü aşağıdaki şekilde olacaktır.

Ana Ekranının Hazırlanması

Uygulamaya giriş yapan kullanıcının karşılaşacağı MainActivity ekranının hazırlanmasını gerçekleştirelim. Bu arayüzde en basitinden giriş yapılmış olan kullanıcıya ait name, email bilgileri görüntülenecektir. Ayrıca kullanıcının logout olmasına imkan sunan bir butonda bu ekranda görüntülenecektir.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/welcome"
            android:textSize="20dp" />

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textColor="@color/lbl_name"
            android:textSize="24dp" />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="13dp" />

        <Button
            android:id="@+id/btnLogout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dip"
            android:background="@color/btn_logut_bg"
            android:text="@string/btn_logout"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textSize="15dp" />
    </LinearLayout>

</RelativeLayout>

Bu arayüz ile ilişkili RegisterActivity.java sınıfının içeriğini aşağıdaki şekilde belirleyelim. registerUser() metodu ile yeni kullanıcı kaydını gerçekleştirelim.

import info.yazilimdersi.sampleapp.helper.SQLiteHandler;
import info.yazilimdersi.sampleapp.helper.SessionManager;

import java.util.HashMap;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView txtName;
    private TextView txtEmail;
    private Button btnLogout;

    private SQLiteHandler db;
    private SessionManager session;

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

        txtName = (TextView) findViewById(R.id.name);
        txtEmail = (TextView) findViewById(R.id.email);
        btnLogout = (Button) findViewById(R.id.btnLogout);

        db = new SQLiteHandler(getApplicationContext());

        session = new SessionManager(getApplicationContext());

        if (!session.isLoggedIn()) {
            logoutUser();
        }

        // Kullanıcı bilgilerinin veritabanından getirilmesi
        HashMap<String, String> user = db.getUserDetails();

        String name = user.get("name");
        String email = user.get("email");

        // Kullanıcı bilgilerinin ekranda görüntülenmesi
        txtName.setText(name);
        txtEmail.setText(email);

        // Çıkış butonu
        btnLogout.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                logoutUser();
            }
        });
    }

    private void logoutUser() {
        session.setLogin(false);

        db.deleteUsers();

        // login ekranının görüntülenmesi
        Intent intent = new Intent(MainActivity.this, LoginActivity.class);
        startActivity(intent);
        finish();
    }
}

Yapılan düzenlemeler sonrası ana ekrana ait ekran görüntüsü aşağıdaki şekilde olacaktır.

Uygulamanın Test Edilmesi

Hem mobil uygulamaya ait kodlama hem de API ye ait kodlamaları tamamladık. Uygulamanın çalışırlığını test edebilmemiz adına aşağıdaki adımları uygulamanız gerekmektedir;

  • AppConfig.java dosyasında tanımlanan URL_REGISTER ve URL_LOGIN linklerinin cihazınıza ait IP adresi ile değiştirilmesi gerekmektedir. Bunu öğrenmek için bilgisayarınızda komut istemcisini açıp ipconfig komutunu girdiğinizde gelen ekrandaki IPV4 Adres bilgisini kullanmanız gerekecektir.
  • Mobil uygulamayı yüklediğiniz cihazla API nın olduğu bilgisayar aynı network üzerinde olmalıdır.
  • config.php dosyasında username, password ve database alanına veritabanına erişimde kullanılan bilgiler girilmelidir.
]]>
ADSL Modemlere ait kullanıcı adı şifre http://yazilimdersi.info/makaleler/detay/127/adsl-modemlere-ait-kullanici-adi-sifre Thu, 21 Jan 2021 00:00:00 +0000 mstfchelik Evimizde veya iş yerimizde modemimizi kullanıyoruz ve bazen bu modemin arayüz kısmına erişmemiz gerekiyor. Erişim sebebi; modemin şifresinin değiştirilmek istenmesi, mevcut olan konfigurasyonlarda değişiklik yapılması olabilir.

Çoğu zaman modemlerin arayüzüne erişimde kullanıcı adı ve şifre bilgilerini ya unutuyoruz yada bilmiyoruz. Aşağıdaki listede yaygın olarak kullanılan modemlerin kullanıcı adı ve şifrelerini sizlerle paylaşıyoruz.

Zyxel Modem

Zyxel modeminin default url adresi 192.168.1.1 ve kullanıcı adı "admin" dir. Eğer modemi Türk Telekom kampanyası ile aldıysanız şifre ttnet veya turktelekom, eğer Göknet firmasından aldıysanız şifre kısmına goknet yazarak modem arayüzüne giriş yapabilirsiniz. Eğer modemi farklı bir firmadan aldıysanız default şifre 1234 veya admin olabilir.

Tp-Link Modem

Tp-Link modeminin default url adresi 192.168.1.1 ve kullanıcı adı "admin" dir. Eğer modemi Türk Telekom kampanyası ile aldıysanız şifre kısmına ttnet veya turktelekom yazarak modem arayüzüne giriş yapabilirsiniz. Eğer modemi farklı bir firmadan aldıysanız default şifre 1234 veya admin olabilir.

AirTies Modem

AirTies modeminin default url adresi 192.168.2.1 ve kullanıcı adı "admin" dir. Eğer modemi Türk Telekom kampanyası ile aldıysanız şifre kısmına ttnet veya turktelekom yazarak modem arayüzüne giriş yapabilirsiniz. Eğer modemi farklı bir firmadan aldıysanız şifre alanı boş bırakılmalıdır.

Asus Modem

Asus modeminin default url adresi 192.168.1.1 veya 192.168.1.254 ve kullanıcı adı "admin" dir. Default şifre olarak ise admini kullanabilirsiniz.

 

Pikatel ComboMax Modem

Pikatel ComboMax modeminin default url adresi 192.168.1.1 ve kullanıcı adı "admin" dir. Eğer modemi Türk Telekom kampanyası ile aldıysanız şifre kısmına ttnet veya turktelekom yazarak modem arayüzüne giriş yapabilirsiniz. Eğer modemi farklı bir firmadan aldıysanız default şifre password olabilir.

Şu ana kadar anlattığımız modemler Türkiye'de yaygın olarak kullanılan markalardır. Bu markaların dışında olan modemlerin listesi ve bilgileri şu şekildedir;

 

Modem Markası URL Adresi Kullanıcı Şifre
US Robotics 10.0.0.2 admin admin
Zoom X serisi 10.0.0.2 admin zoomadsl
Actiontec 192.168.0.1 admin boş bırakınız
Actiontec Verizon 192.168.1.1 admin boş bırakınız
Airties 192.168.2.1 admin ttnet
Airties RT206v2 (TTNET) 192.168.2.1 admin ttnet
Airties RT210 (TTNET) 192.168.2.1 boş bırakınız boş bırakınız
Airties RT210 (TTNET) 192.168.2.1 admin ttnet
Allied Telesyn 192.168.1.1:8080 manager friend
Apache 192.168.1.1 root veya setup root
Artes 192.168.1.1 admin adslroot
Aztech 10.0.0.2 admin admin
Bec 192.168.1.254 admin admin
Billion 192.168.1.254 admin admin
Billion Bipac 192.168.1.254 admin password
Bross 192.168.1.1 admin 1234
C-Com 192.168.1.1 boş bırakınız boş bırakınız
Cnet 10.0.0.2 admin epicrouter
Corecess 3112 usb 10.0.0.3 admin corecess3112
Corecess 3113 eth 10.0.0.2 admin corecess3113
Creative 192.168.1.1 admin admin
Dibeg 108 192.168.1.1 dare boş bırakınız
D-Link 192.168.1.1 admin admin
Datron ETHERNET 192.168.1.1 admin admin
Datron USB 192.168.1.2 admin admin
Dost GVC 192.168.1.254 admin dostdost
DryTek 192.168.1.1 admin boş bırakınız
Dynalink 192.168.1.1 admin admin
Edimax 192.168.2.1 admin 1234
E-Con 192.168.1.1 admin admin
Eicon Diva 10.0.0.2 boş bırakınız boş bırakınız
Everest SG-1400 192.168.1.1 admin admin
Fishnet AR-1101 (DOPING) 192.168.1.1 admin 1234
Flynet 192.168.1.1 admin admin
Geek 10.0.0.2 admin epicrouter veya geekadsl
Gezz 10.0.0.2 admin epicrouter
Hayes 10.0.0.2 admin hayesadsl
Home Station DC 213 10.0.0.1 admin admin
Home Station DC 214 192.168.1.254 admin password
Hicomm 10.0.0.2 admin epicrouter
Huawei 192.168.1.1 admin ttnet
Inca 192.168.1.1 veya 10.0.0.2 admin epicrouter
Karel 10.0.0.2 admin adslroot
Ladox 192.168.1.1 admin ladox
Loopcom 10.0.0.2 admin epicrouter
Link SYS 192.168.1.1 admin admin
Mercury ADSL 10.0.0.2 admin conexant
NetMaster 192.168.2.1 veya 192.168.0.1 admin password
Quake 10.0.0.2 admin epicrouter
Onixon 192.168.1.1 root root
Origo Wireless 10.0.0.2 admin kont2004
Origo 192.168.2.1 admin admin
Paradigm 10.0.0.2 admin epicrouter
Pikatel 192.168.7.1 DSL DSL
Pikatel ComboMax 192.168.1.1 admin password
Philips SNA6500 192.168.2.1 boş bırakınız admin
Philips SNC6500 192.168.2.1 boş bırakınız admin
Pti 840 10.0.0.2 admin epicrouter
Pronets 10.0.0.2 admin conexant
Siemens 192.168.254.254 siz belirlersiniz siz belirlersiniz
SMC 192.168.2.1 boş bırakınız smcadmin
Sonicwall 192.168.1.1 admin password
Speedstream 192.168.254.254 admin siz belirlersiniz
Speedcom 10.0.0.2 admin conexant
SpeedTouch 10.0.0.138 siz belirlersiniz siz belirlersiniz
SpeedTouch 330 10.0.0.138 siz belirlersiniz siz belirlersiniz
Thomson 10.0.0.138 siz belirlersiniz siz belirlersiniz
Tecom 192.168.1.1 root root
ZTE XDSL 192.168.2.1 admin ttnet
ZTE ZXDSL 192.168.1.1 ZXDSL ZXDSL
]]>
Windowsda Installer klasörü http://yazilimdersi.info/makaleler/detay/126/windowsda-installer-klasoru Thu, 21 Jan 2021 00:00:00 +0000 mstfchelik Çoğumuz bilgisayarlarımızda (özellikle SSD özellikteki disklerde) sürekli farklı programlamaların kurulmasından, yeni teknolojileri takip edip kurulumların gerçekleştirilmesinden kaynaklı diskte alan problemi yaşamaktayız. Belirli periyotlarla diskimizi temizlememiz gerekmekte ve gereksiz klasörlerin tespit edilmesinde TreeSize gibi uygulamaları kullanmaktayız. Yaptığımız disk taramalarında C:\Windows\Installer klasöründe yüklü miktarda dosya bulunduğunu gözlemledim.

C:\Windows\Installer klasörü, bilgisayarımıza yüklenen programlara ait MSI ve MSP uzantılı kurulum dosyalarını barındırmaktadır. Yüklenen herhangi bir programı kaldırsanız bile bu programa ait MSP veya MSI dosyaları bu klasörde halen durmaktadır. Bu da gereksiz yere bilgisayarınızda alan kaplamaya neden olmaktadır. Burada bulunan tüm dosyalar gereksizdir diyemeyiz. Mevcut kurulu programların çalışması için burada bulunan dosyalara ihtiyac duyulmaktadır. Amacımız bilgisayarımızdan kaldırdığımız programların atıklarını temizlemektir.

Gereksiz olan dosyaların tespitini ise rahatlıkla yapamamaktayız. Çünkü klasörü incelediğinizde anlamsız isimlendirilmiş MSI ve MSP uzantılı dosyalarla karşılaşacaksınız. Burada tavsiye edebileceğimiz en kullanışlı uygulama PatchCleaner. Bu uygulama sayesinde bilgisayarınızda sildiğiniz ama halen Installer klasöründe listelenen gereksiz dosyaların tespitini hızlı şekilde gerçekleştirebilirsiniz. Uygulamayı indirmek için linke tıklayın.

Uygulamayı indirip kurduğunuzda aşağıdaki gibi bir ekranla karşılaşacaksınız.

Patch Cleaner

Yukarıdaki ekran görüntüsünde gördüğünüz gibi 7.86 GB lık 128 adet dosya gereksiz yere bilgisayarımda alan kaplamakta. Bu dosyalara yönelik yapılabilecek Move ve Delete gibi iki seçenek sunulmaktadır. Delete butonuna tıkladığınızda Installer klasörü altındaki gereksiz dosyaların silinmesi sağlanmaktadır. Move butonuna tıklandığında ise bu dosyaların bilgisayarda farklı bir konuma taşınması sağlanmaktadır.

]]>
PHP PDO kullanımı http://yazilimdersi.info/makaleler/detay/125/php-pdo-kullanimi Wed, 20 Jan 2021 00:00:00 +0000 mstfchelik Öncelikle PHP PDO'nun ne olduğunu ve ne amaçla kullanıldığını görelim. PHP PDO(PHP Data Objects), PHP dilinde yazılı olan projenizin veritabanlarına erişmek için kullandığı basit bir kütüphanedir. PHP'de veritabanları üzerinde erişim sağlamak için data erişim katmanı oluşturur. En önemli özelliği, Mongo, Mysql, PostgreSQL vb. farklı veritabanlarına aynı kodlama ile sorunsuz bağlantı imkanı sağlamasıdır. Yani projeniz hangi veritabanını kullanırsa kullansın eğer PDO kütüphanesi ile kodladıysanız ekstradan herhangi bir düzenleme yapmanıza gerek kalmayacaktır.

PDO, PHP ile veritabanı arasında bir bağlantıyı temsil eder. PDOStatement ise herhangi bir sorguyu çalıştırdıktan sonra dönen sonuç kümesini temsil eder. PDOException, PDO tarafından oluşturulan hatayı temsil eder.

MySQL veritabanı

Bu makalemizde yapılacak örneği MySQL veritabanı kullanarak gerçekleştireceğiz. Örnek olarak ülkelerin tutulduğu bir tablo oluşturalım. Bu tablo içerisine de o ülkelere ait popülasyon bilgilerini örnek olarak girelim.

DROP TABLE IF EXISTS ulkeler;
CREATE TABLE ulkeler(id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    ad VARCHAR(255), populasyon INT);

INSERT INTO ulkeler(ad, populasyon) VALUES('China', 1382050000);
INSERT INTO ulkeler(ad, populasyon) VALUES('India', 1313210000);
INSERT INTO ulkeler(ad, populasyon) VALUES('USA', 324666000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Indonesia', 260581000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Brazil', 207221000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Pakistan', 196626000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Nigeria', 186988000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Bangladesh', 162099000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Nigeria', 186988000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Russia', 146838000);
INSERT INTO ulkeler(ad, populasyon) VALUES('Japan', 126830000);

Bu komutla birlikte ulkeler adında bir tablo oluşturup içerisine veriler eklendi.

PHP Pdo Sorgusu

PDO da yaygın olarak kullanılan query() metodu ile veritabanına direkt sorgu atılmakta ve tekil sonuç dönmektedir. Dönen sonuca ulaşmak için fetch() metodu kullanılmaktadır.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

$stm = $pdo->query("SELECT VERSION()");

$version = $stm->fetch();

echo $version[0] . PHP_EOL;
?>

Yukarıdaki örnek sorgu ile veritabanına ait versiyon bilgisi çekilmektedir. Örnek sorguda ilk satırda tanımlanan $dsn bilgisi hangi veritabanına bağlanılacağına yönelik bilgi içermektedir.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";

Sorguda göründüğü üzere localhost üzerinde çalışan mysql veritabanına bağlanılacak. Bağlantılacak veritabanının ismini de veritabanım olarak belirledik. Daha sonrasında username ve password bilgileri alttaki satırlarda girilmektedir. Sonuç olarak aşağıdaki şekilde bir sorgu sonucu ile karşılaşmaktayız.

5.7.22-0ubuntu0.16.04.1

PHP Pdo exec

PDO da önemli bir yere sahip olan exec() metodu, yapılan sorgulama sonucu etkilenen sorgu sayısını geri dönmektedir.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

$nrows = $pdo->exec("DELETE FROM ulkeler WHERE id IN (1, 2, 3)");

echo "Etkilenen kayıt sayısı: $nrows";
?>

Yapılan sorgulama ile ulkeler tablosundan 1,2,3 idlerine sahip kayıtların silinmesi sağlamaktadır. Sonuç olarak ise örneğin üç kayıt silindiği için Etkilenen kayıt sayısı: 3 gibi bir sonuç dönecektir.

PHP Pdo fetch

PDO yapısında PDO::FETCH_ASSOC, PDO::FETCH_NUM ve PDO::FETCH_BOTH şeklinde üç farklı fetch kurgusu bulunmaktadır. PDO::FETCH_BOTH default olarak tanımlı olan tanımlamadır. PDO::FETCH_ASSOC tanımında, dönen dizin elemanının sütün adına göre dönmesi sağlanmaktadır. PDO::FETCH_NUM tanımında, dönen dizin elemanı ise sütun numarasına göre dönecek şekilde ayarlanmaktadır.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

$stm = $pdo->query("SELECT * FROM ulkeler");

$rows = $stm->fetchAll(PDO::FETCH_NUM);

foreach($rows as $row) {

    printf("$row[0] $row[1] $row[2]\n");
}

?>

Yapılan sorgulamada dikkat ederseniz veriler $row[0], $row[1] ve $row[2] olarak çekilmektedir ve dönen içerikte veritabanından id, ad, populasyon alanlarına ait veriler listelenecektir.

Aşağıdaki sorguda ise direkt veritabanında kayıtlı olan sütun ismine göre verilerin çekilmesi sağlanmaktadır. Bunun için PDO::FETCH_ASSOC metodunu kullanmaktayız.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

$stm = $pdo->query("SELECT * FROM ulkeler");

$rows = $stm->fetchAll(PDO::FETCH_ASSOC);

foreach($rows as $row) {

    printf("$row['id'] $row['ad'] $row['populasyon']\n");
}

?>

PHP PDO Parametre İlişkilendirmesi

SQL sorguları genellikle dinamik olarak oluşturulur. Sorgulamada setlenecek olan parametreler kullanıcı tarafından belirlenir. Ancak burada en önemli konu setlenilecek olan parametreleri bindValue() ve bindParam() gibi metodlar üzerinden gerçekleştirmeniz. Çünkü veritabanına bağlantıların gerçekleştirildiği kurgularda güvenlik en sorunlu olan kısımdır. Parametrik olan sorgular çoğunlukla veritabanına SQL injection gerçekleştirilmesi gibi sorunlara sebep olabilmektedir.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

$id = 5;

$stm = $pdo->prepare("SELECT * FROM ulkeler WHERE id = ?");

$stm->bindValue(1, $id);
$stm->execute();

$row = $stm->fetch(PDO::FETCH_ASSOC);

echo "Id: " . $row['id'] . PHP_EOL;
echo "Ad: " . $row['ad'] . PHP_EOL;
echo "Popülasyon: " . $row['populasyon'] . PHP_EOL;

?>

Bu sorgu ile idsi 5 olan kaydın çıktısı dönecektir. Aşağıda ekranda görüntülenecek olan veri şu şekilde olacaktır;

Id: 5
Ad: Brazil
Popülasyon: 207221000

Aynı sorguyu bindParam() metodu ile gerçekleştirelim. Burada yapılacak sorgulamaya göre numerik olarak tanımlama yerine key- value olarak tanımlama gerçekleştirilmektedir.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

$id = 5;

$stm = $pdo->prepare("SELECT * FROM ulkeler WHERE id = :id");
$stm->bindParam(":id", $id, PDO::PARAM_INT);
$stm->execute();

$row = $stm->fetch(PDO::FETCH_ASSOC);

echo "Id: " . $row['id'] . PHP_EOL;
echo "Ad: " . $row['ad'] . PHP_EOL;
echo "Popülasyon: " . $row['populasyon'] . PHP_EOL;

?>

Dikkat ederseniz artık id olarak tanımlama yapılıp, parametrelerde id'ye göre setlemeler gerçekleştirilmektedir. Aslında bu yöntem bindValue metodundan daha kullanışlı ve güvenilirdir. Tavsiyemiz kodlamalarınızda bunu kullanmanızdır. Zaten sonuç olarak elde edilecek ekran görüntüsü yukarıda görüntülenen çıktıdan farklı olmayacaktır.

PHP PDO lastInsertId() metodu

lastInsertId() metodu bizlere veritabanına eklenen herhangi bir veri olduğu zaman eklenen verinin rowId bilgisini dönmektedir. Bu veri çoğu zaman projemizde ilişkili veritabanını kurgusunu ayarlamada kullanılmaktadır. En güzel yani tekrardan select ile veritabanına sorgu atmamıza gerek kalmamakta, performans olarak baya etkin bir sonuç sunmaktadır.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

$pdo->exec("INSERT INTO ulkeler(ad, populasyon) VALUES('Japan',  81050000)");
$pdo->exec("INSERT INTO ulkeler(ad, populasyon) VALUES('Mexico', 550000)");
$pdo->exec("INSERT INTO ulkeler(ad, populasyon) VALUES('Tunis',  938050000)");
$pdo->exec("INSERT INTO ulkeler(ad, populasyon) VALUES('Benin',  182050000)");

$rowId = $pdo->lastInsertId();

echo "Son eklenen row id: $rowId\n";

?>

Gördüğünüz gibi yapılan sorgulama ile birlikte ulkeler veritabanına 4 ayrı kayıt ekledik. Bu kayıtlarında eklenmesinin ardından kayda ait id numarası ekrana aşağıdaki şekilde gelecektir.

Son eklenen row id: 12

PHP PDO Transactionlar

Transaction tanım olarak veritabanı işlemlerinde gerçekleştirilen unique birimdir. Özellikle birden fazla bağlantılı olan global projelerde bu kullanım önemli bir yer tutmaktadır. Çünkü yapılacak olan işlemler commit ve rollback isimli metodlarla desteklenmekte ve yapılan işlemlerin tümünün gerçekleştirilmesi garanti hale getirilmektedir.

<?php

$dsn = "mysql:host=localhost;dbname=veritabanim";
$user = "kullanici";
$passwd = "abc123";

$pdo = new PDO($dsn, $user, $passwd);

try {

    $pdo->beginTransaction();
    $pdo->exec("INSERT INTO ulkeler(ad, populasyon) VALUES('Japan',  81050000)");
    $pdo->exec("INSERT INTO ulkeler(ad, populasyon) VALUES('Mexico', 550000)");
    $pdo->exec("INSERT INTO ulkeler(ad, populasyon) VALUES('Tunis',  938050000)");
    $pdo->commit();

} catch(Exception $e) {
    $pdo->rollback();
    throw $e;
}
 
?>

Bu örnekte gördüğünüz gibi ulkeler veritabanına 3 yeni kayıt eklemeye çalışıyoruz. Öncelikle beginTransaction() metodu ile birlikte yeni bir transaction oluşturulması sağlandı. Yazılan kodlamada ya hep ya hiç kurgusuna göre kodumuz çalışacaktır. Yani çalıştırılan sorguda herhangi bir yerde sorun ortaya çıkarsa rollback ile geri dönecek ve kayıtlar veritabanına kayıt edilmeyecektir.

]]>
Whois Sorgulama http://yazilimdersi.info/makaleler/detay/124/whois-sorgulama Sat, 16 Jan 2021 00:00:00 +0000 mstfchelikWhois Bilgisi Nedir?

Her domain kaydı esnasında domainin hak sahibini, finansal ve teknik sorumlusunu belirlemek için oluşturulan, domain alımlarında ilgili firma tarafından talep edilen ve içerisinde kişisel veya firmaya ait alınan bir domain ise firma ismi, telefon, e-mail ve adres bilgilerini barındıran bilgiler bütününe whois bilgisi denir.

Whois Sorgulama İşlemi Nasıl Çalışır?

Whois sorgulama, yetkilendirilmiş ip adresleri üzerinden ilgili Registry firmasından (Godaddy gibi) veya whois sunucusuna, güvenlik şartlarını tahsis ettiği veri tabanı üzerine bilgilerin yazılması ile gerçekleştirilir.

Gizli whois kaydı/bilgisi nedir?

Bazı domainlerin kimlik bilgileri domaini alan kullanıcılar tarafından gizlenebilmektedir. Bu durum domain whois protection olarak anılır. Whois protection’a sahip alan adlarının sahiplerine veya finansal ya da teknik yöneticilerine ulaşmak için whois bilgisinin gizliliğini üstlenen vekil adresine bildirimde bulunmak gerekir.

Her whois protection servis sağlayıcı, ICANN kuralları gereği kendisi üzerinden iletilen bildirimleri kimliğini gizlediği alan adının gerçek sahibine ulaştırmak zorundadır. Bu zorunlulukta beyan esas kabul edildiğinden whois bilgisi gizlenen alan adlarının gerçek sahibine ulaşmak için iletişim bilgilerinin doğruluğu ve güncelliği öncelikle ilgili alan adının sahibinin sorumluluğundadır.

Hazırladığımız araç ile sorgulamak istediğiniz alan adına ait ayrıntılı detaya whois sorgulama linkinden erişebilirsiniz.

]]>
PuzzImage Uygulamamız Yayında http://yazilimdersi.info/makaleler/detay/123/puzzimage-uygulamamiz-yayinda Wed, 13 Jan 2021 00:00:00 +0000 mstfchelik { '@context': 'https://schema.org', '@type': 'SoftwareApplication', 'name': 'PuzzImage', 'operatingSystem': 'ANDROID', 'applicationCategory': 'GameApplication', 'aggregateRating': { '@type': 'AggregateRating', 'ratingValue': '4.8', 'ratingCount': '58' }, 'offers': { '@type': 'Offer', 'price': '0', 'priceCurrency': 'USD' }, 'publisher': 'mstfchelik', 'review': [ { '@type': 'Review', 'author': { '@type': 'Person', 'name': 'Femi Pots' }, 'datePublished': '2021-03-08', 'name': 'Awesome Game', 'reviewBody': 'The Best puzzle game that offers fantastic experience for puzzle lovers. Love the game so much..great work from the developer.', 'reviewRating': { '@type': 'Rating', 'ratingValue': '5' } }, { '@type': 'Review', 'author': { '@type': 'Person', 'name': 'pankti patel' }, 'datePublished': '2021-01-28', 'name': 'friendly app', 'reviewBody': 'This is a very entertaining and fun game, especially kids likes, but also child-friendly..', 'reviewRating': { '@type': 'Rating', 'ratingValue': '5' } } ] }

Pandemi sürecinde en çok oynadığım oyunlardan birisi puzzle tipindeki oyunlardı. Bu oyunlarda dikkatimi çeken ve eksikliğini hissettiğim özelliklerin listesini oluşturup yeni bir uygulama yazma fikrini gerçekleştirip PuzzImage uygulamamızı yayına aldık.

Uygulamayı indirmek için linkine tıklayabilirsiniz.

Uygulamanın Özellikleri

  • Uygulamamız şimdilik sadece Türkçe, İngilizce, Fransızca ve Arapça dillerini desteklemektedir.
  • Uygulamamız tamamen ücretsizdir.
  • Uygulamada hesap oluşturup lider tablosunda kendinize de bir yer açabilirsiniz.
  • Basitten zora doğru 110 farklı seviyede puzzle listelenmektedir. Uygulamamız offline olarakda çalışmaktadır.
]]>
Faydalı PHP Fonksiyonları http://yazilimdersi.info/makaleler/detay/118/faydali-php-fonksiyonlari Sat, 26 Dec 2020 00:00:00 +0000 mstfchelik PHP, oluşturulduğu günden beri aktif olarak web geliştiricilerin radarında olan bir programlama dili. Anlaşılır yapısı, açık kaynak kod kütüphanelere sahip olması ve birçok platform tarafından desteklenmesi ister istemez herzaman ön planda olmasına sebep olmaktadır. Üzerinden uzun süre geçmesine rağmen halen popülerliği konuşulmakta ve birçok yazılımcı için ilham kaynağı olmaktadır.

Makalemizde PHP programlamada yaygın olarak kullanılan bazı methodlar ile alakalı bilgi verip örnekler gerçekleştireceğiz.

echo komutu

echo komutu, tanımlı olan herhangi bir textin ekrana basılmasında kullanılmaktadır. Aslında kullanımı oldukça yaygın bir fonksiyondur.

$text = 'Süper Kupayı Fenerbahçe aldı.';
echo $text;

echo $text, kodu ile ekrana $text içerisinde tanımlı olan ifadenin basılması sağlanmaktadır. Burada unutulmaması gereken konu ekrana basılacak olan ifadenin text olmasıdır. Eğer array tarzı bir içeriğin ekrana basılması gerekirse print_r() methodunu kullanmanız gerekmektedir.

print_r komutu

print_r komutu, herhangi bir array içerisinde tanımlı bir içerik varsa bunun ekrana basılmasında kullanılmaktadır.

$renkler = array("sarı","mavi","kırmızı", "yeşil");
print_r($renkler);

print_r($renkler), kodu ile ekrana $renkler dizin içerisinde tanımlı olan renklerin basılması sağlanmaktadır. Örneğin bu komutta ekrana Array ( [0] => red [1] => yellow [2] => pink ) verisi basılacaktır.

str_replace komutu

str_replace komutu, adından da anlaşıldığı üzere herhangi bir text üzerinde değiştirilmesini istediğiniz bir ifade varsa onu değiştirmede kullanılmaktadır;

$text = 'Süper Kupayı Fenerbahçe aldı.';
$degisim = str_replace('Fenerbahçe', 'Galatasaray', $text);
echo $degisim;

str_replace('Fenerbahçe', 'Galatasaray', $text), kod satırında gördüğünüz üzere ilk parametre text içerisinde aranacak kelimeyi ifade etmektedir. İkinci parametre ise eğer aranan kelime bulunursa yerine konulacak olan ifadeyi temsil etmektedir. Kodlama sonucunda ortaya çıkacak olan text 'Süper Kupayı Galatasaray aldı.' şeklinde olacaktır.

explode komutu

explode komutu, text içerisinde geçen ifadeleri belirlenen ayraçlara göre bölmede kullanılmaktadır. Örneğin text içerisinde geçen cümleleri ayrı ayrı dizi elemanları içerisine aktarmak istiyorsanız '.' ayracını aşağıdaki şekilde kullanmanız yeterli olacaktır.

$text = "Ahmet bugün okula gelmedi. Evini aradık kimse cevap vermiyor. Çok merak ediyorum";
$ayrilmis = explode(".", $text);
print_r($ayrilmis);

explode(".", $text), kod satırında gördüğünüz üzere ilk parametre ayrıştırıcı olarak kullanılan terimi ifade etmektedir. İkinci parametre ise ifadenin kendisini temsil etmektedir. Kodlama sonucunda ortaya çıkacak olan text Array ( [0] => Ahmet bugün okula gelmedi [1] => Evini aradık kimse cevap vermiyor [2] => Çok merak ediyorum ) şeklinde olacaktır. Dikkat ederseniz burada echo methodu yerine print_r metodunu kullandık. Yukarıda da belirtiğimiz üzere array yani dizileri ekrana basarken print_r metodunu kullanmanız gerekmektedir.

implode komutu

implode komutu, array yani dizi içerisinde tanımlı olan değişkenlerin text olarak birleştirilmesinde kullanılmaktadır. Burada birleşme esnasında kullanılması planlanan ayraç ilk parametrede iletilmektedir.

$array = array("Ahmet bugün okula gelmedi.", "Evini aradık kimse cevap vermiyor.", "Çok merak ediyorum"");
$text = implode(" ", $array);
echo $text;

implode(" ", $array), kod satırında yukarıda array içerisinde tanımlı olan textlerin boşluk karakteri ile birleştirilmesi sağlanmaktadır. Kodlama sonucunda ortaya çıkacak olan text Ahmet bugün okula gelmedi. Evini aradık kimse cevap vermiyor. Çok merak ediyorum şeklinde olacaktır.

rand komutu

rand komutu, verilen minimum ve maksimum rakamlar arasında rastgele sayı oluşturmada kullanılmaktadır. Örneğin websitenizde rastgele sayılara dayalı bir oyun geliştirmek istiyorsanız rand metodundan yararlanabilirsiniz.

echo rand(0,10);

rand(0,10), komutu çalıştırıldığında 0 ile 10 rakamları arasında rastgele bir rakamın oluşturulup ekrana basılması sağlanmaktadır. Burada ilk parametre minimum rakamı, ikinci parametre ise maksimum olan rakamı temsil etmektedir. Örnek çıktı olarak 3, 8, 1 gibi rakamları rastgele görebilirsiniz.

eval komutu

eval komutu, string içerisinde tanımlı olan herhangi bir Php kodunun çalıştırılmasında kullanılmaktadır. Aşağıda yapacağımız örnekle bu komutun işlevinin daha anlaşılır olacağı malum.

$run = 'echo "Ahmet bugun okula gelmedi";';
eval($run);

eval($run), komutu çalıştırıldığında $run değişkeni içerisinde tanımlı olan echo metodunun çalıştırılması sağlanmaktadır. Artık bildiğiniz üzere echo komutu sadece ekrana veri basmada kullanılmakta. eval komutu da aynı işlemi gerçekleştirip ekrana "Ahmet bugun okula gelmedi" textini basacaktır.

die komutu

die komutu, programın istediğiniz bir kod satırında durdurulmasını istediğinizde kullanılmaktadır. Örneğin yazdığınız PHP kodunda hangi dosyada sorunun kaynaklandığını bilemediğiniz durumlarda bu komutu aktif olarak kullanabilirsiniz. Satır satır kod parçacıkları içerisinde ilerleyip problemin neden kaynaklı olduğunu tespit edebilirsiniz.

....
...
..
die("burda");
echo "test";

die("burda"), komutu çalıştırıldığında bu kod satırına gelinceye kadar Php projeniz çalışacaktır. Ancak die komutu çalıştığı anda artık ekrana "burda" ifadesi yazılı bir text gözükecektir. die komutu altında bulunan echo metodu çalışmayacaktır.

]]>
Günlük Burç Uygulaması Yayında http://yazilimdersi.info/makaleler/detay/117/gunluk-burc-uygulamasi-yayinda Sun, 20 Dec 2020 00:00:00 +0000 mstfchelik { '@context': 'https://schema.org', '@type': 'SoftwareApplication', 'name': 'Best Daily Horoscope', 'operatingSystem': 'ANDROID', 'applicationCategory': 'GameApplication', 'aggregateRating': { '@type': 'AggregateRating', 'ratingValue': '4.2', 'ratingCount': '568' }, 'offers': { '@type': 'Offer', 'price': '0', 'priceCurrency': 'USD' }, 'publisher': 'mstfchelik', 'review': [ { '@type': 'Review', 'author': { '@type': 'Person', 'name': 'Saiyan Youth' }, 'datePublished': '2021-01-10', 'name': 'Awesome Game', 'reviewBody': 'This app is one of the best horoscope apps I have ever seen...on top of that it is easy to use and doesn't show any adds in between..very happy that I downloaded it.', 'reviewRating': { '@type': 'Rating', 'ratingValue': '5' } }, { '@type': 'Review', 'author': { '@type': 'Person', 'name': 'Kari Stray' }, 'datePublished': '2020-12-31', 'name': 'friendly app', 'reviewBody': 'Really the best daily horoscope of all I have seen before. Works fine and stable.', 'reviewRating': { '@type': 'Rating', 'ratingValue': '5' } } ] }

Uzun bir süredir üzerinde çalıştığımız günlük burç uygulamasını yayına aldık. Uygulamamızın en önemli çıkış noktası olan çoklu dil desteği özelliği, diğer burç uygulamaların önüne çıkmasına sebep olmaktadır.

Uygulamayı indirmek için linkine tıklayabilirsiniz.

Ayrıca uygulamamıza ait promo videoya aşağıdaki youtube videosu üzerinden ulaşabilirsiniz.

Uygulama Özellikleri

  • Uygulamamız Türkçe, İngilizce, Fransızca, Rusça, Korece, Japonca, Çince, Almanca, Flemenkçe, Filipince, Taylanca benzeri yirmiden fazla dil desteklemektedir.
  • Uygulamamızda ücretsiz olarak günlük bildirim özelliği bulunmaktadır.
  • Her gün size özel şanslı numaralar listelenmekte, ayrıca renklerden de faydalanabilmektesiniz.
  • Uyumlu burçlar özelliği ile birlikte her gün farklı burç uyumluluğuna yönelik bilgiler uygulamamız üzerinden sizlere sunulmaktadır.
  • İletişim sayfası üzerinden gerçek zamanlı olarak astrologlara anlık mesajlar iletebilir ve onlardan gelen cevaplara karşılık verebilirsiniz.
]]>
Linuxda Bellek Kullanımı Komutları http://yazilimdersi.info/makaleler/detay/116/linuxda-bellek-kullanimi-komutlari Sat, 19 Dec 2020 00:00:00 +0000 mstfchelik Linux makinalarda genelde işlemler komut satırları ile gerçekleştirilmektedir, çünkü makina üzerinde GUI her zaman mevcut olmayabilir. Çoğunlukla da sunucular üzerinde çalışırken yalnızca terminal erişimi sağlanmaktadır ve her şeyin komutlar üzerinden gerçekleştirilmesi gerekir. Bu yüzden makalemizde Linux sistemine ait bellek kullanımını kontrol etmek için kullanılabilecek komutları kontrol edeceğiz. Bellek, RAM ve Swap bilgilerini içerir.

Kaynakların yetersiz kalmaması ve kullanıcıların sunucuya erişebilmesi için, sunucularda işlem başına bellek kullanımını ve kullanılan belleği kontrol etmek genellikle önemlidir. Örneğin bir web sitesiniz var ve bu siteyi bir web sunucusu üzerinde çalıştırıyorsanız, sunucunun site ziyaretçilerine sorunsuz hizmet edebilmesi için yeterli belleğe sahip olması gerekmektedir. Aksi takdirde, bellek yetersiz kalıp trafik artışı olduğunda site çok yavaşlayabilir hatta siteniz çökebilir. Tıpkı masaüstü bilgisayarlarda karşılaşılan mavi ekranlar gibi ekranlarla karşılaşılabilirsiniz.

Şimdi bellek kontrolünde kullanılan beş önemli komutu detaylı şekilde madde madde inceleyelim.

free komutu

free komutu, Linux üzerindeki bellek kullanımını kontrol etmek için kullanılan kullanımı en basit bir komuttur. Aşağıda komut kullanımı şu şekildedir;

root@yazilimdersi: free -m
             total       used       free     shared    buffers     cached
Mem:          7976       6459       1517          0        865       2248
-/+ buffers/cache:       3344       4631
Swap:         1951          0       1951

-m parametresi, tüm verileri MB cinsinden görüntülemede kullanılır. Sistemde yüklü olan toplam RAM miktarı 7976 MB yani 8GBdir. used sütununda, Linux tarafından kullanılan RAM miktarını (6.4 GB) civarında göstermektedir. Komut sonucu akan veri oldukça açıklayıcı aslında. İkinci satırda bulunan 4,6 GB'nin kullanılabilir olduğunu göstermektedir.

Linux işletim sistemi doğal yapısında herseyi cacheleyip daha performanslı bir kullanıma yönelik çalışmaktadır. İhtiyac olmadığı durumda cache üzerinden verilerin silinmesi de otomatik olarak işletim sistemi tarafından gerçeklenmektedir.

Son satır, bu durumda tamamen free olan swap bellektir.

/proc/meminfo komutu

Bellek kullanımını kontrol etmenin bir başka yoluda /proc/meminfo dosyasını okumaktır. /proc dosya sisteminde gerçek dosyalar içermediğini bilin. Daha çok core ve sistem hakkında dinamik bilgiler içeren sanal dosyalardan oluşmaktadır.

root@yazilimdersi: cat /proc/meminfo
MemTotal:        8167848 kB
MemFree:         1409696 kB
Buffers:          961452 kB
Cached:          2347236 kB
SwapCached:            0 kB
Active:          3124752 kB
Inactive:        2781308 kB
Active(anon):    2603376 kB
Inactive(anon):   309056 kB
Active(file):     521376 kB
Inactive(file):  2472252 kB
Unevictable:        5864 kB
Mlocked:            5880 kB
SwapTotal:       1998844 kB
SwapFree:        1998844 kB
Dirty:              7180 kB
Writeback:             0 kB
AnonPages:       2603272 kB
Mapped:           788380 kB
Shmem:            311596 kB
Slab:             200468 kB
SReclaimable:     151760 kB
SUnreclaim:        48708 kB
KernelStack:        6488 kB
PageTables:        78592 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     6082768 kB
Committed_AS:    9397536 kB
VmallocTotal:   34359738 kB
VmallocUsed:      420204 kB
VmallocChunk:   34359311 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       62464 kB
DirectMap2M:     8316928 kB

MemTotal, MemFree, Buffers, Cached, SwapTotal, SwapFree alanlarına dikkat ederseniz free komutunda listelenen verilerle aynıdır. Bu komutta daha fazla bilgi verilmektedir.

vmstat komutu

s parametresi ile kullanılan vmstat komutu, proc komutuna çok benzer şekilde bellek kullanım istatistiklerini göstermektedir.

root@yazilimdersi: vmstat -s
      8167848 K total memory
      7449376 K used memory
      3423872 K active memory
      3140312 K inactive memory
       718472 K free memory
      1154464 K buffer memory
      2422876 K swap cache
      1998844 K total swap
            0 K used swap
      1998844 K free swap
       392650 non-nice user cpu ticks
         8073 nice user cpu ticks
        83959 system cpu ticks
     10448341 idle cpu ticks
        91904 IO-wait cpu ticks
            0 IRQ cpu ticks
         2189 softirq cpu ticks
            0 stolen cpu ticks
      2042603 pages paged in
      2614057 pages paged out
            0 pages swapped in
            0 pages swapped out
     42301605 interrupts
     94581566 CPU context switches
   1382755972 boot time
         8567 forks

Üstteki birkaç satır toplam belleği, boş belleği vb. kullanışlı verileri gösterir.

top komutu

top komutu, genellikle işlem başına bellek ve CPU kullanımını kontrol etmek için kullanılır. Bununla birlikte, toplam bellek kullanımını da rapor eder ve toplam RAM kullanımını izlemek için kullanılır. Komut çıktısında bulunan header alanı sonuca yönelik detaylı bilgileri içermektedir.

root@yazilimdersi: top
top - 15:20:30 up  6:57,  5 users,  load average: 0.64, 0.44, 0.33
Tasks: 265 total,   1 running, 263 sleeping,   0 stopped,   1 zombie
%Cpu(s):  7.8 us,  2.4 sy,  0.0 ni, 88.9 id,  0.9 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   8167848 total,  6642360 used,  1525488 free,  1026876 buffers
KiB Swap:  1998844 total,        0 used,  1998844 free,  2138148 cached
  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
 2986 enlighte  20   0  584m  42m  26m S  14.3  0.5   0:44.27 yakuake
 1305 root      20   0  448m  68m  39m S   5.0  0.9   3:33.98 Xorg
 7701 enlighte  20   0  424m  17m  10m S   4.0  0.2   0:00.12 kio_thumbnail

Komut çıktısında başlıktaki KiB Mem ve KiB Swap satırlarını görebilirsiniz. Hafızanın toplam, kullanılan ve boş miktarlarını gösterirler. Arabellek ve önbellek bilgileri, free komut gibi burada da mevcuttur.

htop komutu

top komutuna benzer şekilde, htop komutu da çeşitli diğer ayrıntılarla birlikte bellek kullanımını göstermektedir.

Üstteki alanda RAM ile birlikte Cpu kullanımını ve buna karşılık gelen swap kullanımını göstermektedir.

Böylelikle bellek kontrolünde kullanabileceğimiz en basit ve kullanışlı komutları gözden geçirmiş olduk. Burada önemli olan bu verilerin periyodik olarak sunucularınızda kontrol edilmesi ve gerektiği anda aksiyon alınmasıdır. Çünkü sunucularda bellekten kaynaklı herhangi bir sorun ile karşılaşıldığı anda sistemin çökmesi olası durumlardandır.

]]>
Windowsda Arka Plan Resmi Değiştirme http://yazilimdersi.info/makaleler/detay/115/windowsda-arka-plan-resmi-degistirme Sat, 05 Dec 2020 00:00:00 +0000 mstfchelik Aktif PC kullanıcıları olarak bilgisayarlarımız bizim artık yaşam alanlarımız olmuş durumda. Geliştiriciler olarak uzun süreler karşısında oturup yoğun çalışmalar ve projeler üretmekteyiz. Durum böyle olunca bilgisayarımız üzerine badgeler yapıştırmak, arka plan resmini kişisel tercihlerimize göre düzenlemek kaçınılmaz oluyor. Manual olarak cursorun Masaüstünde sağa tıklayıp Özelliklere erişilmesi ile arka plan resmi düzenlenebilmektedir. Ancak kullandığımız cihaz eğer şirkete ait bir bilgisayar ise, muhtemelen aşağıdaki şekilde bir uyarı ile karşılaşacaksınız.

Bu tarz bir durumla karşılaştığınızda izlemeniz gereken adımlar şu şekildedir;

1. Öncelikle Masaüstünde change-background.bat isminde bir dosya oluşturalım.
2. Daha sonra bu dosyası içerisine aşağıdaki kod parçacığını ekleyelim.
reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v Wallpaper /t REG_SZ /d  [DOSYA_PATHI] /f
RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters

Yaptığımız işlem aslında registry key üzerinde güncelleme yaparak direkt olarak arka resmi atanmasına imkan sunmaktadır.

Yukarıdaki kodlamada [DOSYA_PATHI] alanına değiştirmek istediğiniz dosya pathini yapıştırmanız gerekmektedir.

İkinci satırda RUNDLL32.EXE komutu ile değiştirilen arka plan resminin anlık olarak yansıtılması sağlanmaktadır. Aksi takdirde üstteki kodlama çalıştırsanız bile arka plan resmini değiştirmeyecektir.

Komut satırında çalıştırılan kodlama herhangi bir tehlike arz etmemektedir. Değiştirilecek olan ekran resminin özelliklerinin uygun formatta bulunması önemlidir.

]]>
Temel SSH Komutları http://yazilimdersi.info/makaleler/detay/114/temel-ssh-komutlari Mon, 30 Nov 2020 00:00:00 +0000 mstfchelik Linux tabanlı sunucularda, sunucu yönetimi için sıklıkla kullanılan ssh komutları bulunmaktadır. Bu komutları kullanarak sunucu üzerinde herhangi bir GUI yani arayüze gerek kalmaksızın terminal üzerinden birçok işleminizi gerçekleştirebilirsiniz. Zaten birçok sunucu yöneticisi terminaller üzerinden çalışmakta ve komutların çoğunu sürekli kullandıklarından dolayı ezbere bilmektedir diyebiliriz.

Makalemizde detaylandırılacak olan popüler komutların listesinin tümüne aşağıdan erişebilirsiniz.

SSH Komutu Açıklaması
ls Mevcut dizin altındaki dosyaların bilgilerini listeler.
cd Dizin değiştirmede kullanılır.
mkdir Yeni bir klasör oluşturmada kullanılır.
touch Dosya oluşturmada kullanılır.
rm Dosya silmede kullanılır.
cat Dosya içeriğini görüntülemede kullanılır.
pwd Mevcut dizinin full pathini gösterir.
cp Dosya veya dizin kopyalamada kullanılır.
mv Dosya veya dizin taşımada kullanılır.
grep Dosya içerisinde veya komutta herhangi bir text arama yapılırken kullanılır.
find Dosya ve dizin içerisinde aramada kullanılır.
vi/nano Kullanışlı text editorleri açmada kullanıır.
history Çalıştırılan son 50 komutu listeler.
clear Komut ekranını temizler.
tar Ziplenmiş dosyayı açmada kullanılır.
wget Dosyaları internetten indirmede kullanılır.
du Dosya boyutunu görüntülemede kullanılır.

Şimdi yukarıda listelediğimiz komutları detaylı şekilde madde madde inceleyelim.

ls komutu

ls komutu, tüm dosyaları ve dizinleri listelemede kullanılır. Terminalde ls komutunu girdikten sonra şuna benzer bir çıktı ile karşılaşacaksınız;

root@yazilimdersi:/home/yazilimdersi# ls
var    wwww    html    config    vendor    app    controller 

Bu komuta ek olarak aşağıdaki parametrelerle daha detaylı bilgiler alabilirsiniz;

  • -l: Listelenen dosyaların detaylı bilgisi ile birlikte görüntülenir. Örneğin dosya boyutu, güncellenme zamanı, sahibi vs.
  • -a: Gizlenen dosyalarında listelenmesinde kullanılır.

cd komutu

cd komutu, dosyalar arasında geçiş yapmak amacıyla kullanılır. Zaten bu komut ismini change directory ifadesinin baş harflerinden almaktadır. Çok basit ve kullanışlı bir komuttur. Tek yapmanız gereken gitmeniz gereken dosya pathini cd komutunun ardından yazmak;

cd [DOSYA_YOLU]

// sunucunuza ait ana dizine erişmek için home yazmanı gerekir.
cd home

// ya da farklı bir dizin altındaki klasöre ulaşmak için bu dizini direk full path olarak yazabilirsiniz.
cd /var/www/html/yazilimdersi/controller

Mevcut olan dizinden bir önceki dizine erişmek için .. (iki nokta) kullanmanız gerekmektedir.

root@yazilimdersi:/var/www/html/yazilimdersi/controller# cd ..
root@yazilimdersi:/var/www/html/yazilimdersi#

mkdir komutu

mkdir komutu, dizin oluşturmak amacıyla kullanılır. Zaten bu komut Make Directory ifadesinin kısaltmasıdır. Komutun syntaxı şu şekildedir;

mkdir [DIZIN_ISMI]

// Örneğin, "model" dizini oluşturmak istiyorsanız bu komutu yazmanız yeterli
mkdir model

touch komutu

touch komutu, dosya oluşturmak amacıyla kullanılır. Komutun syntaxı şu şekildedir;

touch [DOSYA_ISMI]

// Örneğin, "app.json" dosyası oluşturmak istiyorsanız bu komutu yazmanız yeterli
touch app.json

rm komutu

rm komutu, dosya veya dizin silme amacıyla kullanılır. Dosya silmede kullanılan komutun syntaxı şu şekildedir;

rm [DOSYA_ISMI]

// Örneğin, "app.json" dosyasını silmek istiyorsanız bu komutu yazmanız yeterli
rm app.json

Eğer bir dizini yani klasörü silmeyi amaçlıyorsanız -r parametresi ile rm komutunu çağırmanız gerekmektedir.


rm -r /var/www/html/yazilimdersi/app

cat komutu

cat komutu, dosya içeriğini görüntülemede kullanılır. Dosya içeriği görüntülemede kullanılan komutun syntaxı şu şekildedir;

cat [DOSYA_ISMI]

Eğer birden fazla dosyanın içeriğini birleştirip tek bir dosya oluşturmayı düşünüyorsanız aşağıdaki komutu çalıştırabilirsiniz;


cat dosya1.txt dosya2.txt > finaldosya.txt

Bu komutla birlikte dosya1.txt ve dosya2.txt içeriği merge edilip finaldosya.txt oluşturulup içerisine yapıştırılır.

pwd komutu

pwd komutu, mevcut dizine ait full pathi görüntülemede kullanılır;

root@yazilimdersi:/var/www/html/yazilimdersi/controller# pwd
/var/www/html/yazilimdersi/controller

Linux sunucularda en kullanışlı komutlardan birisi pwd komutudur. Çünkü herhangi bir path üzerinde bir işlem gerçekleştirmeden önce ilgili pathin doğrulanmasını kolaylaştırmaktadır.

cp komutu

cp komutu, dosya veya dizin kopyalama işlemlerinde kullanılır. Bu komutun syntaxı şu şekildedir;

cp [PARAMETRELER] [KAYNAK_DOSYA_DIZIN] [HEDEF_DOSYA_DIZIN]

// Örneğin "dosya1.txt" dosyamız var ve bunun kopyasını aynı dizinde "dosya2.txt" ismiyle kopyalamak istiyorsunuz
cp dosya1.txt dosya2.txt 

// Eğer direkt dizinin bir kopyasını başka bir dizin altında kopyalamak istiyorsanız
cp /var/www/htm/yazilimdersi/app /home/user/project

cp komutunda bulunan parametre alanı zorunlu değildir. Bu alana gelebilecek parametreler şu şekildedir;

  • -f: Eğer hedef dosya veya klasöre yazma yetkimiz yoksa onu silip yeni dosya veya dizin oluşturulmasını sağlar.
  • -u: Eğer kaynak dosya hedef dosyadan daha güncel ve yeni ise kopyalamayı gerçekleştirmede kullanılır.
  • -n: Eğer aynı isimde bulunan dosya varsa üzerine yazılmasını engeller.
  • -a: Dosyaları arşivlemede kullanılır.

Dosyaların çoğaltılmasının aksine, klasörlerin kopyalanması için -R seçeneğini kullanmanız gerekir. Bu parametre dizin içindeki tüm klasörlerin ve dosyaların kopyalanmasına izin verir.

cp -R /var/www/html/yazilimdersi/app /home/etc/

mv komutu

mv komutu, aslında cp komutuna benzer bir komuttur. Tek fark ise, mv komutunda dosyalar veya dizinler direkt taşınmaktadır. Yani kaynak dizinde herhangi bir dosya kalmayacaktır bu komut çağrıldıktan sonra;

mv [KAYNAK_DOSYA_DIZIN] [HEDEF_DOSYA_DIZIN]

// Örneğin "dosya1.txt" dosyamız var ve bunu /home/yazilimdersi/app dizini altına taşıyalım
mv dosya1.txt /home/yazilimdersi/app 

// Eğer direkt bir dizini başka bir dizin altına kopyalamak istiyorsanız
mv /var/www/htm/yazilimdersi/app /home/user/project

grep komutu

grep komutu, text ile arama işlemlerinde kullanılır.

grep 'Exception' error.log

Yukarıdaki komut error.log dosyası içerisinde 'Exception' ifadesi geçen satırları dönmektedir. Örnek sonuç aşağıdaki şekilde görüntülenir;

root@yazilimdersi:/var/www/html/yazilimdersi/logs# grep 'Exception' error.log
NullPointer Exception has been crashed on this line
ZeroDivider Exception .....
MathException ....
Exception ...

Eğer yapılan aramalarda küçük büyük harf ayrımı olmadan arama yapılsın istiyorsanız -i parametresini kullanmanız gerekmektedir.

find komutu

find komutu, girilen kriterleri (ad, boyut, dosya türü, vb.) karşılayan dosyaları aramada kullanılır. Komutun syntax yapısı şu şekildedir;

find [ARAMA_DIZINI] [PARAMETRELER] [ARANACAK_KELIME]
[ARAMA_DIZINI] aramanın yapılacağı dizini belirlemede kullanılmaktadır;
  • / (slash) Tüm dizinde arama yapmada kullanılır.
  • . (dot) Mevcut dizinde arama yapmada kullanılır.
  • ~ (tilde) home dizini altında arama yapmada kullanılır.
[PARAMETRELER] arama esnasında kullanılacak olan alanı belirler;
  • -name Dosya ismine göre aramada kullanılır.
  • -user Kullanıcıya göre arama yapmada kullanılır.
  • -size Dosya boyutuna göre aramada kullanılır.
[ARANACAK_KELIMA] arama yapmada kullanılacak ifadedir.
find / -name “index”

Yukarıdaki komut isminde "index" geçen ve sunucuda bulunan tüm dosyalarda tarama yapılmasında kullanılmaktadır.

vi/nano komutu

vi ve nano, Linux sunucularda kullanılan popüler text editorlerdir.


// vi editor ile dosya çağrılırsa
vi [DIZIN_ISMI]

//nano editor ile dosya çağrılırsa
nano [DIZIN_ISMI]

Eğer komutta geçen dizin ismi yok ise, editor otomatik olarak bu dosyayı oluşturup açacaktır.

history komutu

history komutu, Linux sunucularda çalıştırılan son komutların listelenmesinde kullanılır. Bu komutta ikinci parametre olarak görüntülenecek komutların sayısı girilmelidir

root@yazilimdersi:/var/www/html/yazilimdersi/controller# history 5
vi index.txt
find / -name "file"
cp /var/wwww/html/yazilimdersi /home/etc
ls
pwd

Yukarıdaki komutta son 5 komutun listelenmesi sağlanmıştır.

clear komutu

clear komutu, terminal ekranında görüntülenen görüntü kirliliğini ortadan kaldırmada kullanılır.

tar komutu

tar komutu, .tar.gz dosyalarını oluşturmada veya paketlenmiş dosyadan çıkarmada kullanılmaktadır. Linux sunucularda aktif olarak kullanılan bir komuttur.

// Herhangi bir dizini .tar.gz formatında arşivlemek istiyorsanız bu komutu kullanmalısınız
tar cvzf archive.tar.gz /var/www/html/yazilimdersi

// .tar.gz formatındaki bir arşivi açmak için bu komutu kullanmalısınız
tar xvzf archive.tar.gz

Yukarıdaki komutlarda dikkat ederseniz farklı harf dizimleri ile komutlar çalıştırılmaktadır.

  • x: tar komutuna arşivlenmiş dosyayı açmasını söyler.
  • c: tar komutuna dosyanın arşivlemesi gerektiğini söyler.

wget komutu

wget komutu, internetde bulunan herhangi bir dosyaya erişip indirmede kullanılır. Örneğin bir websitesinde bulunan dosyaya erişip komutun çalıştırıldığı dizine indirilmesini aşağıdaki komutla sağlarız.

wget http://google.com

du komutu

du komutu, dosya ve dizinlerin boyutunu görüntülemede kullanılmaktadır. Zaten bu komut Disk Usage ifadesinin kısaltmasıdır. Komutun syntaxı şu şekildedir;

du [DIZIN_PATH]

Ancak bu komutun daha okunur olmasını sağlamak için -h parametresini eklememiz gerekmektedir.

root@yazilimdersi:/var/www/html/yazilimdersi/controller# du -h /var/www/html/yazilimdersi/app
120M /var/html/yazilimdersi/app/controllers
10K  /var/html/yazilimdersi/app/models
125K /var/html/yazilimdersi/app/views
11K  /var/html/yazilimdersi/app/config
.....
...

]]>
Android ile Retrofit HTTP Kütüphanesi Kullanımı http://yazilimdersi.info/makaleler/detay/113/android-ile-retrofit-http-kutuphanesi-kullanimi Sun, 29 Nov 2020 00:00:00 +0000 mstfchelik Günümüz projelerinde veriler sunucular üzerinde tutulmakta ve mobil uygulamalar bu verilere online olarak API çağrıları üzerinden erişebilmektedir. API çağrılarını daha sistematik ve fonksiyonel biçime getirmek amacıyla Square firması tarafından Retrofit kütüphanesi oluşturulmuştur. Bu kütüphane ile birlikte proje structure yapısı daha kolay anlaşılır bir hale dönüşmüştür. Retrofit e benzer işlevi gören bazı diğer kütüphanelerde bulunmaktadır. Ancak performans, kolay kullanım ve modüler kurgusu sayesinde Retrofit bir kaç adım öndedir.

Örnek Retrofit Projesi Oluşturalım

Yapacağımız örnek projede json formatta response dönen ücretsiz api çağrısından (Space Flgihts APIsi üzerinden) veriyi parse edip RecyclerView componenti kullanarak listelemeye çalışacağız.

1. File => New Project seçeneğine tıklayalım. Sonrasında açılan ekranda Empty Activity seçeneğini seçip Next butonuna tıklayalım. 
2. Bir sonraki ekranda uygulamanın ismini, paket adını ve kayıt edileceği dizini belirleyelim. İsterseniz uygulamanın adını SampleRetrofit, paket ismi olarak ise info.yazilimdersi.sampleretrofit olarak belirleyelim.
3. Bu işlemler sonrasında projemiz oluşturuldu. Şimdi sırada projemize ait genel klasörleme ve sınıf yapısının nasıl oluşturacağımız konusunda.
Yukarıda projemize ait ana yapıyı gözlemleyebilirsiniz. Bu sınıfları şimdilik içi boş olacak şekilde oluşturalım. Adım adım içlerine konulacak kodları aşağıda sizlerle paylaşacağız.
4. app dizini altında bulunan build.gradle dosyasını açıp Retrofit, GSON kütüphanelerini ekleyelim.
dependencies {
    .........

    // gson kütüphanesini ekleyelim
    implementation 'com.google.code.gson:gson:2.8.6'
    
    // retrofit kütüphanelerini ekleyelim
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
}
5. Projemizde internet üzerinden API çağrısı yapılacağı için AndroidManifest.xml dosyasında INTERNET iznini almamız gerekmektedir kullanıcıdan.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.yazilimdersi.sampleretrofit">

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

    <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">
        <activity android:name=".activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Model Sınıflarını Oluşturalım

Projemizde ücretsiz ve herhangi bir api keye ihtiyacımız olmayan Spaceflight News API servisini kullanacağız. Projenin başında model dizini altında oluşturduğumuz Article, Launch ve Event sınıflarını neden oluşturduğumuza bakalım.

Get Articles linkine tıklağınızda açılan sayfada Try Out butonuna basıp response dönen içeriği inceleyelim.

Aynı içeriğe https://test.spaceflightnewsapi.net/api/v2/articles linki üzerinden de erişebilirsiniz. Bu API üzerinden uzayla alakalı gelişmeler ve ilgili makalalere erişim sağlanmaktadır. Açılan linkin içeriğini JSON veriler formatlamada ve görüntülemede sıkça kullandığım JsonViewer linkinde inceleyelim.
6. Json olarak dönen cevaba uygun formatta model dizini altındaki Article sınıfının içeriğini oluşturalım.
package info.yazilimdersi.sampleretrofit.model;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;
import java.util.List;

public class Article {
    @SerializedName("id")
    private String id;

    @SerializedName("title")
    private String title;

    @SerializedName("url")
    private String url;

    @SerializedName("imageUrl")
    private String imageUrl;

    @SerializedName("newsSite")
    private String newsSite;

    @SerializedName("summary")
    private String summary;

    @SerializedName("publishedAt")
    private String publishedAt;

    @SerializedName("updatedAt")
    private String updatedAt;

    @SerializedName("featured")
    private Boolean featured;

    @SerializedName("launches")
    private List<Launch> launches = new ArrayList<Launch>();

    @SerializedName("events")
    private List<Event> events = new ArrayList<Event>();

    public String getTitle() {
        return title;
    }

    public String getSummary() {
        return summary;
    }

    public List<Launch> getLaunches() {
        return launches;
    }

    public String getImageUrl() {
        return imageUrl;
    }
    
}
7. Article sınıfı içerisinde tanımladığımız ve makale ile ilişkili herhangi bir event yada launch olup olmadığını belirlemede kullanılan Launch ve Event sınıflarının içerisine aşağıdaki kod parçacıklarını ekleyelim.
package info.yazilimdersi.sampleretrofit.model;

import com.google.gson.annotations.SerializedName;

public class Launch {
    @SerializedName("id")
    private String id;

    @SerializedName("provider")
    private String provider;
}

package info.yazilimdersi.sampleretrofit.model;

import com.google.gson.annotations.SerializedName;

public class Event {
    @SerializedName("id")
    private String id;

    @SerializedName("provider")
    private String provider;
}

Retrofit Instance Oluşturalım

Projemizde atılacak olan API requestlerinin ana yapısı olan Retrofit'e ait kurguyu api dizini altında bulunan ApiClient.java dosyası olarak belirledik. Burada Retrofit Builder sınıfını kullanarak API yapısının oluşturulması sağlanacaktır. Ayrıca API ya ait ana linkinde burada tanımlanması gerekmektedir.

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
    public static final String BASE_URL = "https://test.spaceflightnewsapi.net/api/v2/";
    private static Retrofit retrofit = null;


    public static Retrofit getClient() {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

Endpointlerin Belirlenmesi

Endpointler proje süresince kullanılacak olan ve farklı sınıflardan da erişimi kolay olacak şekilde interface yapısına uygun şekilde ayarlanır. Ek olarak, yapılan API çağrılarında dönüş verisi her zaman Call<Article> gibi parametreleştirilmiş bir Call<T> nesnesidir.

import info.yazilimdersi.sampleretrofit.model.Article;
import retrofit2.Call;
import retrofit2.http.GET;

public interface ApiInterface {
    @GET("articles")
    Call<List<Article>> getArticles();
}

Böylelikle Retrofit ile yapılan çağrıda https://test.spaceflightnewsapi.net/api/v2/articles linkine GET ile request atılmış olacaktır.

Retrofit kütüphanesinde HTTP requestlerine yönelik (GET, POST, PUT etc.) gibi annotationlar ve (@Query, @Path, @Body etc.) gibi özel annotationlar bulunmaktadır. Endpointin talebine uygun olarak bu tanımlamaları gerçekleştirmeniz gerekecektir. Kısaca specific annotationları özetleyelim;

  • @Path: Endpoint linkinde iletilmesi gereken herhangi bir parametre olduğunda kullanılır Örneğin; /article/{id} ile request atılmak istenildiğinde @Path kullanılarak id verisi setlenebilir.
  • @Query: Endpointe bağlı olarak iletilecek olan query parametrelerinde kullanılır. Örneğin; /articles?order=id&isfeatured=true tarzı requestleri sağlar.
  • @Body: POST ile iletilecek olan body verisinde kullanılır.
  • @Header: Atılacak olan requestde headerde iletilmesi gereken herhangi bir bilgi varsa kullanılır.

İlk API Çağrısının Yapılması

MainActivity.java sınıfı içerisinde ilk API çağrımızı gerçekleştirelim. Gerçekleştirilecek API çağrısı ile birlikte SpaceFlight API üzerinden yayımlanan makalelere erişmemiz gerekecektir.

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
import info.yazilimdersi.sampleretrofit.R;
import info.yazilimdersi.sampleretrofit.api.ApiClient;
import info.yazilimdersi.sampleretrofit.api.ApiInterface;
import info.yazilimdersi.sampleretrofit.model.Article;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

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

        ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);

        Call<List<Article>> call = apiService.getArticles();
        call.enqueue(new Callback<List<Article>>() {
            @Override
            public void onResponse(Call<List<Article>> call, Response<List<Article>> response) {
                List<Article> articles = response.body();
                Log.d("SampleRetrofit", "Makale sayısı : " + articles.size());
            }

            @Override
            public void onFailure(Call<List<Article>>call, Throwable t) {
                Log.e("SampleRetrofit", t.toString());
            }
        });
    }
}

Retrofit kütüphanesi API requestini background thread üzerinden atıp dönen response ile birlikte failure veya success durumuna göre UI threadini bilgilendirecektir. Projeyi Debug ile çalıştırdığımızda aşağıdaki şekilde verilerin model içerisine nasıl enjekte edildiğini gözlemleyebilirsiniz.

RecyclerView ile Makalelerin Görüntülenmesi

Makaleler artık API üzerinden bize ulaşmaktadır. Sırada yapılacak işlem makalelerin önyüzde görüntülenmesini sağlayacak kodlamayı tanımlamaktır. Öncelikle build.gradle dosyasına RecyclerView'e ait dependecynin eklenmelidir. Ayrıca Glide kütüphanesini kullanarak makaleye ait resimleri yükleyeceğiz.


dependencies {
    .....

    //recyclerview kütüphanesi
    implementation 'androidx.recyclerview:recyclerview:1.1.0'

    //glide kütüphanesi
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

}

Hazırlanacak listelemede makaleye ait resim, başlık, içerik ve events sayısının görüntülenmesi sağlanacaktır. Bunun için layout içerisinde 1 adet ImageView, 3 adet TextView ayarlamamız gerekecektir.

8. colors.xml dosyasını açıp uygulamada kullanılacak renklere ait verileri aşağıdaki şekilde ekleyelim.
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
 
    <color name="orange">#FF3909</color>
    <color name="colorAccentDark">#00B482</color>
 
    <color name="colorBlack">#555555</color>
    <color name="colorWhite">#FFFFFF</color>
    <color name="colorGrey">#707070</color>
    <color name="colorGreyLight">#8A8A8A</color>
</resources>
9. list_item_article.xml dosyasını açıp uygulamada kullanılacak renklere ait verileri aşağıdaki şekilde ekleyelim.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/movies_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:minHeight="72dp"
    android:orientation="horizontal"
    android:padding="16dp">

    <ImageView
        android:id="@+id/articleImageView"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginRight="16dp"
        android:layout_centerInParent="true"
        android:scaleType="centerCrop" />


    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/titleTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:paddingRight="16dp"
            android:textColor="@color/colorBlack"
            android:textSize="16sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/summaryTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:maxLines="3"
            android:paddingRight="16dp"
            android:textColor="@color/colorGreyLight" />

        <TextView
            android:id="@+id/launchesTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/colorPrimaryDark"

    </LinearLayout>

</LinearLayout>
10. ArticlesAdapter.java sınıfı içerisine API den dönen makalelerin verileri işlenmelidir.
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.List;
import info.yazilimdersi.sampleretrofit.R;
import info.yazilimdersi.sampleretrofit.model.Article;

public class ArticlesAdapter extends RecyclerView.Adapter<ArticlesAdapter.ArticleViewHolder> {
    private List<Article> articles;
    private Context context;

    public static class ArticleViewHolder extends RecyclerView.ViewHolder {
        LinearLayout articleLinearLayout;
        TextView titleTextView;
        TextView summaryTextView;
        TextView launchesTextView;
        ImageView articleImageView;


        public ArticleViewHolder(View v) {
            super(v);
            articleLinearLayout = (LinearLayout) v.findViewById(R.id.articleLinearLayout);
            titleTextView = (TextView) v.findViewById(R.id.titleTextView);
            summaryTextView = (TextView) v.findViewById(R.id.summaryTextView);
            launchesTextView = (TextView) v.findViewById(R.id.launchesTextView);
            articleImageView = (ImageView) v.findViewById(R.id.articleImageView);
        }
    }

    public ArticlesAdapter(List<Article> articles, Context context) {
        this.articles = articles;
        this.context = context;
    }

    @Override
    public ArticlesAdapter.ArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_article, parent, false);
        return new ArticleViewHolder(view);
    }


    @Override
    public void onBindViewHolder(ArticleViewHolder holder, final int position) {
        holder.titleTextView.setText(articles.get(position).getTitle());
        holder.summaryTextView.setText(articles.get(position).getSummary());
        holder.launchesTextView.setText(articles.get(position).getLaunches().size() + " launches");

        Glide.with(context).load(articles.get(position).getImageUrl()).into(holder.articleImageView);
    }

    @Override
    public int getItemCount() {
        return articles.size();
    }
}
11. Son olarak MainActivity.java sınıfı içerisine RecyclerView oluşturup parametrik olarak Article sınıfını iletmemiz gerekecektir.
public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.articlesRecyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);

        Call<List<Article>> call = apiService.getArticles();
        call.enqueue(new Callback<List<Article>>() {
            @Override
            public void onResponse(Call<List<Article>> call, Response<List<Article>> response) {
                List<Article> articles = response.body();
                recyclerView.setAdapter(new ArticlesAdapter(articles, getApplicationContext()));
            }

            @Override
            public void onFailure(Call<List<Article>>call, Throwable t) {
                Log.e("SampleRetrofit", t.toString());
            }
        });
    }
}

Böylelikle Retrofit kullanarak oluşturduğumuz örnek projeyi tamamladık. Artık elimizde json dönen bir API üzerinden parsing gerçekleştirebilen bir kodlama bulunmakta. Projeye ait ekran görüntüsü şu şekildedir;

]]>
Android Uygulamalarda Text to Speech Kullanımı http://yazilimdersi.info/makaleler/detay/112/android-uygulamalarda-text-to-speech-kullanimi Sat, 28 Nov 2020 00:00:00 +0000 mstfchelik Text to Speech, Android uygulamalar için kullanıcı deneyimini artırmaya yönelik en önemli kütüphanelerdendir. Kullanıcıların deneyimini artırmak dışında geliştiricilerinde uygulamalarda daha farklı fikirler ortaya koymasına da birçok kapı açmıştır. Örneğin, yüksek kullanıcı kitlesine sahip Google Translate uygulamasında yapılan çevirinin seçili dile göre okutulması kullanıcı deneyimini yüksek miktarda artırmaktadır.

Bu makalemizde text to speech özelliğine ait bir örnek proje oluşturup, kütüphanenin sunduğu fonksiyonlara bağlı olarak dil değişikliği, okuma hızı ve vurgu seviyesine göre denemeler gerçekleştireceğiz.

Örnek Android TTS Projesi Oluşturulması

Hazırlayacağımız örnekte basit bir editText alanı ile kullanıcının dinamik olarak içerik girebilmesi ve sonrasında girilen içeriğin eklenecek butona tıklanıldığında okunabilmesi hedeflenmektedir.

1. File => New Project seçeneğine tıklayalım. Sonrasında açılan ekranda Empty Activity seçeneğini seçip Next butonuna tıklayalım. 
2. Bir sonraki ekranda uygulamanın ismini, paket adını ve kayıt edileceği dizini belirleyelim. İsterseniz uygulamanın adını SampleTTS, paket ismi olarak ise info.yazilimdersi.sampletts olarak belirleyelim.
3. Bu işlemler sonrasında oluşan MainActivity dosyasına TextToSpeech.OnInitListener interface'ni aşağıdaki şekilde implement edelim.
public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {
4.Interface implementasyonundan sonra zaten uygulama bize onInit(int) metodunu implement etmemize yönelik uyarı vermektedir. Aşağıda bulunan kodlamayı MainActivity sınıfına yapıştıralım.
public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {
    private TextToSpeech textToSpeech;
    private Button speakButton;
    private EditText textEditText;

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

        textToSpeech = new TextToSpeech(getApplicationContext(), this, "com.google.android.tts");

        setVolumeControlStream(AudioManager.STREAM_MUSIC);

        speakButton = (Button) findViewById(R.id.speakButton);

        textEditText = (EditText) findViewById(R.id.textEditText);

        speakButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                speakOut();
            }

        });
    }

    @Override
    public void onDestroy() {
        // Don't forget to shutdown tts!
        if (textToSpeech != null) {
            textToSpeech.stop();
            textToSpeech.shutdown();
        }
        super.onDestroy();
    }

    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {

            int result = textToSpeech.setLanguage(Locale.US);

            if (result == TextToSpeech.LANG_MISSING_DATA
                    || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e("TTS", "Bu dil desteklenmemektedir");
            } else {
                speakButton.setEnabled(true);
                speakOut();
            }

        } else {
            Log.e("TTS", "Initilizationda sorunla karşılaşıldı!");
        }
    }

    private void speakOut() {

        String text = textEditText.getText().toString();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Bundle bundle = new Bundle();
            bundle.putInt(TextToSpeech.Engine.KEY_PARAM_STREAM, AudioManager.STREAM_MUSIC);
            textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, bundle, null);
        } else {
            HashMap param = new HashMap<>();
            param.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC));
            textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, param);
        }

    }
}

Kodlamada eklenen kodları dilerseniz adım adım inceleyelim.

textToSpeech = new TextToSpeech(getApplicationContext(), this, "com.google.android.tts");
kullanılacak olan TTS objesinin tanımlanması gerçekleştirilmektedir. Interface kullanılarak sınıfta onInit() metodu ilmeplement edildiği için this parametresi kullanılmıştır.
setVolumeControlStream(AudioManager.STREAM_MUSIC);
metodu ile uygulamanın audio kontrolunu alması sağlanmaktadır.
int result = textToSpeech.setLanguage(Locale.US);
metodu ile de seslendirmede kullanılacak olan dili setlememiz sağlanmaktadır. Şu anda ne yazıkki Türkçe dil desteği henüz default olarak TTS kütüphanesine eklenmemiştir. Ancak Almanca, Fransızca, Çince, Korece gibi farklı dilleri setleyebilirsiniz.
private void speakOut() {

        String text = textEditText.getText().toString();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Bundle bundle = new Bundle();
            bundle.putInt(TextToSpeech.Engine.KEY_PARAM_STREAM, AudioManager.STREAM_MUSIC);
            textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, bundle, null);
        } else {
            HashMap<String, String> param = new HashMap<>();
            param.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC));
            textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, param);
        }

}
speakOut() metodunda gördüğünüz üzere iki farklı Android SDK versiyonuna göre seslendirme çalışmaktadır. Android Lollipop ve üzeri versiyonarda Bundle uzerinden textlerin iletimi sağlanmaktadır. 5. Uygulamanın arayüz dosyası olan activity_main.xml dosyasına aşağıdaki kodlamayı yapıştıralım.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/icon_app_logo" />

        <EditText
            android:id="@+id/textEditText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello World!" />

        <Button
            android:id="@+id/speakButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="@string/speak" />

    </LinearLayout>


</androidx.constraintlayout.widget.ConstraintLayout>
Böylelikle uygulamamızı tamamlamış olduk. Burada söz etmemiz gereken iki önemli fonksiyon bulunmaktadır.
  • setPitch: Bu metod ile konuşma sırasındaki vurgu seviyesini ayarlayabilirsiniz.
  • setSpeechRate: Bu method kullanılarak konuşma hızını ayarlayabilirsiniz. Default olarak 1 seviyesindedir. Ancak konuşmanın daha hızlı olmasını isterseniz bunu 2 veya 3 olarak setlemeniz yeterli olacaktır.
Son olarak uygulamaya ait arayüz aşağıdaki şekildedir;

]]>
Php ile Gmail SMTP kullanarak Email Gönderimi http://yazilimdersi.info/makaleler/detay/111/php-ile-gmail-smtp-kullanarak-email-gonderimi Wed, 25 Nov 2020 00:00:00 +0000 mstfchelik Dijital platformlarda email ve SMS gönderimleri müşteri ile bağlantıda kalmak için kullanılan en önemli metodlardandır. Kullandığınız veya üyesi olduğunuz birçok siteden gün içerisinde farklı mailler alabilmekteyiz. Örneğin, Facebook, Twitter tarzı sosyal medya hesaplarınızdan arkadaşlarınızın aksiyonları ile alakalı belirli aralıkla bilgilendirme maili almaktayız. Geliştiriciler olarak bizimde hedefimiz yapacağımız projelerde email kullanarak bu tip bilgilendirmeleri kullanıcılara aktarabilmek. Bunun en basit ve uygun yöntemi Gmail SMTP sunucularını kullanarak mail gönderimi yapmaktadır.

Daha önceki bir makalemizde PHP'de mail() metodunu kullanarak email gönderimini sizlerle paylaşmıştık. Ancak mail() metodu güvenilebilir ve kullanışlı bir metod değildir. Çünkü mail metodu ile iletilen mailler direkt sunucu üzerinden iletildiği için Spam klasörüne düşme ihtimali yüksektir. Ayrıca mail içerisine image veya herhangi bir dosya eklemek isterseniz bunu mail() metodu ile sağlayamazsınız.

Bu makalemizde popüler email sağlayıcısı olan Gmail'i kullanarak nasıl mail gönderebileceğimizi adım adım sizlerle paylaşacağız. Öncelikle SMTP kullanımının faydalarını nelerdir onu öğrenelim

  • Daha komplex ve iyi email gönderimi
  • Kendi sunucumuza kurulum gerektirmez
  • Karalisteye düşme ihtimaliniz daha düşük olacaktır. Bu nedenle emailleriniz spam klasörüne düşmez veya seyrek düşer.

Gmail SMTP kullanılarak iletilecek maillerin limiti günlük 100 maildir. Eğer bu limite ulaşırsanız, bir sonraki güne kadar beklemeniz gerekmektedir. Gmail'in mail limitleri ile alakalı daha detaylı bilgiye sahip olmak isterseniz bu linke tıklayabilirsiniz.

Gmail hesabını iki şekilde SMTP olarak kullanabiliriz;

  • Daha az güvenli uygulamalara erişim özelliğini kullanarak
  • Uygulama şifresi kullanarak

1. Gmail'de daha az güvenli uygulama erişimi özelliği

Bu yöntemde öncelikle Gmail ayarlarında bulunan daha az güvenli uygulamalara erişim iznini açmanız gerekmektedir. Google bu ayarı açmanızla birlikte artık mail adresinize ait orijinal şifreyi kullanarak mail atılmasına izin verdiğinizi kabul etmektedir. Bu ayarı gerçekleştirmek için linke tıklayabilirsiniz.

 

2. Gmail'de uygulama şifresi özelliği

Uygulama şifresi özelliği ile Gmail geçici bir şifre tanımlamanıza imkan sunmaktadır. Burada izlenmesi gereken adımlar şu şekildedir;

a. Öncelikle Gmail hesabınıza ait güvenlik sayfasına buradan tıklayarak erişiniz.

b. Bu sayfada aşağıda bulunan Google'da oturum açma alanına geliniz. Bu alanda bulunan 2 adımlı doğrulama seçeneği kapalı ise açmanız gerekmektedir. Bunun için 2 Adımlı Doğrulama seçeneğine tıklayın.

c. Açılan sayfada Başlata basıp iki adımlı doğrulamada seçeceğiniz metodu belirleyin. Burada SMS, Arama, Telefonunuzdaki Gmail hesabı vs metodları bulunmaktadır. En pratik olan Gmail hesabı kurulu olan telefonunuza mobil bildirim gelmesi konusudur. Sonrasında ayrıca SMS veya telefon araması ile doğrulama yapmanız gerekmektedir.

Bu işlemin ardından 2 adımlı doğrulama seçeneğiniz aktif hale gelmiştir. Ayrıca güvenlik sayfasınıza geri döndüğünüzde artık Uygulama şifreleri alanınında gözüktüğünü gözlemleyebilirsiniz. Güvenlik sayfasına erişim için buraya tıklayınız.

d. Uygulama şifreleri sayfasına buraya tıklayarak erişebilirsiniz. Açılan sayfada sizden uygulama tipi ve cihaz seçimi talebinde bulunacaktır. Bunun önemli bir yanı yoktur. Genellikle uygulama tipi kısmına Diğer secip projemin ismini yazmaktayım. Böylelikle Gmail SMTP özelliğini farklı projelerde kullammak istediğimde farklı şifreler oluşturabilirim.

e. Diğer seçeneği seçilip uygulamanıza ait isim girdikten sonra Oluştur butonuna basınız. Sonrasında popup ekranda 16 karakterli uygulama şifreniz aşağıdaki şekilde görüntülenecektir. Bu şifreyi başkaları ile paylaşmayınız. Orjinal Gmail şifresinin görünmesi kadar güvenlik problemi içermez ancak bu bilgiye sahip olan herhangi bir kişi sizin adınıza SMTP üzerinden mail atabilir!

Böylelikle Gmail adresimizi direkt mail gönderimi yapacak şekilde ayarlamış olduk. İkinci method ile yapılan gönderimlerin ne kadar önemli olduğunu tekrardan vurgulamak istedim. Şimdi SMTP sunucularında gerekli config ayarları nelerdir. Onları inceleyelim. Gmail'e ait SMTP ayarları aşağıdaki gibidir;

  • SMTP Sunucusu: smtp.gmail.com
  • SMTP Kullanıcı Adı: Gmail adresiniz, örneğin [email protected]
  • SMTP Şifresi: Gmail şifreniz veya uygulama şifreniz
  • SMTP Port: 587 veya 465
  • TLS/SSL: Gerekli

PHPMailer ile Mail Gönderimi

Şu an elimizde kodlamada kullanılacak olan SMTP sunucuya ait config bilgileri bulunmakta. En popüler PHP kütüphanesi olan PHPMailer ile SMTP ayarını yapıp mail atabileceğimiz örnek bir kod geliştirelim. Aşağıdaki adımları izleyerek projemizi oluşturalım.

a. Öncelikle bu linke tıklayarak PHPMailer kütüphanesinin Github kodlarına erişelim. Buradaki Github kodlarını Clone or Download seçeneğine tıklayarak bilgisayarınıza indirin.

b. İndirme işleminin ardından indirilen projede examples dizini altında gmail.phps dosyası bulunmaktadır. Bu dosya içerisinde halihazırda tanımlanmış Gmail ayarları bulunmaktadır.

use PHPMailer\PHPMailer\PHPMailer;

require '../vendor/autoload.php';

//Create a new PHPMailer instance
$mail = new PHPMailer;

//Tell PHPMailer to use SMTP
$mail->isSMTP();

//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;

//Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';
// use
// $mail->Host = gethostbyname('smtp.gmail.com');
// if your network does not support SMTP over IPv6

//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;

//Set the encryption system to use - ssl (deprecated) or tls
$mail->SMTPSecure = 'tls';

//Whether to use SMTP authentication
$mail->SMTPAuth = true;

//Username to use for SMTP authentication - use full email address for gmail
$mail->Username = "[email protected]";

//Password to use for SMTP authentication
$mail->Password = "yourpassword";

//Set who the message is to be sent from
$mail->setFrom('[email protected]', 'First Last');

//Set an alternative reply-to address
$mail->addReplyTo('[email protected]', 'First Last');

//Set who the message is to be sent to
$mail->addAddress('[email protected]', 'John Doe');

//Set the subject line
$mail->Subject = 'PHPMailer GMail SMTP test';

//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->msgHTML(file_get_contents('contents.html'), __DIR__);

//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';

//Attach an image file
$mail->addAttachment('images/phpmailer_mini.png');

//send the message, check for errors
if (!$mail->send()) {
    echo "Mailer Error: " . $mail->ErrorInfo;
} else {
    echo "Message sent!";
}

Bu projede Gmail SMTP sunucunun sorunsuz çalışması için bize ait olan kullanıcı adı (username), şifre (password) ve email alıcı adresi (email recipient address) verilerinin değiştirilmesi gerekmektedir. Ayrıca dosya ismini gmail.php olarak güncellemeniz gerekmektedir.

Artık projemiz mail gönderimine uygun şekilde. Tek yapmanız gereken proje kodlarını web sunucunuzda bir uygulama altına koymanız. Sonrasında http://projeniz.com/PHPMailer-master/examples/gmail.php linki gibi bir link üzerinden kodunuzu çalıştırdığınızda mail atma işleminin başarılı şekilde gerçekleştiğini gözlemleyebilirsiniz.

Wordpress Mail SMTP ile Email Gönderimi

Dünyanın en popüler blog yapısı olan Wordpress'te bir websiteniz varsa ve mail gönderimi yapmak istiyorsanız, WP Mail SMTP pluginini indirip kullanabilirsiniz.

a. Öncelikle yapmanız gereken Wordpress sitenize ait admin sayfasına giriş yapınız.

b. Sonrasında solda bulunan menüden Eklentiler >> Ekle sekmesine tıklayınız.

c. WP Mail SMTP diye arama yaparak eklentiyi yükleyiniz.

d. Yükleme işleminin ardından Eklentiler > Yüklü Eklentiler sayfasını açıp Ayarlar‘a tıklayın ve WP Mail SMTP ayarlarına erişelim.

e. Açılan ayarlar sayfasında bize ait olan SMTP bilgilerinin eksiksiz olarak girilmesi gerekmektedir.

 

Yukarıda rakamlarla tanımlanan alanların bilgileri şu şekildedir;
  • SMTP Host – smtp.gmail.com olarak giriniz.
  • SMTP Port – Varsayılan Gmail SMTP sunucu portu (SSL için 465 ve TSL için 587’dir).
  • Şifreleme – Şifreleme kullanmak her zaman önerilir. Yukarıda seçtiğiniz porta uygun şekilde seçiniz.
  • Doğrulama – SMTP doğrulama gerekli olduğundan Evet’i seçin.
  • Kullanıcı adı – Gmail adresiniz.
  • Şifre – Gmail şifreniz veya Uygulama şifreniz.

Yukarıdaki alanları doğru şekilde doldurduktan sonra Değişiklikleri Kaydedin butonuna tıklayınız. Sonrasında yapılan ayarların doğru olduğundan emin olmak için WP Mail SMTP plugininin sunduğu Send Test ekranı üzerinden test mesajı atabilirsiniz.

 

Böylelikle makalemizde Gmail hesabımızı nasıl SMTP server olarak ayarlayıp projelerimizde kullanacağımızı öğrendik. Ayrıca PHPMailer veya WP Mail SMTP kullanarak mail gönderimlerinin nasıl gerçekleştirildiğinin adım adım inceleme imkanı bulduk. ]]>
Android ListView kullanımı ve örnek uygulama http://yazilimdersi.info/makaleler/detay/110/android-listview-kullanimi-ve-ornek-uygulama Sun, 22 Nov 2020 00:00:00 +0000 mstfchelikListView componentidir. Kullanıcılar listelenen veriler üzerinde tek parmağıyla yukarı-aşağı sürükleme yaparak dolaşabilirler. Makalemizde basit bir ListView kullanımını sizlerle birlikte gerçekleştireceğiz.

Aşağıdaki adımları takip ederek Android Studio üzerinde yeni bir uygulama geliştirelim;
1. File => New Project seçeneğine tıklayalım. Sonrasında açılan ekranda Empty Activity seçeneğini seçip Next butonuna tıklayalım. 
2. Bir sonraki ekranda uygulamanın ismini, paket adını ve kayıt edileceği dizini belirleyelim. İsterseniz uygulamanın adını SampleListView, paket ismi olarak ise info.yazilimdersi.listview olarak belirleyelim.
3. Bu işlemler sonrasında oluşan MainActivity dosyasını ListActiviy üzerinden extend edilecek şekilde ayarlayalım.
public class MainActivity extends ListActivity {
4. Şimdi sıra listelemede görüntülenecek seçeneklerin res => values dizini altında list_data.xml dosyası içerisine eklenmesinde.
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="adobe_products">
        <item>Android</item>
        <item>Objective C</item>
        <item>Swift</item>
        <item>Kotlin</item>
        <item>React Native</item>
        <item>Xamarin</item>
        <item>Ionic</item>
        <item>Sencha Touch</item>
    </string-array>
</resources>
5. Seçeneklerin gösteriminde kullanılacak sayfanın tasarımı için res => layout dizini altında list_item.xml dosyası içerisine aşağıdaki kod parçasının eklenmesi gerekmektedir.
<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/label"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="10dip"
        android:textSize="16dip"
        android:textStyle="bold" >
</TextView>
6. Şimdi MainActivity sınıfı içerisine aşağıdaki kod parçalarını yapıştıralım. Yazdığımız kod sayesinde listeleme için eklediğimiz seçeneklerin görüntülenmesi sağlanmaktadır.
package info.yazilimdersi.listview;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String[] mobileAppFrameworks = getResources().getStringArray(R.array.mobile_app_frameworks);
        this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, mobileAppFrameworks));

    }
}

Projeyi çalıştırdığımızda aşağıdaki ekran görüntüsü ile karşılaşacaksınız. Ekran görüntüsünde gördüğünüz üzere popüler mobil frameworkler listelenmektedir.

7. Şimdi de seçilen popüler dilin bir sonraki Activity'e aktarımını gerçekleştirelim. Bunun için DetailItemActivity.java sınıfını oluşturup AndroidManifest.xml dosyası içerisinde tanımlayalım. Bu konunun nasıl gerçekleştirildiğini daha önceki makalelerimizde dile getirmiştik.
package info.yazilimdersi.listview;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String[] mobileAppFrameworks = getResources().getStringArray(R.array.mobile_app_frameworks);
        this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, mobileAppFrameworks));
        
        ListView lv = getListView();

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
	    
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                String product = ((TextView) view).getText().toString();
                Intent i = new Intent(getApplicationContext(), DetailItemActivity.class);
                i.putExtra("product", product);
                startActivity(i);
            }
       });

    }
}
8. DetailItemActivity sınfı için kullanılacak arayüzü res => layout dizini altında detail_item.xml isminde oluşturalım.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:gravity="center"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <TextView android:id="@+id/product_label"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="25dip"
            android:textStyle="bold"
            android:gravity="center"
            android:padding="10dip"
            android:textColor="#000000"/>    
</LinearLayout>

Hazırlanan arayüzde seçilen seçeneğin yeni Activity içerisinde gösterimini sağlayalım. Burada önemli olan yukarıda eklenen kodlama ile Intent ile seçili textin DetailItemActivity aktarımını sağladık. getIntent() ile Activityler arası iletilen verilerin yakalanması sağlanmaktadır.

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class DetailItemActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.detail_item);

        TextView txtProduct = (TextView) findViewById(R.id.product_label);

        Intent i = getIntent();
        String product = i.getStringExtra("product");
        txtProduct.setText(product);

    }
}
Son olarak oluşturulan yeni Activity sınıfının AndroidManifest.xml dosyası içerisinde tanımlanması gerekmektedir. Aksi takdirde uygulamanız crash edecektir.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.yazilimdersi.listview">

    <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">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".DetailItemActivity"
            android:label="Detail Item"></activity>
    </application>

</manifest>
Böylelikle ListView yapısını kullanarak örnek bir projeyi de gerçekleştirmiş olduk. ]]>
Android Multi Language | Çoklu Dil Desteği Ekleme http://yazilimdersi.info/makaleler/detay/109/android-multi-language--coklu-dil-destegi-ekleme Sat, 21 Nov 2020 00:00:00 +0000 mstfcheliklokalizasyon kavramını iyi anlamalı ve uygulamanıza entegre etmeniz gerekmektedir. Lokalizasyon işlemini gerçekleştirirken sadece label olarak textlerin değil ayrıca uygulamada görüntülenen görsellerin, ses dosyalarının ve tarih birimlerinin de bu işlemden geçmesi gerekmektedir. Ancak bu makalemizde sadece text bazında farklı dillerde uygulamamızın nasıl görüneceği bilgisini sizlerle paylaşacağız. 

Yapılacak olan örnek uygulamada Türkçe, İngilizce ve Arapça dilinde ekranların nasıl görüntüleneceği anlatılacaktır.

1. Text Lokalizasyonu Nasıl Çalışır

Android işletim sistemi, uygulamalarda default olarak İngilizceyi ana dil olarak kabul eder ve uygulama içeriklerini res ⇒ values ⇒ strings.xml'den yükler. Uygulamanıza ait yeni bir dil tanımlamanız gerektiğinde tanımlayacağınız dile ait ISO kodunu values dizinin ardına eklemeniz gerekmektedir. Örneğin uygulamamıza Türkçe ve Arapça dil desteği eklemeyi planladığımız için Türkçe için values-tr, Arapça dili içinse values-ar dizinlerini oluşturup içerisine strings.xml dosyasını yerleştirmemiz gerekmektedir.

Lokalizasyon yapısı ise aşağıdaki adımlara göre çalışmaktadır;

  • Kullanıcı cihaz dilini Ayarlar ⇒ Dil ve Giriş seçeneğinden değiştirdiğinde, Android işletim sistemi uygulamadaki uygun dil kaynaklarını kontrol eder.(Farzedelim kullanıcı Arapça'yı seçiyor)
  • Uygulama seçilen dili destekliyorsa, Android projede bulunan values-(ISO Dil Kodu) klasöründeki strings.xml dosyasına bakar. (Arapça için values-ar/string.xml'de bulunan içerikleri yükler)
  • Eğer Arapça dil dosyasına eksik olan herhangi bir değer varsa values/strings.xml dosyası içerisinde bulunan içeriği gösterir.

Bundan dolayı, values/stings.xml dosyasının içeriği tüm text değerlerini içermesi gerekmektedir. Aksi takdirde, uygulamanın hata alacaktır.

Uygulamanızda dikkat etmeniz gereken en önemli konulardan birisi static textlerin tanımlamaları her zaman strings.xml dosyası içerisinde olmalıdır.
<string name="enter_email">Enter email address</string>
Tanımlanan textleri uygulamamıza ait layoutlarda aşağıdaki şekilde çağırabiliriz.
<TextView ...   android:text="@string/enter_email"  />

2. Örnek Proje Oluşturalım

Android Studio'da File ⇒ New ⇒ New Project seçeneğine tıklayıp Empty Activity ile yeni bir proje oluşturalım.

Sonrasında values dizini altında strings.xml dosyası içerisine aşağıdaki tanımlamaları gerçekleştirelim. Bizde default olarak İngilizceyi farz edip ona göre stringleri tanımlayalım.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Sample Localization App</string>
    <string name="action_settings">Settings</string>
    <string name="welcome">Welcome!</string>
    <string name="email">Email Address</string>
    <string name="password">Password</string>
    <string name="login">Login</string>
    <string name="signup">Don\'t have account? Sign Up</string>
</resources>
Bu işlemden sonra Türkçe ve Arapça dil desteği için values-ar ve values-tr dizinleri oluşturup içerisine strings.xml dosyalarını koymamız gerekmektedir. Bu işlemleri gerçekleştirdikten sonra proje diziniz şu şekilde olacaktır.

 

Şimdi öncelikle Türkçe strings.xml dosyasına çeviri içeriklerini girelim.

Türkçe values-tr/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Örnek Lokalizasyon Uygulaması</string>
    <string name="action_settings">Ayarlar</string>
    <string name="welcome">Merhaba!</string>
    <string name="email">Email Adresi</string>
    <string name="password">Şifre</string>
    <string name="login">Giriş Yapın</string>
    <string name="signup">Herhangi bir hesabınız yokmu? Hesap Oluştur</string>
</resources>
Şimdi de Arapça dil desteği için values-ar/strings.xml dosyasına çeviri içeriklerini girelim.
Arapça values-ar/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">نموذج لتطبيق التعريب</string>
    <string name="action_settings">إعدادات</string>
    <string name="welcome">أهلا بك!</string>
    <string name="email">عنوان بريد الكتروني</string>
    <string name="password">كلمه السر</string>
    <string name="login">تسجيل الدخول</string>
    <string name="signup">ليس لديك حساب؟ سجل</string>
</resources>
Şimdi sırada uygulamamıza ait activity_login.xml sayfasına aşağıdaki kod parçalarını yapıştırmamızda. Login sayfamız basit bir email ve şifre arayüzüne sahip olacaktır.
<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"
    android:background="@color/colorAccent">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="40dp"
            android:text="@string/welcome"
            android:textColor="@color/colorWhite"
            android:textSize="45dp"
            android:textStyle="bold" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorWhite"
            android:orientation="vertical" >

            <EditText
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:background="@null"
                android:hint="@string/email"
                android:padding="5dp"
                android:singleLine="true"/>

            <EditText
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:hint="@string/password"
                android:inputType="textPassword"
                android:padding="5dp" />
        </LinearLayout>

        <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="25dp"
            android:background="@color/colorPrimary"
            android:text="@string/login"
            android:textColor="@color/colorWhite"/>
    </LinearLayout>

    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/signup"
        android:layout_alignParentBottom="true"
        android:gravity="center_horizontal"
        android:layout_marginBottom="25dp"
        android:textColor="@color/colorWhite"/>

</RelativeLayout>
Şu anda Android Studio üzerinde layout kısmına kodlamanıza yapıştırmanızın ardından Design tabına geçtiğinizde aşağıdaki ekran görüntüsü ile karşılaşmanız gerekmektedir.

 

3. Uygulamanın Diğer Dillerini İnceleyelim

Uygulamanın diğer dilleri desteklediğini test etmek için izlenecek iki farklı yöntem bulunmaktadır. En basiti Android Studio'da design sayfasının üst kısmında desteklenen dillere ait selectbox listelenmektedir.

Burada Türkçe ve Arapça seçeneği listelenmektedir. Örnek olarak Türkçe dili seçildiğinde ekran görüntüsü aşağıdaki gibi olacaktır.

Böylelikle uygulamamıza Arapça ve Türkçe dil desteği eklendi. İstenirse daha farklı dil seçenekleri uygun ISO koduna ait klasörleme yapılarak oluşturulabilir.]]>
Android MVVM Design Pattern Kullanımı http://yazilimdersi.info/makaleler/detay/108/android-mvvm-design-pattern-kullanimi Tue, 17 Nov 2020 00:00:00 +0000 mstfchelikGoogle, Google I/O 18 ile MVVM patternini destekleyeceğini açıkladıktan sonra Android uygulama geliştiriciler için bu patternin nasıl bir yapı üzerine kurgulandığına yönelik bir makale paylaşma ihtiyacı duydum. Makalemizde öncelikle patternin avantajları ve nasıl kullanıldığını anlatacağım. Sonrasında da basit bir login işlemi ile konuyu pekiştireceğim. 

Öncelikle MVVM yapısı Model, View, ViewModel üzerine kurgulanmaktadır.
  • Model: Model, uygulamanın verilerini tutar. Doğrudan view ile iletişim kurmaz. Genel olarak, verileri Observables aracılığıyla ViewModel'e aktarır.
  • View: View, uygulamanın arayüzünü kapsamaktadır.
  • ViewModel: Model ve View arasında bir köprü görevi görür. Modelden gelen datanın View'e aktarılmasından sorumludur. Verilerin anlık aktarımı için hook veya callback metodları kullanılmaktadır.
MVVM Design Pattern Flow

MVP Patterni İle Arasındaki Fark

  • Middle Layer'de Presenter yerine ViewModel kullanılmaktadır.
  • Presenter, View'e ait referanslar tutar. Ancak ViewModelde buna gerek kalmamaktadır.
  • Presenter, View'i klasik yolları kullanarak güncellemektedir.
  • ViewModel, Model üzerinden gelen verileri iletebilmektedir.
  • Presenter ve View 1'e 1 (one to one) ilişki içindedir.
  • View ve ViewModelde ise 1'e çok yönlü (one to many) ilişki içindedir.
  • ViewModel, View'un onu dinlediğini bilmez.

Android'de MVVM'yi uygulamanın iki yöntemi bulunmaktadır:

  • Data Binding
  • RX Java

Makalemize Data Binding yöntemini kullanarak devam edelim. Data Binding, verileri doğrudan xml dosyalar üzerinden bağlamak için Google tarafından tanıtılan bir kütüphanedir.

Şimdi MVVM'i kullanarak email ve password içeren basit bir login sayfası oluşturalım. Uygulamamızda View'e ait herhangi bir referans tutulmaksızın ViewModel üzerinden iletilen verinin nasıl gösterildiğini göreceğiz.

İpucu: Herhangi bir referans tutulmadan bir sınıfa bildirimde bulunmak nasıl mümkün olabilir?

Bu işlem üç şekilde gerçekleştirilebilir;

  • Çift Yönlü Data Binding kullanarak
  • Live Data kullanarak
  • RxJava kullanarak

Çift Yönlü Data Binding Kullanımı

Çift Yönlü Data Binding, uygulama arayüzünde bulunan nesnelerin verilerle çift taraflı haberleşmesine imkan sunan bir tekniktir. Bu tekniğe göre layout üzerinden ViewModel'e ve ViewModel üzerinden layouta data aktarımı sağlanabilmektedir.

Bizim örnek projemiz ise ViewModel üzerinden veri aktarımı ve yaşanan değişikliklerin Observer yapısı üzerinden yakalanmasını kapsamaktadır.

Bunun için BindingAdapter ve XML'de tanımlanan custom attributelere ihtiyacımız var. Binding Adapter, custom attribute üzerinde gerçekleşen değişiklikleri izleyecektir.

Örnek Android MVVM Projeye ait Klasör Yapısı

Projemizde klasör yapısını aşağıdaki şekilde kurgulayacağız. Projemizde sadece login sayfası kurguladığımızdan dolayı User modeli, LoginViewModel sınıfı ve LoginActivity yeterli olmaktadır.

Android MVVM Project Structure

Data Binding Kütüphanesinin Eklenmesi

Aşağıdaki kod parçasını app klasörünüz altında bulunan build.gradle dosyasına ekleyelim.
android {

    dataBinding {
        enabled = true
    }

}
Eklenen kod parçası data bindingin projemizde aktif hale gelmesini sağlamaktadır.

Dependecylerin Eklenmesi

Aşağıdaki kod parçasını app klasörünüz altında bulunan build.gradle dosyasında dependecy alanına ekleyelim.
implementation 'android.arch.lifecycle:extensions:1.1.0'

Model

Uygulamamızda kullanıcıya ait email ve şifre alanlarını tutacak User modeli aşağıdaki şekilde oluşturalım.
public class User {
    private String email;
    private String password;

    public User(String email, String password) {
        this.email = email;
        this.password = password;
    }

    public void setEmail(String email) {
        this.email = email;
    }
    
    public String getEmail() {
        return email;
    }

    public void setPassword(String password) {
        this.password = password;
    }


    public String getPassword() {
        return password;
    }

}
Projemizde kullanılacak olan çift yönlü data binding işlemi yukarıda da dile getirdiğimiz gibi xml layout üzerinde tanımlanan viewlerin güncellenmesinde veya view üzerinde yapılan işlemin Model üzerine aktarımında kullanılmaktadır.

Çift yönlü data binding için kullanılan syntax @={variable} şeklindedir.

Layout

Login sayfasına ait arayüz için aşağıdaki kodu activity_login.xml dosyası içerisine yapıştıralım.
?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/tools">

    <data>

        <variable
            name="viewModel"
            type="yazilimdersi.info.example.samplemvvm.viewmodels.LoginViewModel" />
    </data>


    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/yazilimdersiImageView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_centerHorizontal="true"
                android:padding="10dp"
                android:src="@drawable/icon_app_logo" />

            <EditText
                android:id="@+id/inEmail"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Email"
                android:inputType="textEmailAddress"
                android:padding="8dp"
                android:text="@={viewModel.userEmail}" />


            <EditText
                android:id="@+id/inPassword"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Password"
                android:inputType="textPassword"
                android:padding="8dp"
                android:text="@={viewModel.userPassword}" />


            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:background="@color/colorPrimaryDark"
                android:textColor="@color/colorWhite"
                android:onClick="@{()-> viewModel.onLoginClicked()}"
                android:text="LOGIN"
                bind:toastMessage="@{viewModel.toastMessage}" />


        </LinearLayout>

    </ScrollView>

</layout>
Data Bindingde arayüzüne yönelik işlemlerde sayfanın en üst kısmında layout taglerinin tanımlanması gerekmektedir. Yukarıda yapılan tanımlamalar sonrasında ViewModel dataları direkt olarak arayüze bind edebilmektedir. Kodlamada gördüğünüz üzere ()-> viewModel.onLoginClicked() fonksiyonu LoginViewModel sınıfı içerisinde tanımlanmıştır. Kullanıcı login butonuna bastığı anda bu bilginin ViewModel e iletilmesi sağlanmaktadır. Ayrıca ViewModel üzerinden gelen verilerin view e aktarımına örnek olarak (bind:toastMessage="@{viewModel.toastMessage}" kullanımını inceleyebiliriz. toastMessage verisinde herhangi bir değişiklik olduğu takdirde view üzerinde bu mesajın gösterimini sağlanmaktadır.

View Model

Aşağıdaki kod parçasını LoginViewModel.java sınıfı içerisine yapıştıralım.
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.text.TextUtils;
import android.util.Patterns;

import com.android.databinding.library.baseAdapters.BR;
import yazilimdersi.info.example.samplemvvm.model.User;

public class LoginViewModel extends BaseObservable {
    private User user;


    private String successMessage = "Başarılı şekilde giriş yapıldı";
    private String errorMessage = "Email veya Şifre hatalı";

    @Bindable
    private String toastMessage = null;


    public String getToastMessage() {
        return toastMessage;
    }


    private void setToastMessage(String toastMessage) {

        this.toastMessage = toastMessage;
        notifyPropertyChanged(BR.toastMessage);
    }


    public void setUserEmail(String email) {
        user.setEmail(email);
        notifyPropertyChanged(BR.userEmail);
    }

    @Bindable
    public String getUserEmail() {
        return user.getEmail();
    }

    @Bindable
    public String getUserPassword() {
        return user.getPassword();
    }

    public void setUserPassword(String password) {
        user.setPassword(password);
        notifyPropertyChanged(BR.userPassword);
    }

    public LoginViewModel() {
        user = new User("","");
    }

    public void onLoginClicked() {
        if (isInputDataValid())
            setToastMessage(successMessage);
        else
            setToastMessage(errorMessage);
    }

    public boolean isInputDataValid() {
        return !TextUtils.isEmpty(getUserEmail()) && Patterns.EMAIL_ADDRESS.matcher(getUserEmail()).matches() && getUserPassword().length() > 5;
    }
}

LoginViewModel sınıfımızı ViewModel üzerinden extend edebiliriz. Ancak amacımız login butonuna tıklanıldığında Toast mesajı gösterecek bir kurgu olduğundan BaseObservable sınıfını extend etmemiz daha iyi olacaktır.

toastMessage ile alakalı olarak ViewModel sınıfımızda getter ve setter methodlarını tanımlamamız gerekmektedir. settter methodu içerisinde notifyPropertyChanged metodunu çağırmamız gerekmekte. Böylelikle datamızın değiştiği bilgisini View ile paylaşmış oluyoruz. View de yaptığımız tanımlamalara göre aksiyon alacaktır. BR sınıfı proje rebuild edilirken otomatik olarak data binding kütüphanesi tarafından oluşturulmaktadır.

LoginActivity.java sınıfı içinde aşağıdaki kod parçasını yapıştıralım.
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.BindingAdapter;
import androidx.databinding.DataBindingUtil;

import yazilimdersi.info.example.samplemvvm.R;
import yazilimdersi.info.example.samplemvvm.databinding.ActivityLoginBinding;
import yazilimdersi.info.example.samplemvvm.viewmodels.LoginViewModel;

public class LoginActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityLoginBinding activityLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_login);
        activityLoginBinding.setViewModel(new LoginViewModel());
        activityLoginBinding.executePendingBindings();
    }

    @BindingAdapter({"toastMessage"})
    public static void runMe(View view, String message) {
        if (message != null)
            Toast.makeText(view.getContext(), message, Toast.LENGTH_SHORT).show();
    }
}

DataBinding librarysi sayesinde ActivityLoginBinding sınıfı otomatik olarak oluşturulmaktadır. @BindingAdapter methodunda tanımlı olan toastMessage güncellendiği anda içerisinde bulunan kod parçası trigger etmektedir.

Böylelikle ViewModel, yukarıdaki kodlamada görüldüğü üzere View üzerindeki işlemleri izleyerek Model'i güncellemektedir. Ayrıca Model, notifyPropertyChanged metodunu kullanarak View'i trigger edebilmektedir.

Uygulamamıza ait ekran görüntüsü aşağıdaki şekildedir.

]]>
PHP Composer Kurulumu ve Kullanımı http://yazilimdersi.info/makaleler/detay/107/php-composer-kurulumu-ve-kullanimi Sun, 01 Nov 2020 00:00:00 +0000 mstfchelikComposer, popüler programlama dili olan PHP için bir paket yöneticisidir. Geliştiricilerin harici paketleri veya kütüphaneleri yönetmek ve PHP tabanlı projelerine entegre etmek için kullandıkları basit ve güvenilir bir araçtır. Böylelikle, geliştiricilerin websitelerini sıfırdan oluşturmalarına gerek kalmamaktadır. Makalemizde örnek bir proje üzerinden sistemin nasıl çalıştığına yönelik kodlamalarla konuyu daha iyi anlamanızı sağlayacagız.

Composer'ı nasıl kuracağınızı öğrenmeden önce, bilgisayarınızdaki veya sunucunuzdaki komut satırı arayüzüne erişiminiz olduğundan emin olunuz. Çünkü komutlarımızı komut istemcisi diğer adıyla terminaller üzerinden gireceğiz.

Composer Kurulumu

Bu kısımda, Php Composer'ı Linux, MacOS ve Windows gibi işletim sistemlerinde nasıl kuracağınızı göstereceğiz.
 

Linux veya MacOS işletim sisteminde Composer Kurulumu

Composer'ı Linux ve MacOS işletim sistemine sahip sunucu veya bilgisayarlara yüklemede kullanılan komutlar aynıdır. Composer'ı sisteminize nasıl kuracağınızı öğrenmek için aşağıdaki adımları izleyin;
 

  • Öncelikle komut satırını açıp aşağıdaki komutu kullanarak Composer'ı resmi web sitesinden indirin:
    #composerin resmi websitesinden indirilmesi
    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    
  • Yükleyici dosyanın bozuk olmadığından emin olmak için yükleyicinin imzasını (SHA-384) aşağıdaki kodu kullanarak doğrulayın:
    #yükleyici dosyanın doğrulanması
    php -r "if (hash_file('sha384', 'composer-setup.php') === 'c31c1e292ad7be5f49291169c0ac8f683499edddcfd4e42232982d0fd193004208a58ff6f353fde0012d35fdd72bc394') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
    

    Yukarıdaki komuttaki uzun karakter dizisi ("c31c1e292ad…") yükleyicinin imzasıdır. Composer'ın her yeni sürümü çıktığında bu kod değişir. Bu nedenle, bu sayfaya tıklayarak en son SHA-384'ü getirdiğinizden emin olun.

  • Son sürümün indirildiğini doğruladıktan sonra composer'i global veya local olarak kurabilirsiniz. Local kurulum, composerin mevcut dizininizde saklanacağı ve yükleme öncesi komutları çalıştırmadan önce dosya yolunu belirtmeniz gerektiği anlamına gelir. Global kurulum ise herhangi bir path tanımlamaya gerek kalmaksızın /usr/local/bin dosyası altında bulunan kurulum dosyalarının cihazın herhangi bir konumundan kuruluma izin vermesini sağlamaktadır. Her iki yöntemde şu şekilde gerçekleştirilir;
    #Local Kurulum
    php composer-setup.php
    
    #Global Kurulum
    php composer-setup.php --install-dir=/usr/local/bin --filename=composer
    
    Kurulum başarılı gerçekleştirildiği takdirde aşağıdaki ekranla karşılaşacaksınız...
    All settings correct for using Composer
    Downloading...
    
    Composer (version 1.10.5) successfully installed to: /usr/local/bin/composer
    
  • Başarılı yükleme işleminden sonra kurulumda kullanılan dosyayı kaldırmayı unutmayın.
    #Kurulum dosyasının silinmesi
    php -r "unlink('composer-setup.php');"
    
  • Şimdi de kurulumu test edelim.
    #Komut satırına bu komutu girin
    composer
    
    Çalışan komut sonrasında aşağıdaki şekilde bir ekranla karşılaşmanız gerekmektedir.
       ______
      / ____/___ ____ ___ ____ ____ ________ _____
     / / / __ / __ `__ / __ / __ / ___/ _ / ___/
    / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
    ____/____/_/ /_/ /_/ .___/____/____/___/_/
                      /_/
    
    Composer version 2.0.4 2020-11-02 16:20:11
    

Windows işletim sisteminde Composer Kurulumu

Windows makinesinde Composer kurulumu Linux ve MacOS sistemlere göre biraz farklıdır. Yazılımın indirilmesi ve kurulması için herhangi bir komut satırı talimatı gerekli değildir.

Aşağıdaki adımları izleyerek kurulumu gerçekleştirelim.

  • Bilgisayarınıza PHP'yi kurun. Kurulumu basit olduğundan ve birkaç dakika içinde tamamlayabileceğinizden, XAMPP'yi kullanmanızı öneririz.
  • XAMPP kurulumu tamamlandıktan sonra Composer'in son sürümünü indirin.
  • Sonrasında composer kurulum sihirbazını çalıştırın. Geliştirici modunu etkinleştirmenizi istediğinde, onu yok sayın ve kurulum işlemine devam edin.
  • Başka bir pencere açılacak ve sizden PHP komut satırını bulmanızı isteyecektir. Varsayılan olarak, C:/xampp/php/php.exe gösterilmektedir. Konumu belirledikten sonra İleri'ye tıklayın.
  • Proxy ayarları için ayrı bir pencereye yönlendirileceksiniz. Kutuyu işaretlemeden bırakın ve İleri'ye basarak bu bölümü atlayın. Ardından, son pencerede Yükle'ye tıklayın.
  • Kurulumu tamamladıktan sonra komut istemini açın. CTRL + R tuşlarına basın, "cmd" yazın ve Tamam'ı tıklayın.

     
  • Son olarak aşağıdaki komutu girin:
    composer
    

Artık Windows bilgisayarınızda composer yüklü. Yükleyici, composer'i PATH değişkeninize otomatik olarak ekleyecektir. Artık komut istemini açabilir ve yazılımı her yerden çalıştırabilirsiniz.  

Composer.json dosyasının oluşturulması

Şu ana kadar makalemizde composer kurulumunun nasıl yapıldığını sizlerle paylaştım. Şimdi ilginç kısım geliyor - PHP projenizde composer'i nasıl kullanabiliriz. Bunu sağlamak için projenizde composer.json dosyası oluşturmanız gerekir. Bu dosya, projeniz için indirilmesi gereken paketleri (kütüphaneleri) içerir. Ayrıca bu dosya, projenizle ile alakalı sürüm uyumluluğunu da kontrol eder. Eğer eski bir kütüphane veya paket kullanıyorsanız, composer.json'ın gelecekteki sorunları önlemek için size haber vereceği anlamına gelmektedir.

composer.json dosyasını manual olarak sizde oluşturabilirsiniz. Ancak herşeyin otomatik olarak sunulduğu sistemde en iyisi tüm çalışmaların otomatik olarak kontrol edilmesidir.

Örnek bir proje oluşturarak composer.json'ın kullanılışını görelim. Projemiz, herhangi bir kod çalıştırıldığında geçen süreyi gösteren bir zamanlayıcı olsun. Aşağıdaki adımları izleyerek proje dosyalarını oluşturalım.

  • Projemizin için yeni bir dizin oluşturalım. Projemiz bir zamanlayıcı olduğu için, klasöre phpzamanlayici adını vereceğiz. Bunu yapmak için aşağıdaki komutu çalıştırın komut satırında:
    #phpzamanlayici klasörü oluşturun
    mkdir phpzamanlayici
    
  • Aşağıdaki komutla yeni dizine girin;
    #phpzamanlayici klasörünü girin
    cd phpzamanlayici
    
  • Proje için bir paket veya kitaplık bulun. Bunu başarmak için en iyi yer, proje geliştirmenize yardımcı olacak tonlarca kitaplık bulacağınız Packagist'tir. Projemiz için bir zamanlayıcı paketine ihtiyacımız var. Bunu elde etmek için arama çubuğuna timer yazmanız yeterlidir:

    Gördüğünüz gibi, arama sonucu birkaç zamanlayıcı paketi listelendi ve her birinin bir adı ve ne işe yaradığına dair küçük bir açıklaması vardır. Bu örnekte, en çok indirilen ve GitHub yıldızlarının çoğuna sahip olduğu için phpunit/php-timer'ı seçiyoruz.

  • Aşağıdaki komutu kullanarak composer in ilgili paketi yüklemesini sağlayın;
    #php-timer kütüphanesinin kurulumu
    composer require phpunit/php-timer
    
    Komut sonrasında aşağıdaki şekilde bir ekran ile karşılaşmanız gerekmektedir.
    Using version ^1.0 phpunit/php-timer
    

Yukarıdaki komutu çalıştırdıktan sonra, proje dizininizde iki yeni dosya (composer.json ve composer.lock) ve vendor adlı bir klasör olacaktır. vendor dizini, composer'in tüm paketlerinizi ve bağımlılıklarınızı depolayacağı dizindir.  

Autoload Scriptinin Kullanımı

Projede herşey yolunda görünüyor. Şu anda yapmanız gereken tek şey phptimer bağımlılığının PHP kodunuza yüklemesidir. Otomatik yüklemeyi kullanmak için, komut dosyanızda yeni değişkenler bildirmeden veya başlatmadan önce aşağıdaki satırı yazın;

require '/vendor/autoload.php'
Daha iyi anlamanız için size bir örnek göstereceğim. projenizde demo.php adında bir sınıf oluşturun.
nano demo.php
Bu dosya içerisine aşağıdaki kod satırını yapıştıralım.

<?php 
      
      require __DIR__ . '/vendor/autoload.php' 
      Timer::start();
      $time = Timer::stop(); 
      var_dump($time); 
      print Timer::secondsToTimeString($time);
?>
Sonrasında aşağıdaki komut satırını çalıştırın;
php demo.php
Terminalde aşağıdaki sonuçların görüntülenmesi gerekmektedir.
double(1.0893424438611E-5)
0 ms

Proje Bağımlılıklarının Güncellenmesi

Son olarak, paketlerinizi nasıl güncelleyeceğinizi bilmeniz gerekir. Bu, iki şekilde gerçekleştirilebilir:

  • Global güncelleme: Tüm paketleriniz ve bağımlılıklarınız için güncellemeleri bir defada kontrol etmek ve yüklemek için aşağıdaki komutu yazın;
    composer update
    
  • Paket bazlı güncelleme: Bir veya daha fazla belirli paket için güncellemeleri kontrol etmek için aşağıdaki komutu çalıştırın;
    composer update vendor/package vendor2/package2
    
    Komutta yer alan vendor/package alanını güncellemek istediğiniz paket ismi ile değiştirmeyi unutmayın.
Composer güncelleme komutunu çalıştırdığımız takdirde composer.json ve composer.lock dosyalarını proje bağımlılıklarınızın mevcut durumuyla eşleşecek şekilde güncellenir. ]]>
Koronavirus Sorgulama http://yazilimdersi.info/makaleler/detay/106/koronavirus-sorgulama Fri, 20 Mar 2020 00:00:00 +0000 mstfchelik Çin’in Wuhan kentinde ortaya çıkan ve şu ana kadar pek çok ülkede görülen yeni tip Corona virüsü can almaya devam etmekte. Ülkelerin aldığı önlemlerle birlikte vaka sayısında azalma görülse de ilk aşamada gösterilen tedbirsizliklerin sonucu ölümlerle sonuçlanmaktadır.

Ülkelerin koronavirüsten kaynaklı gerçekleşen gerçek zamanlı vaka sayıları listelenmektedir. Hazırladığımız arayüz sayesinde herhangi bir ülke adı ile arama yaparak koronavirus vaka sayılarına rahatlıkla erişebilirsiniz.

]]>
Android ile SQLite Veritabanı Kullanımı (Örnek Uygulama Anlatımı ile) http://yazilimdersi.info/makaleler/detay/105/android-ile-sqlite-veritabani-kullanimi-(ornek-uygulama-anlatimi-ile) Tue, 25 Feb 2020 00:00:00 +0000 mstfchelik Android işletim sistemli cihazlarda, verileri kalıcı olarak saklamanın birkaç yolu vardır. SQLite, uygulama verilerini depolama yöntemlerinden birisidir. Android işletim sistemi ile birlikte gelen çok hafif bir veritabanıdır. Eğer uygulamanızda basit veri nesneleri depolaması gerekiyorsa SQLite sistemini kullanmaya çalışın. SQLite kullanımı size hız, performans ve modülerlik sağlayacaktır.

Bu makalede, Android işletim sistemli cihazlarda veritabanının temellerini SQLite kullanarak oluşturacağımız Notlarım uygulaması ile öğreneceğiz.

1. The Notlarım Uygulaması

Veri tabanı depolamasının Android uygulamalarda nasıl çalıştığını göstermek üzere basit bir Notlarım uygulaması oluşturacağız. Bu uygulama kullanıcının yeni not girebildiği, silebildiği veya güncelleme yapabildiği bir ekrandan oluşan basit bir uygulamadan oluşacaktır. Uygulama ile alakalı ekran görüntüleri şu şekildedir;

 

Hadi Android Studio'da notlarım uygulamasını oluşturmaya başlayalım.

2. Yeni Android Uygulama Oluşturulması

1. Android Studio'da File ⇒ New Project seçeneğini seçip, templates olarak görüntülenen seçeneklerden Basic Activity olanı seçerek yeni bir Android proje oluşturun.

2. app dizini altında bulunan build.gradle dosyasını açın ve RecyclerView kütüphanesini ekleyin. Bu kütüphane notların listelenmesinde kullanılacaktır.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // ..
 
    implementation 'com.android.support:recyclerview-v7:26.1.0'
}

3. colors.xml, dimens.xml ve strings.xml dosyalarına aşağıdaki kod parçalarını ekleyin.

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <color name="colorPrimary">#455399</color> 
    <color name="colorPrimaryDark">#455399</color> 
    <color name="colorAccent">#00c6ae</color> 
    <color name="msg_no_notes">#999</color> 
    <color name="hint_enter_note">#89c3c3c3</color> 
    <color name="timestamp">#858585</color> 
    <color name="note_list_text">#232323</color> 
</resources>

<resources> 
    <dimen name="fab_margin">16dp</dimen> 
    <dimen name="activity_margin">16dp</dimen> 
    <dimen name="dot_margin_right">10dp</dimen> 
    <dimen name="msg_no_notes">26sp</dimen> 
    <dimen name="margin_top_no_notes">120dp</dimen> 
    <dimen name="lbl_new_note_title">20sp</dimen> 
    <dimen name="dimen_10">10dp</dimen> 
    <dimen name="input_new_note">20sp</dimen> 
    <dimen name="dot_height">30dp</dimen> 
    <dimen name="dot_text_size">40sp</dimen> 
    <dimen name="timestamp">14sp</dimen> 
    <dimen name="note_list_text">18sp</dimen> 
</resources>

<resources> 
   <string name="app_name">Notlarım</string> 
   <string name="action_settings">Ayarlar</string> 
   <string name="activity_title_home">Notlar</string> 
   <string name="msg_no_notes">Hernangi bir not bulunamadı!</string> 
   <string name="lbl_new_note_title">Yeni Not</string> 
   <string name="lbl_edit_note_title">Notu Güncelle</string> 
   <string name="hint_enter_note">Notunu gir!</string> 
</resources>

4. Projede database, database/model, utils ve view isimlerinde dosya paketleri oluşturun. Yapılan düzenlemelerden son projenin son hali şu şekilde olacaktır;

2.1. SQLite Helper Sınıfının Oluşturulması

Android'in official kütüphanesi olan SQLiteOpenHelper sınıfı miras alınarak yeni bir sınıf oluşturalım. Bu sınıf CRUD(Create, Read, Update, Delete) yani notlarımız için gerekli olan ekleme, okuma, güncelleme ve silme işlemlerini kapsayacak şekilde ayarlanacaktır.

Veritabanına kayıt edilen notları daha kolay yönetebilmek için Notes modelini oluşturalım.

5. database/model paketi altında, Note.java sınıfı oluşturun. Bu sınıf içerisinde tablo ismi, sütunlar, bu tabloya ait SQL sorgularını ve getter/setter metodlarını içermektir.

  • `notes` tablosu `id`, `note` and `timestamp` gibi sütunları içermektedir.
  • `id` sütunu eklenen notların tekil olmasını sağlamada kullanılan alandır.
  • `note` sütunu yazılan notların tutulduğu alandır.
  • `timestamp` sütunu eklenen notların kayıt tarihini tutmada kullanılan alandır.
public class Note {
    public static final String TABLE_NAME = "notes";
 
    public static final String COLUMN_ID = "id";
    public static final String COLUMN_NOTE = "note";
    public static final String COLUMN_TIMESTAMP = "timestamp";
 
    private int id;
    private String note;
    private String timestamp;
 
 
    // Create table SQL query
    public static final String CREATE_TABLE =
            "CREATE TABLE " + TABLE_NAME + "("
                    + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                    + COLUMN_NOTE + " TEXT,"
                    + COLUMN_TIMESTAMP + " DATETIME DEFAULT CURRENT_TIMESTAMP"
                    + ")";
 
    public Note() {
    }
 
    public Note(int id, String note, String timestamp) {
        this.id = id;
        this.note = note;
        this.timestamp = timestamp;
    }
 
    public int getId() {
        return id;
    }
 
    public String getNote() {
        return note;
    }
 
    public void setNote(String note) {
        this.note = note;
    }
 
    public String getTimestamp() {
        return timestamp;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
}

6. database paketi altında, DatabaseHelper.java adında ve SQLiteOpenHelper sınıfını miras alan bir sınıf oluşturun. Bu sınıf veritabanı için yapılacak tüm işlemlerde kullanılacaktır.

  • onCreate() fonksiyonu uygulama yüklendiğinde sadece bir kere çağrılmaktadır. Bu metod, uygulamada kullanılacak veritabanı ve bu veritabanında kullanılacak olan tabloların oluşturulmasında kullanılmaktadır.
  • Tablolarda herhangi bir güncelleme gerektiğinde onUpgrade() fonksiyonu kullanılmaktadır. Herhangi bir güncelleme olup olmadığını DATABASE_VERSION numarasına göre gerçekleştirebilirsiniz. Tabloda herhangi bir yeni sütun eklenmesi veya yeni tabloların oluşturulması durumunda bu numaranın yükseltilmesi yeterli olacaktır. Örneğimizde mevcut olan tabloların tümünün silinmesi ve yeniden oluşturulması sağlanmıştır.
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
 
import java.util.ArrayList;
import java.util.List;
 
import info.yazilimdersi.sqlite.database.model.Note;
 
public class DatabaseHelper extends SQLiteOpenHelper {
 
    // Veritabanı versiyonu
    private static final int DATABASE_VERSION = 1;
 
    // Veritabanı adı
    private static final String DATABASE_NAME = "notes_db";
 
 
    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
 
    // Tabloların oluşturulması
    @Override
    public void onCreate(SQLiteDatabase db) {
 
        // notes tablosunu oluştur
        db.execSQL(Note.CREATE_TABLE);
    }
 
    // Veritabanının güncellenmesi
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Mevcut notes tablosunu kaldır.
        db.execSQL("DROP TABLE IF EXISTS " + Note.TABLE_NAME);
 
        // Veritabanını tekrardan oluştur.
        onCreate(db);
    }
}

Artık notları kayıt etmede kullanılacak olan veritabanı oluşturuldu. Şimdi aynı sınıfa aşağıdaki fonksiyonları ekleyelim;

a. Not Eklenmesi

Bu fonksiyon veritabanına yazma imkanı sunan getWritableDatabase() metoduna erişim gerektirmektedir. Aşağıdaki kodlamada veritabanına yeni bir notun nasıl kayıt edildiğini görebilirsiniz;

  • ContentValues() sütun isimlerinin belirlenmesi ve verilerin kayıt edilmesinde kullanılmaktadır. Burada, `id` and `timestamp` sütunları otomatik olarak setleneceği için bunları ekleme işleminde tanımlamıyoruz.
  • Her zaman veritabanında yapılacak işlemin bitirilmesinin ardından db.close() metodunun çağrılması gerekmektedir. db.close() metodunun çağrılması aktif olan bağlantının kapatılmasını sağlamaktadır.
  • Herhangi bir yeni kayıt oluşturulduğunda eklenen kayda ait `id` verisi dönecektir.
public long insertNote(String note) {
    // veritabanına erişimde kullanılacak nesne
    SQLiteDatabase db = this.getWritableDatabase();
 
    ContentValues values = new ContentValues();
    // `id` and `timestamp` otomatik oluşturulduğu için eklemeye gerek yoktur.
    values.put(Note.COLUMN_NOTE, note);
 
    // yeni kayıt oluştur
    long id = db.insert(Note.TABLE_NAME, null, values);
 
    // bağlantıyı kapat
    db.close();
 
    // yeni eklenen kaydın id bilgisini dönebilirsin.
    return id;
}

b. Notların Listelenmesi

Bu fonksiyon veritabanına okuma imkanı sunan getReadableDatabase() metoduna erişim gerektirmektedir. Aşağıdaki kodlamada veritabanında kayıtlı olan tüm notların ve sadece istenilen nota erişimi görebilirsiniz;

  • getNote() metodu ile iletilen `id` parametresine bağlı olarak ilişkili notun döndürülmesi sağlanmıştır.
  • getAllNotes() metodunun çağrılması ile veritabanında kayıtlı tüm notların getirilmesi sağlanmıştır.
  • getNotesCount() metodu ile veritabanında kayıtlı bulunan notların sayısını dönmektedir.

public Note getNote(long id) {
    SQLiteDatabase db = this.getReadableDatabase();
 
    Cursor cursor = db.query(Note.TABLE_NAME,
            new String[]{Note.COLUMN_ID, Note.COLUMN_NOTE, Note.COLUMN_TIMESTAMP},
            Note.COLUMN_ID + "=?",
            new String[]{String.valueOf(id)}, null, null, null, null);
 
    if (cursor != null)
        cursor.moveToFirst();
 
    Note note = new Note(
            cursor.getInt(cursor.getColumnIndex(Note.COLUMN_ID)),
            cursor.getString(cursor.getColumnIndex(Note.COLUMN_NOTE)),
            cursor.getString(cursor.getColumnIndex(Note.COLUMN_TIMESTAMP)));
 
    // veritabanı bağlantısını kapatalım
    cursor.close();
 
    return note;
}
 
public List getAllNotes() {
    List notes = new ArrayList<>();
 
    // Select Sorgusu
    String selectQuery = "SELECT  * FROM " + Note.TABLE_NAME + " ORDER BY " +
            Note.COLUMN_TIMESTAMP + " DESC";
 
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);
 
    if (cursor.moveToFirst()) {
        do {
            Note note = new Note();
            note.setId(cursor.getInt(cursor.getColumnIndex(Note.COLUMN_ID)));
            note.setNote(cursor.getString(cursor.getColumnIndex(Note.COLUMN_NOTE)));
            note.setTimestamp(cursor.getString(cursor.getColumnIndex(Note.COLUMN_TIMESTAMP)));
 
            notes.add(note);
        } while (cursor.moveToNext());
    }
 
    // veritabanı bağlantısını kapatalım
    db.close();
 
    // notların tümünü döner
    return notes;
}
 
public int getNotesCount() {
    String countQuery = "SELECT  * FROM " + Note.TABLE_NAME;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(countQuery, null);
 
    int count = cursor.getCount();
    cursor.close();
 
 
    // notların sayısını döner
    return count;
}

c. Notun Güncellenmesi

Bu fonksiyon veritabanına yazma imkanı sunan getWritableDatabase() metoduna erişim gerektirmektedir. Aşağıdaki kodlamada veritabanında kayıtlı bir notun nasıl güncellenebildiğini görebilirsiniz;

public int updateNote(Note note) {
    SQLiteDatabase db = this.getWritableDatabase();
 
    ContentValues values = new ContentValues();
    values.put(Note.COLUMN_NOTE, note.getNote());
 
    // notunu güncelleyelim
    return db.update(Note.TABLE_NAME, values, Note.COLUMN_ID + " = ?",
            new String[]{String.valueOf(note.getId())});
}

c. Notun Silinmesi

Bu fonksiyon veritabanına yazma imkanı sunan getWritableDatabase() metoduna erişim gerektirmektedir. Aşağıdaki kodlamada veritabanında kayıtlı bir notun nasıl silindiğini görebilirsiniz;

public void deleteNote(Note note) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(Note.TABLE_NAME, Note.COLUMN_ID + " = ?",
            new String[]{String.valueOf(note.getId())});
    db.close();
}

7. utils paketi altında, RecyclerTouchListener.java ve MyDividerItemDecoration.java adında sınıflar oluşturun.

  • RecyclerTouchListener sınıfı ile listelemede tıklanan alan ile alakalı alınacak aksiyonlar tanımlanır.
  • MyDividerItemDecoration sınıfı ile listeler arasına çizilmesi istenen çizgilerin oluşturulmasında kullanılmaktadır.

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
 
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
 
    private ClickListener clicklistener;
    private GestureDetector gestureDetector;
 
    public RecyclerTouchListener(Context context, final RecyclerView recycleView, final ClickListener clicklistener) {
 
        this.clicklistener = clicklistener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
 
            @Override
            public void onLongPress(MotionEvent e) {
                View child = recycleView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clicklistener != null) {
                    clicklistener.onLongClick(child, recycleView.getChildAdapterPosition(child));
                }
            }
        });
    }
 
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clicklistener != null && gestureDetector.onTouchEvent(e)) {
            clicklistener.onClick(child, rv.getChildAdapterPosition(child));
        }
 
        return false;
    }
 
    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
 
    }
 
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
 
    }
 
    public interface ClickListener {
        void onClick(View view, int position);
 
        void onLongClick(View view, int position);
    }
}

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.View;
 
public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {
 
    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };
 
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
 
    private Drawable mDivider;
    private int mOrientation;
    private Context context;
    private int margin;
 
    public MyDividerItemDecoration(Context context, int orientation, int margin) {
        this.context = context;
        this.margin = margin;
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }
 
    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }
 
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }
 
    public void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left + dpToPx(margin), top, right - dpToPx(margin), bottom);
            mDivider.draw(c);
        }
    }
 
    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top + dpToPx(margin), right, bottom - dpToPx(margin));
            mDivider.draw(c);
        }
    }
 
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
 
    private int dpToPx(int dp) {
        Resources r = context.getResources();
        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
    }
}

1. Notlarım Uygulamasının Arayüzünün Tasarlanması

Veritabanı ile alakalı işlemler gerçekleştirildi. Şimdi sıra uygulamanın arayüzünün oluşturulması ve bunun veritabanı ile ilişkilendirilmesinde;

Öncelikle notlarımız listelendiği bir layout sayfasına ve bununla ilişkili adapter sınıfına ihtiyacımız bulunmakta.

9. Her notun tek başına görüntülenebildiği arayüzü oluşturmak için note_list_row.xml adında bir layout oluşturun.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:foreground="?attr/selectableItemBackground"
    android:paddingBottom="@dimen/dimen_10"
    android:paddingLeft="@dimen/activity_margin"
    android:paddingRight="@dimen/activity_margin"
    android:paddingTop="@dimen/dimen_10">
 
    <TextView
        android:id="@+id/dot"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/dot_height"
        android:layout_marginRight="@dimen/dot_margin_right"
        android:layout_marginTop="@dimen/dimen_10"
        android:includeFontPadding="false"
        android:textColor="@color/colorAccent"
        android:lineSpacingExtra="0dp"
        android:textSize="@dimen/dot_text_size" />
 
    <TextView
        android:id="@+id/timestamp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/dot"
        android:textColor="@color/timestamp"
        android:textSize="@dimen/timestamp" />
 
    <TextView
        android:id="@+id/note"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/timestamp"
        android:layout_toRightOf="@id/dot"
        android:textColor="@color/note_list_text"
        android:textSize="@dimen/note_list_text" />
 
</RelativeLayout>


10. view paketi altında, NotesAdapter.java adında bir sınıf oluşturalım. Bu adapter arayüz ile alakalı yapılması planlanan gösterimlerde kullanılacaktır. Ayrıca listelemede tıklanan notun hangisi olduğunu belirlemeye de yaramaktadır.

 

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
 
import info.androidhive.sqlite.R;
import info.androidhive.sqlite.database.model.Note;
 
public class NotesAdapter extends RecyclerView.Adapter {
 
    private Context context;
    private List notesList;
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView note;
        public TextView dot;
        public TextView timestamp;
 
        public MyViewHolder(View view) {
            super(view);
            note = view.findViewById(R.id.note);
            dot = view.findViewById(R.id.dot);
            timestamp = view.findViewById(R.id.timestamp);
        }
    }
 
 
    public NotesAdapter(Context context, List notesList) {
        this.context = context;
        this.notesList = notesList;
    }
 
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.note_list_row, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Note note = notesList.get(position);
 
        holder.note.setText(note.getNote());
 
        // Her notun başında nokta simgesinin gösterimi
        holder.dot.setText(Html.fromHtml("•"));
 
        // Oluşturulduğu zaman diliminin formatlanması ve görüntülenmesi
        holder.timestamp.setText(formatDate(note.getTimestamp()));
    }
 
    @Override
    public int getItemCount() {
        return notesList.size();
    }
 
    private String formatDate(String dateStr) {
        try {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = fmt.parse(dateStr);
            SimpleDateFormat fmtOut = new SimpleDateFormat("MMM d");
            return fmtOut.format(date);
        } catch (ParseException e) {
 
        }
 
        return "";
    }
}


3.1 Yeni Not Ekleme/Güncellemede Kullanılacak Dialogların Oluşturulması

Oluşturulacak dialogda sadece not girilmesi veya notun editlenebilmesi gibi özellik içerdiğinden EditText elementinin layouta eklenmesi yeterli olacaktır. Burada daha hızlı aksiyon almak adına direkt olarak Dialog elementini kullanabiliriz.

10. Yeni not girmede kullanılacak olan note_dialog.xml adında bir layout oluşturun.

 

 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_margin"
    android:paddingRight="@dimen/activity_margin"
    android:paddingTop="@dimen/activity_margin">
 
    <TextView android:id="@+id/dialog_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/dimen_10"
        android:fontFamily="sans-serif-medium"
        android:lineSpacingExtra="8sp"
        android:text="@string/lbl_new_note_title"
        android:textColor="@color/colorAccent"
        android:textSize="@dimen/lbl_new_note_title"
        android:textStyle="normal" />
 
    <EditText
        android:id="@+id/note"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:gravity="top"
        android:hint="@string/hint_enter_note"
        android:inputType="textCapSentences|textMultiLine"
        android:lines="4"
        android:textColorHint="@color/hint_enter_note"
        android:textSize="@dimen/input_new_note" />
 
</LinearLayout>


11. activity_main.xml ve content_main.xml dosyalarını açın ve içerisine RecyclerView widgetini ekleyin.

 
 
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/coordinator_layout"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="info.androidhive.sqlite.view.MainActivity">
 
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
 
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
 
    </android.support.design.widget.AppBarLayout>
 
    <include layout="@layout/content_main" />
 
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@drawable/ic_add_white_24dp" />
 
</android.support.design.widget.CoordinatorLayout>


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="info.androidhive.sqlite.view.MainActivity"
    tools:showIn="@layout/activity_main">
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
    <TextView
        android:id="@+id/empty_notes_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/margin_top_no_notes"
        android:fontFamily="sans-serif-light"
        android:text="@string/msg_no_notes"
        android:textColor="@color/msg_no_notes"
        android:textSize="@dimen/msg_no_notes" />
 
</RelativeLayout>


12. Son olarak MainActivity.java sınıfını açıp aşağıdaki düzenlemeleri yapın;

  • showNoteDialog() metodu yeni bir not girilmesi için dialog açmaktadır.
  • createNote() veritabanına yeni kayıt eklenmesi ve eklenen yeni kaydın notların listelendiği arayüzde gözükmesini sağlamaktadır.
  • showActionsDialog() fonksiyonu `Güncelle` ve `Sil` seçeneklerinin görüntülenmesini sağlamaktadır. Bu arayüze ulaşmak için listelemede bulunan notlardan herhangi birisine uzun süre basılı tutmanız gerekmektedir.
  • Güncelle seçeneğine tıklanıldığında, tıklanılan notun text kısmı dialog içerisinde editlenecek şekilde görüntülenmektedir. updateNote() metodu çağrılarak, mevcut kaydın veritabanında güncellenmesi ve arayüze yansıması sağlanmaktadır.
  • deleteNote() metodu veritabanında ilgili notun silinmesini sağlamaktadır. Listelemede görüntülenen kaydın silinmesi için adaptere ait notifyItemRemoved() metodunun çağrılması gerekmektedir.
  • toggleEmptyNotes() metodu ise notların sayısına bağlı olarak eğer herhangi bir not bulunmuyorsa ona göre farklı bir arayüz gösterimine gidilmesini sağlamaktadır.

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
 
import java.util.ArrayList;
import java.util.List;
 
import info.androidhive.sqlite.R;
import info.androidhive.sqlite.database.DatabaseHelper;
import info.androidhive.sqlite.database.model.Note;
import info.androidhive.sqlite.utils.MyDividerItemDecoration;
import info.androidhive.sqlite.utils.RecyclerTouchListener;
 
public class MainActivity extends AppCompatActivity {
    private NotesAdapter mAdapter;
    private List notesList = new ArrayList<>();
    private CoordinatorLayout coordinatorLayout;
    private RecyclerView recyclerView;
    private TextView noNotesView;
 
    private DatabaseHelper db;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        coordinatorLayout = findViewById(R.id.coordinator_layout);
        recyclerView = findViewById(R.id.recycler_view);
        noNotesView = findViewById(R.id.empty_notes_view);
 
        db = new DatabaseHelper(this);
 
        notesList.addAll(db.getAllNotes());
 
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showNoteDialog(false, null, -1);
            }
        });
 
        mAdapter = new NotesAdapter(this, notesList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
        recyclerView.setAdapter(mAdapter);
 
        toggleEmptyNotes();
 
        
        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this,
                recyclerView, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, final int position) {
            }
 
            @Override
            public void onLongClick(View view, int position) {
                showActionsDialog(position);
            }
        }));
    }
 
    private void createNote(String note) {
        // yeni not ekleyin
        long id = db.insertNote(note);
 
        // veritabanına eklenen yeni notun id bilgisini alın.
        Note n = db.getNote(id);
 
        if (n != null) {
            // listeye yeni not ekleyin
            notesList.add(0, n);
 
            // listelemeyi güncelleyin
            mAdapter.notifyDataSetChanged();
 
            toggleEmptyNotes();
        }
    }
 
    private void updateNote(String note, int position) {
        Note n = notesList.get(position);
        // notun text kısmını setleyin
        n.setNote(note);
 
        // notu veritabanında güncelleyin
        db.updateNote(n);
 
        // listeyi güncelleyin
        notesList.set(position, n);
        mAdapter.notifyItemChanged(position);
 
        toggleEmptyNotes();
    }
 
    private void deleteNote(int position) {
        // veritabanından notu silin
        db.deleteNote(notesList.get(position));
 
        // listeden notu kaldırın
        notesList.remove(position);
        mAdapter.notifyItemRemoved(position);
 
        toggleEmptyNotes();
    }
 
    private void showActionsDialog(final int position) {
        CharSequence colors[] = new CharSequence[]{"Güncelle", "Sil"};
 
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Seçeneği seçin");
        builder.setItems(colors, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {
                    showNoteDialog(true, notesList.get(position), position);
                } else {
                    deleteNote(position);
                }
            }
        });
        builder.show();
    }
  
    private void showNoteDialog(final boolean shouldUpdate, final Note note, final int position) {
        LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
        View view = layoutInflaterAndroid.inflate(R.layout.note_dialog, null);
 
        AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(MainActivity.this);
        alertDialogBuilderUserInput.setView(view);
 
        final EditText inputNote = view.findViewById(R.id.note);
        TextView dialogTitle = view.findViewById(R.id.dialog_title);
        dialogTitle.setText(!shouldUpdate ? getString(R.string.lbl_new_note_title) : getString(R.string.lbl_edit_note_title));
 
        if (shouldUpdate && note != null) {
            inputNote.setText(note.getNote());
        }
        alertDialogBuilderUserInput
                .setCancelable(false)
                .setPositiveButton(shouldUpdate ? "güncelle" : "kaydet", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialogBox, int id) {
 
                    }
                })
                .setNegativeButton("iptal",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogBox, int id) {
                                dialogBox.cancel();
                            }
                        });
 
        final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
        alertDialog.show();
 
        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Herhangi bir not girilmediğinde hata mesajının gösterilmesi
                if (TextUtils.isEmpty(inputNote.getText().toString())) {
                    Toast.makeText(MainActivity.this, "Not Girin!", Toast.LENGTH_SHORT).show();
                    return;
                } else {
                    alertDialog.dismiss();
                }
 
                // eğer kullanıcı notlarda güncelleme yapıyorsa
                if (shouldUpdate && note != null) {
                    // kayıtlı notu id verisi ile güncellemek
                    updateNote(inputNote.getText().toString(), position);
                } else {
                    // yeni not oluşturma
                    createNote(inputNote.getText().toString());
                }
            }
        });
    }
 
    /**
     * Eğer kayıtlı not bulunmuyorsa layout değişikliğinin sağlanması
     */
    private void toggleEmptyNotes() {
 
        if (db.getNotesCount() > 0) {
            noNotesView.setVisibility(View.GONE);
        } else {
            noNotesView.setVisibility(View.VISIBLE);
        }
    }
}


Böylelikle SQLite kullanarak Android uygulamada basit bir not uygulaması hazırlanmış oldu. ]]>
React Native ile Android ve iOS Programlama Geliştirme http://yazilimdersi.info/makaleler/detay/104/react-native-ile-android-ve-ios-programlama-gelistirme Tue, 25 Feb 2020 00:00:00 +0000 mstfchelikReact Native, React kod yazarak web uygulaması geliştiren yazılımcıların aynı zamanda mobil platformlar içinde kod yazabilmesine imkan sunan ve Facebook tarafından geliştirilen bir dildir. Böylelikle mobilde native uygulama geliştiren yazılımcıların güncellemelerde hem Android hem iOS kodlarında çalışma yapmalarına gerek kalmaksızın yeni versiyonun yayına almasını sağlayarak daha verimli sonuçların elde edilmesine imkan tanımıştır.

React Native Nedir?
React Native, ReactJS çatısını baz alarak native arayüzler aracılığıyla mobil uygulama yazılmasını sağlayan bir geliştirme ortamıdır. Native arayüz bileşenlerini barındırdığından React dilinde bulunan <div> bileşeni yerine Android ve iOS’teki arayüzü karşılığına dönüşecek olan <View> bileşeni, <img> yerine ise <Image> bileşeni kullanılır. <View> ve <Image> gibi componentler Facebook tarafından Android ve iOS karşılıklarının kodlanmasıyla oluşturulmuş yapılardır.

React Native Çalışma Yapısı
React Native uygulamalarında ve gibi componentlerin native uygulamadaki karşılıklarını tanımlayan ara bir bridge yapısı bulunmaktadır. Bu yapının nasıl oluşturulduğunu gözlemlemeniz için aşağıdaki resmi inceleyebilirsiniz.

React ve React Native gibi uygulamaların kodlanmasında, kodlamaya pratiklik katan JSX kodları kullanılmaktadır. Yazılan JSX kodu, uygulamanın çalışması ile birlikte Android ve iOS platformları için tasarlanan köprüler yardımıyla ilgili platformun Native bileşenlerine dönüştürür. Böylelikle uygulamanın native olarak yazılmasıyla arasında bir fark kalmıyor. Uygulama çalıştığı sürece native bileşene render işlemi gerçekleştirilmesi CPU tüketimine sebep olduğu için pil tüketimi native uygulamaya göre daha fazladır. Ancak aradaki fark çok küçük olduğundan kullanıcı tarafında herhangi bir sorun teşkil etmeyecektir. React Native bridge sadece UI bileşenlerine değil, ayrıca cihazda bulunan kamera, mikrofon, sensör gibi hardware componentlerine de erişim imkanı sunmaktadır. Ancak oyun kodlama yada image processing gibi işlemler gerçekleştirilmek istendiğinde native dili kullanmanızı tavsiye ederim.

React Native Kurulumu
React Native uygulama geliştirmede gereksinimlerden en önemlisi Android ve iOS SDK lerin kurulu olması konusudur. Ayrıca iOS uygulama geliştirme esnasında simulator gereksiniminden dolayı uygulamalarınızı MacOSX cihazlarda çalışır hale getirmenizi tavsiye ederiz. Aksi takdirde uygulamanızı sadece kodlar ancak simülasyonda çalışır versiyonunu gözlemleyemezsiniz.

#npm install ile react-native-cli modülünün kurulması
npm install -g react-native-cli

#react_ilk_uygulama isimli React Native uygulaması oluşturulması
react-native init react_ilk_uygulama

Yukarıdaki komutu çalıştırmanız ile birlikte react_ilk_uygulama isimli dizinde React Native projesi oluşturulur. Oluşturulan dizin yapısı şu şekilde olacaktır;

  • tests: Facebook’un JavaScript test aracı ile alakalı bileşenler bu kısımda yer almaktadır.
  • android: Android platformuna ait dosyalar bu kısımda yer almaktadır.
  • ios: iOS platformuna ait dosyalar bu kısımda yer almaktadır.
  • node_modules: Projede kullanılan npm modülleri bu dizin altında kurulmaktadır.
  • .babelrc: Babel JavaScript derleyicisine ait yapılandırma dosyası olan .babelrc, "presets": ["react-native"] satırı ile node_modules dizininde yer alan babel-preset-react-native plugin’inin kullanılacağını belirtmektedir.
  • .buckconfig: Android uygulaması için build sürümü ve maven repo url’ini barındırmaktadır.
  • .flowconfig: React Native projesi ile ilgili çeşitli yapılandırma ayarlarını içermektedir.
  • .gitattributes/.gitignore: Git versiyon kontrol sistemi ile ilgili yapılandırma dosyalarını içermektedir.
  • .watchmanconfig: Projenin development aşamasında yapılan değişikliklerin ekrana anında yansıması için kullanılan watchman pluginine ait dosyaları içermektedir.
  • App.js: React Native uygulama dosyasıdır.
  • app.json: Uygulamanın manifest dosyasıdır.
  • index.js: Uygulamanın derlendiğinden ilk çalışan dosyasıdır. İlgili bileşenler ve başlangıç bileşeni bu dosyada belirtilir.
  • package.json: Proje ile ilgili bağımlılıkların npm’e belirtildiği ana dosyadır. Proje adı, versiyonu, lisans bilgisi, dependecies ve diğer ilgili ayarlar burada tutulur.


React Native Uygulama Kodu İnceleme:
Yukarıda projenin dosyalarını inceledikten sonra default uygulamada bileşenlerin nasıl tanımlandığını inceleyelim. Belirtiğimiz üzere proje içerisinde uygulama dosyası olarak App.js dosyası bulunmektadır. React Native temelinde React programlama dili üzerine kurgulandığı için eğer App.js dosyasını incelerseniz sizin için daha anlaşılır olduğunu gözlemleyebilirsiniz. Burada React programlamadan farklı olarak <div> ve <p> yerine, <View> ve <Text> componentleri bulunmaktadır. Aşağıda oluşturulan uygulamanın kodlarını gözlemleyebilirsiniz.
export default class App extends Component<{}> { 

  render() { 

    return ( 
      <View style={styles.container}>
        <Text style={styles.welcome}> 
          Welcome to React Native! 
        </Text> 
        <Text style={styles.instructions}> 
          To get started, edit App.js 
        </Text> 
        <Text style={styles.instructions}> 
          {instructions} 
        </Text> 
      </View> ); 

  } 

}
Dosyada gördüğünüz üzere uygulamanın ilk sayfasında Welcome to React Native texti görüntülenecek şekilde bir kodlama gerçekleştirilmiştir. Projenin çalıştırılması için aşağıdaki komutları çalıştırmanız gerekmektedir.

#android uygulamayı derlemek için kullanılan kod
react-native run-android

#ios uygulamayı derlemek için kullanılan kod
react-native run-ios

Projenin Android uygulama olarak derlenmesi için ANDROID_HOME değişkeninin ortam değişkeni olarak bilgisayarınıza eklemesi gerekmektedir. Bunun için öncelikle Android SDK'yini linkten indirmeniz gerekmektedir. Sonrasında aşağıda tanımlı olan komut ile ortam değişkeninize ANDROID_HOME değişkenini tanımlayabilirsiniz.
#Windows için

set ANDROID_HOME=C:\<installation location>\android-sdk-windows 

set PATH=%PATH%;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools

#Mac OS X için

export ANDROID_HOME=/<installation location>/android-sdk-macosx 

export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools

Komutun çalışması ile birlikte emülatörde yazılı olan mesajı gözlemleyebilirsiniz.


Böylelikle ilk React Native uygulamamızı Android cihazımızda gözlemlemiş olduk. Şimdi uygulamanın arkaplan renginde ve textlerin renginde birkaç kod değişikliği yaparak değişikliklerin nasıl anlık olarak cihazınıza iletildiğini gözlemleyelim. Aşağıda bulunan kod parçası ile hem anasayfada görüntülenen text bilgisini, hem de background rengini rahatlıkla değiştirebiliriz. Altta bulunan kodlamayı App.js dosyası içerisine yapıştırınız.
export default class App extends Component<{}> { 

  render() { 

    return ( 
      <View style={styles.container}>
        <Text style={styles.welcome}> 
          React Native projeme hoşgeldiniz! 
        </Text> 
      </View> ); 

  } 

}

const styles = StyleSheet.create({ 
    
    container: { 
       flex: 1, 
       justifyContent: 'center', 
       alignItems: 'center', 
       backgroundColor: '#FF0000'
    }, 

    welcome: { 
       fontSize: 20, 
       textAlign: 'center', 
       margin: 10, 
       color: '#CCCCCC'
    }
 
});

Yapılan değişiklikler sonrasında uygulamanın son halini aşağıdaki şekilde görebilirsiniz. Gördüğünüz gibi yaptığımız düzenleme hem text hemde background renginde değişikliğe sebep olmuş durumda.

]]>
React ile Progressive Web App Oluşturmak http://yazilimdersi.info/makaleler/detay/103/react-ile-progressive-web-app-olusturmak Tue, 25 Feb 2020 00:00:00 +0000 mstfchelikProgressive Web App isminden de anlaşıldığı üzere mobil uygulamada ortaya çıkan kullanıcı deneyimini websitelerinde de sunmak amacıyla hazırlanan bir veri biçimidir. Hazırlanan yapı ile birlikte mobil uygulamada sağlanan push notification bildirimi, responsive arayüz, offline çalışalabilirlik gibi birçok özelliği progressive web app çatısı altında websitenizde gerçekleştirebilirsiniz. Google PWA teknolojisini destekleyerek mobil kullanıcılar için modern-web teknolojisinde ortaya çıkan sorunların giderilmesine yönelik adımları son zamanlarda daha çok ön plana çıkarmaya başlamıştır.

PWA, aslında tamamen mobil cihazlar için tasarlanmış hız ve performans odaklı web uygulamalarıdır. PWA yapısına uygun tasarlanmış olan siteler mobil cihazınızın anasayfasına direkt bir mobil uygulama gibi kayıt edilmesini sağlamakta ve native bir mobil uygulamada olan (çevrimdışı erişim ve push bildirimleri gibi özellikler de dahil) birçok özelliği desteklemektedir. Şimdi sizlere popülerliği her geçen gün artan React programlama dili ile PWA tabanlı bir sitenin nasıl gerçekleştirildiği ile alakalı bilgi paylaşımında bulunacağız.
 
1. Kurulumların Gerçekleştirilmesi:
Öncelikle create-react-app komutu kullanılarak aşağıdaki şekilde basit bir React uygulamasının oluşturulması gerekmektedir.
#npm init ile package.json dosyası yoksa oluşturulması
npm init

#npm ile create-react-app modülünün yüklenmesi
npm install -g create-react-app

#create-react-app ile yeni uygulama oluşturulması
create-react-app ornek-pwa-uygulamasi

Yukarıdaki komutun çalıştırılması ile birlikte aşağıdaki şekilde bir ekran görüntüsü oluşacaktır.

create-react-app

Sonrasında link yönlendirmelerini gerçekleştirebilmemiz için React-Router modülü aşağıdaki şekilde kuralım.
cd ornek-pwa-uygulamasi

#react-router modulunun kurulması
npm install --save [email protected]

Daha sonra hazırlanan proje kodunda src dizini içine girilerek App.js dosyasının aşağıdaki kodlara göre güncellenmesi gerekmektedir.
#src dizini içerisine girin.
cd src

#App.js dosyası içerisine asagıdaki kodu yapıştırın.

import React, { Component } from 'react'; 
import { Router, browserHistory, Route, Link } from 'react-router'; 
import logo from './logo.svg'; 
import './App.css'; 

const Page = ({ title }) => ( 
        
        <div className="App"> 
          <div className="App-header"> 
            <img src={logo} className="App-logo" alt="logo" /> 
            <h2>{title}</h2> 
          </div> 
          <p className="App-intro"> Bu {title} sayfasıdır. </p> 
          <p> <Link to="/">Anasayfa</Link> </p> 
          <p> <Link to="/hakkinda">Hakkında</Link> </p> 
          <p> <Link to="/ayarlar">Ayarlar</Link> </p> </div> 
); 

const Anasayfa = (props) => ( 
        <Page title="Anasayfa"/> 
);
 
const Hakkinda = (props) => ( 
        <Page title="Hakkinda"/> 
); 

const Ayarlar = (props) => ( 
        <Page title="Ayarlar"/> 
); 

class App extends Component { 
         render() { 
             return ( <Router history={browserHistory}> 
                      <Route path="/" component={Anasayfa}/> 
                      <Route path="/hakkinda" component={Hakkinda}/> 
                      <Route path="/ayarlar" component={Ayarlar}/> 
                      </Router> 
                    );
         } 
} 

export default App;
Son olarak npm start komutunu çalıştırarak projenin 3000 portu üzerinden çalışmasını sağlayabilirsiniz.
#projenin çalıştırılması
npm start

2. Lighthouse Chrome Plugin Kurulumu:
LightHouse Google tarafından geliştiriciler için oluşturulmuş, sitenizi PWA tabanlı hazırlamak için yararlanabileceğiniz bir araçtır. Sağladığı birçok yarar bulunmaktadır. Geliştirme süresince tool üzerinden eksik kalan konularla alakalı geri bildirimleri alabilirsiniz.

Öncelikle Lighthouse uzantısını Chromenuza linke tıklayarak yükleyiniz. Sonrasında browserinizde açılmış olan http://localhost:3000 sayfasının olduğu taba geçiniz ve LightHouse uzantısında bulunan Generate Reports butonuna tıklayınız. Açılan popup dialogta sitenizin PWA yapısına uyum durumu hakkında progressive bar gözükecektir.


Yukarıdaki resimde görüldüğü üzere PWA için yapılması ve izlenmesi gereken adımlarımız bulunmaktadır. Şimdi bunları adım adım gerçekleyelim;

3. Service Worker Kurulması:
Service worker uygulamamız ile network arasında bulunan bir javascript tabanlı köprü gibidir. Bu yapı kullanılarak network hataları veya alınan dosyaların cachelenmesi gibi durumların oluşturulması sağlanacaktır. Böylelikle offline çalışma yapısına uygun bir kurguda bu worker sayesinde tanımlanabilecektir. Yapılması gereken adımlar şu şekildedir;
  • public dizini altında service-worker.js dosyası oluşturmak,
  • service worker dosyasını index.html dosyasına kayıt etmek,
  • Cacheleme mekanizmasının kurulması
Öncelikle public dizini altında service-worker.js adında bir javascript dosyası oluşturun. Sonrasında ise browserin registeri destekleyip desteklemediğini belirlemek için aşağıdaki kod parçasını index.html dosyasına yapıştırınız.
<!doctype html> 
<html lang="en"> 
    <head> 
      <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> 
      <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> 
      <title>React Uygulaması</title> 
    </head> 
    
    <body> 
        <div id="root"></div> 
        <script> 
            if ('serviceWorker' in navigator) { 

                window.addEventListener('load', function() { 
                   navigator.serviceWorker.register('service-worker.js').then(function(registration) { 
                   console.log('ServiceWorker registration successful with scope: ', registration.scope); 
                }, function(err) {  
                   console.log('ServiceWorker registration failed: ', err); 
                }).catch(function(err) { 
                  console.log(err) 
                }); 

            }); 
            } else { 
                console.log('service worker is not supported'); 
            } 
       </script> 
    </body> 
</html>
Son olarak cache mekanizmasının hazırlanması kaldı. Aşağıdaki kod parçacığını daha önceden oluşturduğumuz service.workers.js dosyası içerisine yapıştıralım.
var doCache = false; 
 
var CACHE_NAME = 'my-pwa-cache-v1'; 

self.addEventListener("activate", event => { 
    const cacheWhitelist = [CACHE_NAME]; 
    event.waitUntil( 
        caches.keys().then(keyList => 
            Promise.all(keyList.map(key => 
            { 
                if (!cacheWhitelist.includes(key)) { 
                    console.log('Deleting cache: ' + key) 
                    return caches.delete(key); 
            } 
        })) ) ); 
   }); 
   
self.addEventListener('install', 
    function(event) { 
    if (doCache) { 
          event.waitUntil( caches.open(CACHE_NAME) .then(
          function(cache) { 
              fetch("asset-manifest.json") .then(response => { response.json() }) .then(assets => { 
              const urlsToCache = [ "/", assets["main.js"] ] 
              cache.addAll(urlsToCache) console.log('cached'); 
       }) }) ); 
} });


self.addEventListener('fetch', function(event) { 
    if (doCache) { 
        event.respondWith( caches.match(event.request).then(
        function(response) { 
              return response || fetch(event.request); }) ); 
        } 
});
Şimdi tekrardan Lighthouse pluginini çalıştırıp generate report ile son durumu gözlemleyelim.



Yukarıdaki resimde de gördüğünüz gibi service worker ile alakalı hata giderilmiş oldu. Halen caching ile alakalı hata gözükmekte ancak bunun sebebi halen uygulamada cache mekanizmasını çalışır hale getirmedik. Bunu çalışır duruma getirmemiz ile birlikte bu hata listeden kalkacaktır.

4. Javascript yüklenmeden çalışma yöntemi eklenmesi:
Şimdi sıra sitenize giriş yapıldığı anda Javascript yüklenmesine gerek kalmaksızın sitenin çalışırlığının sağlanmasında. Şimdi index.html sayfamızın içerikleri javascript ile doldurulmaktadır. Bunun öncesinde React ile içeriğin doldurulması yerine html ve css ile sayfanın boş gelmesi engellenecektir. Aşağıdaki kod satırını kopyalarak içeriği ayarlayalım.
<!doctype html>

<html lang="en">

  <head>

    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

    <title>React Uygulaması</title>

    <!-- Add in some basic styles for our HTML -->

    <style type="text/css">

      body {

        margin: 0;

        padding: 0;

        font-family: sans-serif;

      }

      .App {

        text-align: center;

      }

      .App-header {

        background-color: #222;

        height: 150px;

        padding: 20px;

        color: white;

      }

      .App-intro {

        font-size: large;

      }

    </style>

  </head>

  <body>

    <!-- Filler HTML as our app starts up -->

    <div id="root">

      <div class="App">

      <div class="App-header">

        <h2>Home</h2>

      </div>

      <p class="App-intro">

        Site yükleniyor..

      </p>

    </div>

    <script>

      if ('serviceWorker' in navigator) {

        window.addEventListener('load', function() {

          navigator.serviceWorker.register('service-worker.js').then(function(registration) {

            // Registration was successful

            console.log('ServiceWorker registration successful with scope: ', registration.scope);

          }, function(err) {

            // registration failed :(

            console.log('ServiceWorker registration failed: ', err);

          }).catch(function(err) {

            console.log(err)

          });

        });

      } else {

        console.log('service worker is not supported');

      }

    </script>

  </body>

</html>
5. Siteye mobil uygulama özelliği kazandırılması:
Burada yapılacak çalışma sonrasında sitenizi ziyaret eden kullanıcı websitenizi mobil bir uygulama gibi telefonunun anasayfasına kayıt edebilecektir. Yapılması gereken ilk şey public dizini altında manifest.json dosyasını oluşturmanız ve aşağıdaki içeriğin kopyalanmasıdır.
{    
    "short_name": "İlk PWA Uygulamam", 
    "name": "İlk Progressive Web Uygulamam", 
    "icons": [ { "src":"icon.png", "sizes": "192x192", "type": "image/png" } ], 
    "start_url": "/?utm_source=homescreen", 
    "background_color": "#222", 
    "theme_color": "#222", 
    "display": "standalone" 
}

icon.png dosyasının boyutu 192x192 şeklinde olmalıdır.

manifest.json dosyasını ve icon.png dosyasını public dizini altına koyduktan sonra index.html dosyasının header kısmını aşağıdaki şekilde güncelleyelim.
<!doctype html>

<html lang="en">

  <head>

    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

    <!-- manifest dosyasını tanımla --> 
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json"> 

    <!-- Browsera PWA uyumlu olduğunu söyle --> 
    <meta name="mobile-web-app-capable" content="yes"> 

    <!-- iOS'a PWA uyumlu olduğunu söyle --> 
    <meta name="apple-mobile-web-app-capable" content="yes"> 

    <!-- Tema renginin tanımlı olduğundan emin ol --> 
    <meta name="theme-color" content="#536878">
    <title>React Uygulaması</title>

6. Firebase Üzerinde Uygulamanın Çalıştırılması:
Son olarak uygulama artık PWA yapısına uygun hale getirilmiştir. Şimdi yapılması gereken uygulamamızı canlıya almak. Öncelikle uygulamanın cache mekanizmasını service-worker.js dosyasında bulunan doCache = false satırını true olarak setleyerek aktif hale getirelim. Sonrasında Firebase Konsoluna gidip orada yeni bir uygulama oluşturalım. Daha sonra komut satırına gidip aşağıdaki kodlamaları çalıştıralım.
#firebase-tools indirilmesi
npm install -g firebase-tools

#firebase modülüne giriş
firebase login

#firebase tabanlı proje oluşturulması
firebase init

#firebasede projenin canlıya atılması
npm run build && firebase deploy

]]>
Ubuntu 14.04de FFmpeg kurulumu http://yazilimdersi.info/makaleler/detay/101/ubuntu-1404de-ffmpeg-kurulumu Tue, 25 Feb 2020 00:00:00 +0000 mstfchelik Popüler medya kütüphanelerinden olan FFmpeg, Ubuntu 14.04 sürümünden kaldırılarak yerine Libav getirildi. Ancak bu kütüphane, kullanıcıların taleplerini tamamen karşılayamamaktadır. Ubuntu bunun farkına vardı ve 15.04 sürümüne tekrar FFmpeg kütüphanesini embed etti. Ancak halen 14.04 sürümünde official olarak ffmpeg kütüphanesi bulunmamaktadır. Bu makalemizde Ubuntu 14.04 sürümüne FFmpeg kurulumun nasıl yapıldığı ile alakalı adımları anlatacağız.

Öncelikle aşağıda bulunan komut satırını terminalde çağırarak Ubuntu repository'sinize mc3man ppa kütüphanesini ekleyin.

    sudo add-apt-repository ppa:mc3man/trusty-media

Bu komutu Enter'e basarak çalıştırdığınızda, terminalde aşağıdaki ifadeyi görmeniz gerekmektedir;

    Also note that with apt-get a sudo apt-get dist-upgrade is needed for initial setup & with some package upgrades
    More info: https://launchpad.net/~mc3man/+archive/ubuntu/trusty-media
    Press [ENTER] to continue or ctrl-c to cancel adding it

Şimdi Ubuntu paketlerini aşağıdaki komutla güncelleyin.

   sudo apt-get update
   sudo apt-get dist-upgrade

Şu an Ubuntu 14.04 işletim sisteminiz FFmpeg kurulumuna uygun hale getirilmiştir. Aşağıdaki komutu çalıştırarak FFmpeg kurulumunu sorunsuz şekilde yerine getirebilirsiniz.

   sudo apt-get install ffmpeg
]]>
Havayolu Sorgulama http://yazilimdersi.info/makaleler/detay/100/havayolu-sorgulama Sun, 23 Feb 2020 00:00:00 +0000 mstfchelikIATA (International Air Transport Association) tüm dünyadan tarifeli havayolu taşıyıcılarının temsil edildiği ticari bir kuruluştur.
  • 1945 yılında Havana, Küba’da 31 ülkeden 57 üyeyle kurulmuştur.
  • Şimdi ise dünya genelinde 140 ülkeden 270’in üzerinde havayolu üyedir. Toplam tarifeli hava trafiğinin %98’ini kapsar.
  • Merkezi Kanada’nın Montreal şehrinde olup “Clearing House” merkezi İsviçre’nin Cenevre kentindedir.
IATA’nın esas amacı hem yolcular hem de havayolu şirketleri için havayolu taşımacılığının mümkün olan en yüksek hızda, emniyette, güvenlikte, uygunlukta ve verimlilikte gerçekleşmesini sağlamaktır. Temel olarak tarife koordinasyonu (bilet fiyatları, oranlar, ücretler ve seyahat acente komisyon oranları) ile ilgilenmektedir. Hem organizasyon olarak hem de faaliyetleri açısından IATA, ICAO ile işbirliği halindedir.

Havayolu firmalarının tümünün üyesi olduğu bu kuruluşlarda unique olarak atanmış ICAO ve IATA kodları bulunmaktadır. Bu kodlar sayesinde havayolu firmaları kimliklerini edinmiş ve tüm dünyada geçerliliği kabul görmüş kodlar ile işlemler gerçekleştirmektedir. Hazırladığımız arayüz sayesinde herhangi bir havayolu firmasının adı ile arama yaparak IATA ve ICAO kodlarına rahatlıkla erişebilirsiniz.]]>
Android Google Play Hesabı Açma ve Apk yükleme (Resimli Anlatım) http://yazilimdersi.info/makaleler/detay/92/android-google-play-hesabi-acma-ve-apk-yukleme-(resimli-anlatim) Sun, 26 Jul 2015 00:00:00 +0000 mstfchelik 
Android uygulamaların geliştirilmesi ile alakalı bazı konuları daha önceki makalelerimizde sizlerle paylaşmıştık. Ancak oluşturduğumuz uygulamanın Play Storede nasıl kullanıcılarla buluşmasını sağlayacağımızı anlatmamıştık. Bu makalemizde detaylı olarak bu işlemlerin nasıl gerçekleştirildiği anlatılacaktır.

 1. Google Play Hesabı Nasıl Açılır: 
Öncelikle kullanmak istediğiniz Gmail hesabı ile yandaki linke tıklıyoruz. https://play.google.com/apps/publish/signup/ Çıkan ekranda Google Play Geliştirici Dağıtım Sözleşmesi’ni okuyup Hesap kaydınızın Google Play Geliştirici Dağıtım Sözleşmesi ile ilişkilendirilmesini kabul ediyor ve onaylatıyorsunuz. Aşağıda resimli olarak bu sayfaya ait ekran görüntülenmektedir.


Ardından Ödeme işlemine devam et butonuna tıklamanız gerekmektedir. Sonrasında karşınıza satın alma işlemi ile alakalı sayfa çıkacaktır. Sadece bir kereye mahsus hesabınızdan 25$ çekilmektedir. Bu ücret ile Google Play Store hesabınıza apk dosyalarını yükleme işlemini aktive edilebilmektesiniz. Aşağıda Ödeme işlemine devam et butonuna tıklanıldığında açılacak sayfaya ait görüntü bulunmaktadır.


Ekran görüntüsünden gördüğünüz üzere formda Ad, Adres, Posta Kodu, Bölge, Şehir, Kredi kartı bilgilerinizi girmeniz gerekmektedir. Sonrasında Google Play hesabınızın aktive hale geldiğine dair sayfa görüntülenecektir. Artık uygulamanıza ait apk dosyasını play store hesabınıza yükleyebilecek duruma gelebildiniz. Şimdi de yazdığınız Android uygulamanın nasıl apk dosyasına dönüştürülebilindiği ile alakalı konuyu inceleyeceğiz.

2. Uygulamanın Apk Dosyası Nasıl Oluşturulur: 
İlk yapmanız gereken yapmış olduğunuz projeye keystore koymanız yani kendi imzanızı atmanız gerekmektedir. Bu keystore olmadan yaptığınız uygulamayı upload edemezsiniz veya bu keystore'u kaybederseniz uygulamanıza güncelleme yapamazsınız. Uygulamanızı apk dosyasına dönüştürmeniz için ilk önce yapmış olduğumuz projeye sağ tıklayıp Android Tools->Export Signed Application Package adlı butonlara sırasıyla tıklayıp ileri tuşuna tıklıyoruz.


 
Sonrasında karşımıza gelen ekranda kendi oluşturmuş olduğumuz proje otomatik olarak seçili durumda gösterilmektedir. Next butonuna tıklayarak Keystore Selection ekranına gelmekteyiz.


Önceden keystore oluşturmadıysak Create New Keystore adlı checkboxa tıklıyoruz. Bu checkboxa tıkladıktan sonra yeni oluşturacağımız keystore dosyasının yükleneceği pathi Browse ile belirliyoruz. Ayrıca şifre atamasını burada gerçekleştiriyoruz. Bu kısım keystore için en önemli kısımdır. Çünkü yazılımcı arkadaşlar oluşturdukları keystorelere ait şifre bilgisini unuturlarsa uygulamalarını şifreleyemediklerinden dolayı tekrardan play storede update edemezler. Bu nedenle verilecek şifre kullanıcı açısından kolay hatırlanabilir bir ifade olmalıdır. Password ve Confirm alanları dolduruktan sonra Next butonuna tıklanılmalıdır. Aşağıdaki şekilde bir form karşınıza çıkacaktır.


 
Yukarıdaki formda bulunan fieldler şu anlamlara gelmektedir:
Alias: Oluşturduğumuz keystoreleri farklı projelerde de kullanabilmemizi sağlamaktadır. Bu alias alanlarını proje ismine baglı olarak düzenleyebilirsiniz. Örneğin; Horoscope
Password: Oluşturulan aliasa ait şifre kısmıdır.
Confirm: Oluşturulan şifrenin doğrulanması için tekrardan girildiği field alanıdır.
Validity (years): Bu alan keystore süresini belirlemede kullanılmaktadır. Google tarafından 25 yıl olarak setlenmesi tavsiye edilmektedir.
First And Last Name: Keystore sahibine ait bilgilerin yazıldığı kısımdır.
Organizational Unit: Burası uygulamayı yayına alan birimin girildiği kısımdır.
Organization: Kurumsal ise ona ait bilgiler bu alanda girilmektedir.
State or Province: Keystore datasının eklendiği yer olarak belirlenmektedir. İlçe veya semt olarak doldurulur.
Country Code: Ülke kodunun girildiği kısımdır.

Yukarıdaki alanları eksiksiz doldurmanız iyi olacaktır. Ancak bazı alanlar tamamen optional yani isteğe baglı olarak doldurulabilmektedir. Bu alan doldurulduktan sonra Finish butonuna basarak apk dosyasını oluşturmuş olursunuz. Eğer mevcut herhangi bir keystore dosyanız varsa, Use Existing Keystore checkboxına tıklayarak şifre alanını doldurmanız gerekmektedir. Sonrasında açılan sayfada da daha önceden proje için hazırlamış olduğunuz Aliası secmeniz ve ona ait şifreyi girmeniz gerekmektedir. Bu işlemleri yaptıktan sonra projemiz Google Play Store koyulabilir hale gelmiş oluyor.

3. Uygulamanın Apk Dosyasının Play Store Hesabına Yüklenmesi: 
En başta seçmiş olduğumuz Google Play hesabı ile giriş yapıyoruz. Google Play'de Android uygulaması yayınla butonuna tıklıyoruz. Karşımıza gelen pencerede yapmış olduğumuz projenin yayınlanacak olan adını ve dilini seçiyoruz. Örnek olarak uygulamamızın yayımlanacağı adı Best Daily Horoscope ve dilini İngilizce olarak belirleyelim.


Sonrasında APK Yükle diyoruz ve projemizi seçiyoruz. Aşağıda bulunan ekrana geçmektedir proje. Burada Üretim'e yeni APK Yükle butonuna tıklayarak projenizin apk dosyasını yükleyebilirsiniz.


Yüklendikten sonra sol taraftaki menüden Mağaza Girişi butonuna tıklıyoruz. Mağaza Girişi alanında uygulamamızın Play Storede listelenirken gösterilecek içeriklerin girildiği kısımdır. Burada Başlık, Kısa Açıklama, Tam Açıklama alanları bulunmaktadır ve girilmesi zorunludur.


Ayrıca uygulamanın ikonun eklendiği panelde bu kısımda bulunmaktadır. Uygulamaya ait screenshotlar yani ekran görüntüleri de buradan girilmektedir. Kullanıcılar isteğe bağlı olarak Telefon, 7 inch tablet, 10 inch tablet ve TV alanlarına ekran görüntülerini ekleyebilirler. Buraya eklenen resimler Play Store de arama yapılan cihazın tipine göre resimler öncelik bazlı listelenecektir. KATEGORİZASYON tarafından uygulamanızın Uygulama Türü, Kategori ve İçerik derecelendirme gibi önemli bilgilerinide bu alanda giriyoruz. Burada Yeni İçerik Derecelendirmesi tabında derecelendirmeleri gerçekleştirmemiz gerekmektedir. Sol menüde İçerik Sınıflandırma tabına geçmemiz ve Yeni anket başlat butonuna tıklamamız gerekmektedir.


Bunları yaptıktan sonra sol menüden Fiyatlandırma ve Dağıtım butonuna tıklıyoruz. Yaptığınız uygulamanın ücretli veya ücretsiz olarak seçip yayınlamak istediğiniz ülkeleri seçmeniz gerekmektedir. Sonrasında İçerik Yönergeleri ve ABD ihracat Yasaları checkbox adlı yerleri tıkladıktan sonra Kaydet butonuna tıklıyorsunuz. Yaptığınız proje Google Play Storede yaklaşık 2-3 saatlik bir süreç içerisinde aşağıdaki şekilde yayında olacaktır. 


Sonuçta uygulamız uzun bir işlemden sonra yayına alınmıştır. Konuyla alakalı sorunlarınızı bizlerle paylaşırsanız yardımcı oluruz.]]>
Dailymotionun %80lik hissesi Vivendi tarafından satın alındı http://yazilimdersi.info/makaleler/detay/91/dailymotionun-80lik-hissesi-vivendi-tarafindan-satin-alindi- Sat, 04 Jul 2015 00:00:00 +0000 mstfchelikDailymotion'a ait %80'lik hisse 295 milyon Euro karşılığında Vivendi tarafından satın alındı. Vivendi SA müzik, televizyon, telekomünikasyon ve internet sektöründe faaliyet gösteren bir Fransız medya kuruluşudur. Bu satın alma sonrasında DailyMotion'un asıl sahibi olan Orange şirketinin %20 lik hisse kaldı. Youtube' un önemli bir pazar payına sahip olduğu sektörde Dailymotion satın alma sonrasında rekabeti kızıştıracak gibi.

]]>
Facebook Messenger kullanmak için Facebook hesabına gerek kalmadı. http://yazilimdersi.info/makaleler/detay/90/facebook-messenger-kullanmak-icin-facebook-hesabina-gerek-kalmadi Sun, 28 Jun 2015 00:00:00 +0000 mstfchelikFacebook bir çoğumuzun hayatında önemli bir yere sahip hale gelmiştir. Sosyal medyada en çok kullanılan Facebook'un aktif kullanıcı sayısı 1,25 milyarın üzerinde belirtilmektedir. Bu rakam birçok ülkenin nüfusundan fazla durumdadır. Facebook Androidde ve tabletlerde kullanıcıların mesajlaşmalarını yalnızca Messenger üzerinden yapabiliyor.Bu yüzden Messenger bir çok Facebook kullanıcısının aygıtında bulunmakta, fakat sadece Facebook'u olan kullanıcılar bu içerikten yararlanabiliyordu.Facebook kullanıcılarının arttırmak ve Facebook kullanmayanların Facebooktaki kişilerle mesajlaşmasını sağlamak için Facebook hesabı olmadan Facebook  Messanger kullanımını aktif hale getirdi. Artık sadece isminizi veya telefon numaranızı yazarak Facebook Messenger hesabına sahip olabilir ve sevdiklerinizle rahatlıkla iletişime geçebilirsiniz. Bu gelişme ile birlikte Facebook' un sosyal medyadaki gücü durdurulamaz bir hale gelmektedir. ]]> Cihazın IMEI numarasını öğrenmek http://yazilimdersi.info/makaleler/detay/89/cihazin-imei-numarasini-ogrenmek Sat, 27 Jun 2015 00:00:00 +0000 mstfchelik Her GSM telefon cihazına yüklenen unique bir koddur.Telefonunuzun çalınma durumunda veya kaybolma durumunda telefonunuzu bulmanız için size yardımcı olabilecek önemli bir numaradır. Cihazlar arasında yapılan tüm işlemler bu IMEI numarası üzerinden gerçekleştirilmektedir. Böylelikle kullanıcı telefonunu kaybetse bile IMEI numarasına GSM operatörleri üzerinden ulaşılabilinmektedir. Önemli olan durum ise cihazın GSM operatörü üzerinden haberleşebilir durumda olması gerekmektedir. Böylelikle çalınan veya kaybolan cihazınızın son konumu hakkında bilgiler cihaza ait operatörü güncel bir şekilde iletilecektir. Şimdi sizlere cihazınıza ait IMEI numarasına nasıl erişebileceğiniz ile alakalı birkaç yöntem sunacağız: 

METOD #1
En bilindik yöntemlerden birisi, cihazınızın arama sayfasına *#06# yazmanızdır. Bu işlemin ardından arama butonuna basmanızla birlikte, cihazınıza ait IMEI numarası aşağıda gösterilen şekilde ekranda görüntülenecektir:
 

METOD #2
Eğer telefonunuzun arka kapağı çıkarılabiliyorsa batarya kısmında cihazınıza ait IMEI numarasını görebilirsiniz. Aşağıda bu metod ile alakalı örnek bir resim bulunmaktadır:


METOD #3
Iphone cihazında IMEI numarasını bulmak için Ayarlar>Telefon Hakkında>Duruma sekmelerine tıklayın. Açılan pencerede aşağıdaki şekilde IMEI numarasını görebilirsiniz:


METOD #4
Telefonunuza giriş yaptığınız Gmail hesabına ait Google Dashboard sayfasına girin. Bu sayfada listelenen Android tabına tıklayın ve bu hesapla ilişkilendirilen bütün cihazlarınızın IMEI numaralarını görebileceksiniz. Aşağıdaki resimde örnek bir kaydın nasıl görüntülendiği gösterilmektedir:
 
 
 

Bu yöntemlerle IMEI numaranıza kolaylıkla erişebilirsiniz. Yukarıda anlatılan yöntemler dışında da birçok yöntem bulunmaktadır. Ancak o kısa ve hızlı şekilde IMEI numaralarına erişim bu metodlarla gerçekleştirilmektedir.

]]>
Voly, karşılaştığınız kişilere ait bilgileri tutan güzel bir arkadaşlık uygulamasıdır http://yazilimdersi.info/makaleler/detay/87/voly-karsilastiginiz-kisilere-ait-bilgileri-tutan-guzel-bir-arkadaslik-uygulamasidir Thu, 02 Apr 2015 00:00:00 +0000 mstfchelikGün içerisinde birçok farklı mekanda bulunmakta ve farklı kişileri görmekteyiz. Bazen bu kişilere baktığınızda yüzleri tanıdık gelmekte ve daha önceden bir yerde karşılaşıp karşılaşmadığınız hakkında kafa yorarsınız. Bazen de hayatın yoğunluğundan tanıdığınız kimseleri bile göremeden yanlarından geçmektesiniz. Voly oluşturduğu fikir ile birlikte kişilerin daha önceden karşılaştığı bilgileri tutmaktadır. Sloganı da bu doğrultuda olan Voly uygulaması kısa zamanda sosyal medyada büyük ses getirecek gibi görünüyor.

Uygulamanın kullanımı oldukça basit. Yapmanız gereken uygulamayı app storede Voly olarak aratıp bu linkten indirmenizdir. Sonrasında Facebook hesabınız ile uygulamaya giriş yapmanız gerekmektedir. Uygulamayı giriş yapmanız ile birlikte karşınıza etrafınızda bulunan Voly kullanıcılarının bilgileri getirilmektedir. Facebook arkadaşlarınızın Voly kullanıcısı olması durumunda direkt olarak sizi arkadaş olarak eklemesi güzel bir özellik olarak eklenmiş. Sonrasında etrafınızda bulunan kişilere ait profile tıklayıp onlarla daha önceden nerede karşılaştığınız hakkında bilgiler listelenmektedir. Nerede, ne zaman ve hava durumu hakkında detaylı bilgiler sunulmaktadır. Kullanıcılarla mesajlasmak isterseniz öncelikle winkleşmemniz gerekmektedir. Eğer her iki kullanıcı da birbirine wink gönderirse, mesajlaşma sayfası aktif hale gelecektir.

Aşağıda Voly uygulaması ile alakalı örnek ekran resimleri bulunmaktadır:
 
   

Şu an için sadece iOS uygulaması yayına alınan Voly, kısa bir süre sonra Android cihazlarda da yayına alınacaktır. Uygulama tamamen ücretsizdir. Kısa sürede popüler olacağı düşünülen uygulama şu anki Tinder, Tango vs. gibi uygulamalardan daha hızlı şekilde yayılacağı kanısındalar. Çünkü karşılaşılan kişiler sadece anlık olarak chatleşmiyor. Bu karşılaşmalar sistemde tutuluyor ve istenildiği zaman uygulamadan görüntülenebiliyor. Uygulamaya ait siteye http://voly.me linkinden ulaşabilirsiniz.
]]>
Javada final anahtar kelimesinin kullanımı http://yazilimdersi.info/makaleler/detay/86/javada-final-anahtar-kelimesinin-kullanimi Mon, 23 Mar 2015 00:00:00 +0000 mstfchelikJava programlama dilinde önemli bir yere sahip olan final anahtar kelimesi birçok projede farklı amaçlarla kullanmaktadırlar. Birçok yazılımcının kafasını karıştıran bu değişkenin ne amaçla ve nerelerde kullanılacağı hakkında bazı örneklerle bilgiler sunacağız. final anahtar kelimesi hem Java sınıflarında hem metodlarda hem parametrelerde hemde değişkenlerde kullanılabilmektedir. Makalemizde aşağıda bulunan maddeler sırasıyla anlatılacaktır:
  1. Değişken seviyesinde final kullanımı
  2. Metod seviyesinde final kullanımı
  3. Sınıf seviyesinde final kullanımı
1. Değişken seviyesinde final kullanımı:
Java'da sınıflar içerisinde bulunan değişkenler, oluşturulan her nesne için farklı alanda  tekrar tekrar oluşturulmaktadır. final anahtar kelimesini kullanılan değişkenler ilk değerlerinin setlenmesinin ardından tekrardan değiştirilemezler. final değişkenlerine değerler ya tanımlamanın gerçekleştirildiği esnada yada sınıfa ait initalize (yapıcı) metodu çağrıldığında setlenmelidir. Aksi takdirde uygulama hata verecektir. Aşağıdaki Urun sınıfımızda urunadi degiskenini final olarak setleyelim:
  1. package com.yazilimdersi.info.finalkullanimi; 
    
    public class Urun{ 
    
        #urunadi final değişken olarak setlendi.
        private final String urunadi;
        
        public void urunAdiYazdir() {
            System.out.println("urunadi : "+urunadi);
        }
    }
Yukarıda bulunan sınıfta urunAdiYazdir() metodundaki urunadi değişkenine herhangi bir atama yapılmadan kullanılmak istenildiğinden derleme sırasında The blank final field urunadi may not have been initialized şeklinde bir hata ile karşılaşacaksınızdır. Bu hata final olarak belirlenen urunadi değişkenini herhangi bir değer ataması yapmadığımızı belirtmektedir. Aşağıdaki kodlamada olduğu gibi metod içerisinde değer atamasını gerçekleştirelim:
  1. package com.yazilimdersi.info.finalkullanimi; 
    
    public class Urun{ 
    
        #urunadi final değişken olarak setlendi.
        private final String urunadi;
        
        public void urunAdiYazdir() {
            urunadi = "FLOWMETRE";
            System.out.println("urunadi : "+urunadi);
        }
    }
Yukarıdaki kodlamayı çalıştırdığımızda tekrar aynı hatayı alacaksınız muhtemelen. Bunun sebebi yazının başında belirttiğim üzere final değişkenlerine ait değer setlemeleri ya değişkenin tanımlandığı esnada yada sınıfa ait initialize (yapıcı) metod içerisinde gerçekleştirilmelidir. Aşağıdaki örnekte olduğu gibi direkt değişkenin tanımlandığı sırada gerçekleştirebiliriz:
  1. package com.yazilimdersi.info.finalkullanimi; 
    
    public class Urun{ 
    
        #urunadi final değişken olarak setlendi.
        private final String urunadi = "FLOWMETRE";
        
        public void urunAdiYazdir() {
            System.out.println("urunadi : "+urunadi);
        }
    }
Yukarıdaki kodlamayı derlediğimizde herhangi bir hata ile karşılaşmayacağınızı göreceksiniz. Ayrıca initialize metodu içerisinde de final değişkenine ait tanımlama şu şekilde gerçekleştirilebilir:
  1. package com.yazilimdersi.info.finalkullanimi; 
    
    public class Urun{ 
    
        #urunadi final değişken olarak setlendi.
        private final String urunadi;
        
        public Urun(String urunAdiDegiskeni) {
            urunadi = urunAdiDegiskeni;
        }
        
        public void urunAdiYazdir() {
            System.out.println("urunadi : "+urunadi);
        }
    }
Yukarıdaki kodlamayı derlediğimizde herhangi bir hata ile karşılaşmayacağınızı göreceksiniz.

Final değişkenlerinin en önemli özelliği herhangi bir değer setlendikten sonra, tekrar değer setlenememesidir. Yani initialize metodu içerisinde veya değişken tanımlanmasında setlenen değişken, başka bir metod içerisinde tekradan setlenemez.
Final değişkeninin kullanımının asıl amacı zaten setlediğimiz herhangi bir değerin tekrar değiştirilmesini istememizden dolayıdır.  
  1. package com.yazilimdersi.info.finalkullanimi; 
    
    public class Urun{ 
    
        #urunadi final değişken olarak setlendi.
        private final String urunadi;
        
        public Urun(String urunAdiDegiskeni) {
            urunadi = urunAdiDegiskeni;
        }
        
        public void urunAdiYazdir() {
            urunadi = "FLOWMETRE";
            System.out.println("urunadi : "+urunadi);
        }
    }
Yukarıdaki kodlamayı derlediğimizde şu şekilde bir hata ile karşılaşacaksınız. The final field Urun.urunadi cannot be assigned
Çoğu programda final değişkeni static anahtar kelimesiyle birlikte kullanılmaktadır. Bunlar constant olarak ifadelendirilmektedir ve bu degiskenler genellikle her sınıftan erisilebilecek degiskenler olarak kabul edilirler:
  1. package com.yazilimdersi.info.finalkullanimi; 
    
    public class Constant{ 
    
        public static final String MYSQL_HOST = "128.93.09.12";
        public static final String MYSQL_USER = "mysql_user";
        public static final String MYSQL_PASS = "password";
    
    }
 
2. Method seviyesinde final kullanımı:
Java'da sınıflar içerisinde bulunan methodlarda final anahtar kelimesi kullanılarak oluşturulabilmektedir. Ancak final tanımlı olan method hiçbir şekilde başka sınıf tarafından miras alınsa bile override edilemez. Aşağıda bulunan kodlamayı örnek verecek olursak:
  1. package com.yazilimdersi.info.statickullanimi; 
    
    public class Urun{ 
        
        #urunsayisi Sınıf değişkeni. Program çalışır çalışmaz bellekte yer oluşturulur.
        public static int urunsayisi = 0;
    
        public final int urunsayisiGetir() {
            return urunsayisi;
        } 
    
    }
    
    public class Arac extends Urun { 
        
        public int urunsayisiGetir(){
            System.out.println("urunsayisi getir");
        }
    
    }
Yukarıda bulunan kodlamada Arac sınıfı, Urun sınıfını miras almaktadır. Urun sınıf içerisinde bulunan urunsayisiGetir() metodu final olarak ayarlanmıştır. Ancak dikkat ederseniz aynı isimde bir metod Arac sınıfı içerisinde de tanımlanmış ve override edilmiştir. Bu da Cannot override the final method from urunsayisiGetir şekilde bir hataya sebep olacaktır. Bu tip hatalarla karşılaşmamak için alt sınıflarda miras alınan sınıflardaki final metodları override edilmemelidir. 

3. Sınıf seviyesinde final kullanımı:
Final değişkeni sınıf seviyesinde de kullanılmaktadır. Ancak final olarak hazırlanan sınıflar başka sınıflar tarafından kesinlikle miras alınamazlar. Bir sınıfın zaten hiçbir şekilde başka sınıf tarafından miras alınmasını istemiyorsak bu yapıyı kullanırız. Aşağıda bulunan kodlamayı inceleyelim:
  1. package com.yazilimdersi.info.statickullanimi; 
    
    public final class Urun { 
        
        #urunsayisi Sınıf değişkeni. Program çalışır çalışmaz bellekte yer oluşturulur.
        public static int urunsayisi = 0;
    
        public int urunsayisiGetir() {
            return urunsayisi;
        } 
    
    }
    
    public class Arac extends Urun { 
        
        public int urunsayisiGetir(){
            System.out.println("urunsayisi getir");
        }
    
    }
Yukarıda bulunan kodlamada Arac sınıfı, Urun sınıfını miras almaktadır. Ancak Urun  sınıfı final olarak belirlendiğinden The type Arac cannot subclass the final class Urun şekilde bir hata ile karşılaşacaksınız.

]]>
Javada this anahtar kelimesinin kullanımı http://yazilimdersi.info/makaleler/detay/85/javada-this-anahtar-kelimesinin-kullanimi Sun, 22 Mar 2015 00:00:00 +0000 mstfchelikthis dir. Birçok yazılımcının kafasını karıştıran bu değişkenin ne amaçla ve nerelerde kullanılacağı hakkında bazı örneklerle bilgiler sunacağız. Çok fazla kullanım alanına sahip olmamasına rağmen akıllardaki soru işaretlerini gidermek amacıyla da bu makalemizi hazırlamış bulunuyoruz. Aslında this anahtar kelimesi üzerinde işlem yapılan nesnenin kendisini dönmektedir. Örnek verecek olursak bir sınıfta tanımlanan nesne değişkenlerine fonksiyonlar içerisinden erişimde kullanılabilinmektedir.

Çoğunlukla bir metodda tanımlanan aynı isme sahip değişken ile nesne değişkenini ayırt etmekte kullanılmaktadır. Örnek verecek olursak;
  1. package com.yazilimdersi.info.thiskullanimi; 
    
    public class Urun{ 
    
        private String urunadi;
        private String marka;
        private String model;
    
        public Urun(String urunadi, String marka, String model) { 
            this.urunadi= urunadi; 
            this.marka = marka; 
            this.model = model;
        } 
    }
Yukarıda bulunan Urun sınıfına bağlı urunadi, marka ve model nesne değişkenleri bulunmaktadır. Bu değişkenlere ait verileri setlemek amacıyla initialize (yapıcı) metodunda da parametreler aynı isimle girilmiş. Burada setleme yapıldığında gelen parametrik değerin nesneye atanması için this kullanımı gerekmektedir. this anahtar kelimesi bizlere Urun sınıfına ait urunadi, marka ve model değişkenlerine erişimimizi sağlamaktadır. Eğer initialize (yapıcı) metodundaki parametreler farklı şekilde adlandırılsaydı, this kullanımına ihtiyaç olmayacaktı! Ama programın okunurluğu ve yapısı açısından this kullanımı kabul gören bir kullanım türüdür bu tip durumlarda. Yani eğer parametreler aşağıdaki şekilde nesne değişkenlerinden farklı isimlendirilseydi this kullanımına gerek kalmayacaktı aşağıdaki örnekte olduğu gibi:
  1. package com.yazilimdersi.info.thiskullanimi; 
    
    public class Urun{ 
    
        private String urunadi;
        private String marka;
        private String model;
    
        public Urun(String urunadiDegiskeni, String markaDegiskeni, String modelDegiskeni) { 
            urunadi= urunadiDegiskeni; 
            marka = markaDegiskeni; 
            model = modelDegiskeni;
        } 
    }
Diğer bir kullanım türü de direkt olarak metodların this anahtar kelimesi ile çağrılmasıdır. Aşağıdaki kodlama da this metodu kullanılarak hazırlanmış bir initialize metodu tetiklenebilmektedir:
  1. package com.yazilimdersi.info.thiskullanimi; 
    
    public class Urun{ 
    
        private String urunadi;
        private String marka;
        private String model;
        
        public Urun(String urunAdi) { 
            this(urunAdi, "FLOWMETRE", "FL 256");
        }
    
        public Urun(String urunadi, String marka, String model) { 
            this.urunadi= urunadi; 
            this.marka = marka; 
            this.model = model;
        } 
    
    }
Yukarıdaki kullanımda görüldüğü üzere tek parametre alan Urun initialize metodu 3 parametre alan diğer bir initialize metodunu direkt olarak this ifadesi ile çağırabilmektedir. Yaygın olarak kullanılan sadece bu tip durumlardır. 

Önemli bir konu da this anahtar kelimesini static metodlar içerisinde kullanamayız. Çünkü this kelimesi sınıfa ait nesnelerin oluşturulmasıyla bellekte yer tutmaktadır. 

]]>
Node.js ile basit bir sayfa hazırlanması http://yazilimdersi.info/makaleler/detay/84/nodejs-ile-basit-bir-sayfa-hazirlanmasi Thu, 19 Mar 2015 00:00:00 +0000 mstfchelikUbuntu da Node.js kurulumu başlıklı makalemizden okuyabilirsiniz. Şimdi adım adım basit bir websayfasının nasıl oluşturulduğunu inceleyelim.

1. Dosya oluşturulması: 
Öncelikle nodejs programının çalıştırılacağı app.js isimli dosyamızı oluşturalım. Bu dosya ismi opsiyoneldir. Yani dosya ismini istediğiniz şekilde değiştirebilirsiniz ancak dosya uzantısı .js olmalıdır.
sudo touch app.js

2. Webserver oluşturulması: 
Websitesi oluşturacağımızdan dolayı webservere ihtiyaç duymaktayız. Node.js tabanlı uygulamaların çoğunda http modülüne rastlayabilirsiniz. Websiteleri servera ihtiyaç duyduklarından bu modül önemli bir yer tutmaktadır. Aşağıda bulunan komutla app.js isminde oluşturduğumuz dosyaya erişip http modulunü tanımlayalım. Sonrasında tanımlanan http serveri 1111 portu üzerinden dinleyecek şekilde ayarlayalım.
#app.js dosyasının içerisine girildi.
vi app.js

#http modülü oluşturuldu.
var http = require("http");

http.createServer(function(req, res){ }).listen(, '127.0.0.1');
Yukarıdaki komutla birlikte 1111 portundan 127.0.0.1 üzerinde çalışan bir webserver oluşturulmuş oldu. Şu an gelen istekler bu port üzerinden dinlenmektedir. Sırada gelen isteklere cevapların nasıl iletileceği ile alakalı kodlamayı gerçekleştirelim.

3. Dönecek response tipinin belirlenmesi: 
http modülünden bulunan function değişkenleri kullanarak iletilen request ve responseler ile alakalı çalışmalarımızı gerçekleştirebiliriz. Burada req ve res olarak adlandırılan parametreler aslında request(istek) ve response(cevap) anlamına gelmektedir. Dönecek response tipini belirlemede res.writeHead() metodu kullanılmaktadır. Sunucuya yapılan istekler sonucunda geri dönecek olan içeriklerin tipinin nasıl olması gerektiğini aşağıda bulunan komutlarla function metodu içerisinde gerçekleştirebiliriz:
res.writeHead(200, {'Content-Type': 'text/html'});
Eğer herhangi bir api hazırlıyorsanız nodejs kullanarak, Content-Type verisini application/json olarak girmeniz gerekecektir. Biz basit bir websitesi oluşturmak istediğimizden dolayı text/html olarak içerik tipini belirledik.

4. Response olarak basit bilgilerin yazılması: 
Şimdi sırada response olarak dönmesini istediğimiz içeriğin girilmesini gerçekleştirelim. Burada res.write() metodu kullanılmaktadır:
res.write('<!doctype html>\n<html lang="en">\n' + 
          '\n<meta charset="utf-8">\n<title>Node.js ile basit bir sayfa</title>\n' + 
          '<style type="text/css">* {font-family:arial, sans-serif;}</style>\n' + 
          '\n\n<h1>En popüler programlama dilleri</h1>\n' + 
          '<div id="content"><p>Son 3 yıla ait en popüler programlama dilleri:</p>\n'+
          '<ul><li>Java</li><li>C#</li><li>Ruby</li><li>Nodejs</li></ul></div>' + 
          '\n\n');
Daha sonrasında http servere ait response verisinin döndüğünü belirtmek için res.end() metodunu çağırırız. Böylelikle websitesi içeriğine gelmesi gereken verilerin geldiğini ve sunucudan daha fazla talepte bulunamayacağımızı anlamış oluruz.
res.end()
5. Sitenin çalıştırılması : 
Tüm kodlamalar gerçekleştirildi. Eklenen kodlamalar sonucunda oluşması gereken kod parçacığı tam olarak şu şekilde olmalıdır:
var http = require('http'); 

http.createServer(function(req, res) { 

    res.writeHead(200, { 'Content-Type': 'text/html' }); 
    
    res.write('<!doctype html>\n<html lang="en">\n' + 
              '\n<meta charset="utf-8">\n<title>Node.js ile basit bir sayfa</title>\n' + 
              '<style type="text/css">* {font-family:arial, sans-serif;}</style>\n' + 
              '\n\n<h1>En popüler programlama dilleri</h1>\n' + 
              '<div id="content"><p>Son 3 yıla ait en popüler programlama dilleri</p>\n' + 
              '<ul><li>Java</li><li>C#</li><li>Ruby</li><li>Nodejs</li></ul></div>' + 
              '\n\n'); res.end(); 
         
}).listen(1111, '127.0.0.1');
Aşağıdaki komutla nodejs uygulamamızı çalıştıralım.
node app.js
Çalıştırılan komutla birlikte browserimizde http://127.0.0.1:1111 linkine erişim yaptığımızda aşağıdaki şekilde bir sayfa ile karşılaşmamız gerekmektedir.

]]>
Lovebook, aşk hayatınızı facebook reklamlarına dönüştürüyor http://yazilimdersi.info/makaleler/detay/83/lovebook-ask-hayatinizi-facebook-reklamlarina-donusturuyor Sat, 21 Mar 2015 00:00:00 +0000 mstfchelik
Bu slogan ile yolan çıkan Lovebook takımı, Facebook üzerindeki yüksek kullanıcı potansiyelinden yola çıkarak aşk hayatınızı canlandırmayı planlamaktadır. Partner bulma konusunda yapılan bir çok farklı girişimde olumlu sonuçlar alamayan kullanıcılar için Lovebook biçilmiş bir kaftan gibi. Yapmanız gereken LoveBook sitesine giriş yapmak ve yayımlanacak reklam seçeneklerinden birisini belirlemek. Sonrasında reklam olarak verilecek içeriklerin girilmesini sağlamaktadır. 

Lovebook üzerinde yayımlanacak reklam seçenekleri 3 adettir: FirstDate, Lovebug ve Casanova. Bu seçenekler aylık olarak 15$ ile 60$ arasında fiyatlandırılmıştır. Fiyatlara bağlı olarak profil reklamınıza erişecek kişilerin sayısı da belirlenmektedir. Lovebug ve Casanova seçeneklerinde bazı özel fırsatlar ve kurucusu olan James'den öneriler sunulmaktadır.


Reklam seçeneğinizi belirledikten ve Paypal ile ödeme gerçekleştirdikten sonra, Lovebook size ait bir Facebook sayfası oluşturuyor. Bu sayfaya profilinizden 3 adet resim ekleyip, sizinle alakalı ve aradığınız partner ile alakalı kısa bilgiler sunuyor. Sonrasında sizin profilinize uygun olan kullanıcılara erişim için Facebook üzerinden reklam yayımlıyor. Lovebook kurucus olan James'e göre bu tarz yapılan partner aramaları daha olumlu ve hedef odaklı sonuçları getirmektedir. Diğer önemli bir partner bulma uygulaması olan Match.com sitesinden çok daha uygun fiyatta ve uygun kriterlerde sonuç alındığını belirtmektedir. Tinder üzerinden yapılan partner aramalara göre daha hızlı sonuç alındığını da belirtmektedir.
]]>
Artık Facebook Messanger üzerinden para gönderilebilecek http://yazilimdersi.info/makaleler/detay/82/artik-facebook-messanger-uzerinden-para-gonderilebilecek Sat, 21 Mar 2015 00:00:00 +0000 mstfchelik Bir zamanlar sadece sohbet uygulaması olarak kullanılan Facebook Messenger, yeni özelliği ile birlikte kullanıcıların birbirlerine rahatlıkla para gönderimi yapmasını sağlamaktadır. Şimdilk sadece Amerika'da yayına alınacak olan özellik daha sonradan tüm dünyada aktif hale getirilecektir. Messenger uygulamasında sohbet sayfalarının altında bulunan tablara $ işareti eklenerek özelliğe erişilecektir. Bu ikona tıklanıldıgında gönderilecek ücretin miktarını girebileceğimiz bir sayfa açılacaktır. Bu alana gönderilecek miktarı girmemizle birlikte Pay butonuna tıkladıktan sonra gerekli kart bilgileri giriliyor ve gönderim işlemi tamamlanıyor. Aşağıda bulunan resimde gelecek özellikle alakalı ekran resimleri bulunmaktadır:

Amerikada yayınlacak olan özellikte sadece Visa ve MasterCard olarak bilinen popüler kartlarda gönderim gerçekleştirilecektir. Şu an için herhangi bir gönderim ücreti alınmayacağı gözlemlenmektedir. Ancak ilerde nasıl bir ücrete tabi tutulacağı hakkında bilgi verilmemektedir. Ayrıca özelliğin tüm dünyada aktif hale getirileceği tarih belirtilmemiştir. Özellikle alakalı hazırlanan videoyu aşağıdan izleyebilirsiniz:



]]>
Javada static anahtar kelimesinin kullanımı http://yazilimdersi.info/makaleler/detay/79/javada-static-anahtar-kelimesinin-kullanimi Sat, 21 Mar 2015 00:00:00 +0000 mstfchelikMakalemizde aşağıda bulunan maddeler sırasıyla anlatılacaktır:
  1. Sınıf seviyesinde static kullanımı
  2. Metod seviyesinde static kullanımı
  3. Import edilen kütüphane seviyesinde static kullanımı
  4. Static kullanımlar ne zaman gerçekleştirilmeli?
1. Sınıf seviyesinde static kullanımı:
Java'da sınıflar içerisinde bulunan değişkenler, oluşturulan her nesne için farklı alanda  tekrar tekrar oluşturulmaktadır. Örneğin ürün adı, markası, modeli ve ücreti gibi 4 farklı değişkeni bulunan bir sınıfta, bu sınıfla alakalı oluşturulan her nesne  için bellekte farklı alanlarda ürün adı, markası, modeli ve ücreti bilgileri tutulmaktadır. Bu nesnelere atanan değerler tamamen birbirinden bağımsızdır. Bundan dolayı bu değişkenler nesne değişkeni olarak tanımlanmaktadır. Ancak bazı uygulamalarmızda sınıflarda kullanılan değişkenlerin ortak bir yerden veri çekmesini sağlamamız gerekmektedir. Örneğin ürünlerin girildiği bir sınıfta toplam ürün miktarının bu sınıfa ait bir değişken ile sayılması istenildiğinde static anahtar kelimesinden yararlanmamız gerekmektedir. static anahtar değişkeni daha sınıfla alakalı herhangi bir nesne oluşturulmadan bellekte bir alan kaplamaktadır. Sınıftaki değişkeni ortak bir alana yazma yapmasından dolayı bu değişkenler sınıf değişkeni olarak ifadelendirilmektedir. Yani yazılımcı istediği kadar bu sınıfa bağlı nesne oluştursun. static olarak ifadelendirilen değişkenler sadece bir kere bellekte oluşturulmaktadır ve her oluşturulan nesne bu değişkene ait ortak belleği kullanmaktadır. Aşağıda oluşturulan örnekte bu durumu daha açıklayıcı şekilde ifadelendirelim:
  1. package com.yazilimdersi.info.statickullanimi; 
    
    public class Urun{ 
    
        private String urunadi;
        private String marka;
        private String model;
        private int fiyat;
        
        #urunsayisi Sınıf değişkeni. Program çalışır çalışmaz bellekte yer oluşturulur.
        public static int urunsayisi = 0;
    
        public Urun(String urunadi, String marka, String model, int fiyat) { 
            this.urunadi= urunadi; 
            this.marka = marka; 
            this.model = model;
            this.fiyat = fiyat;
    
            #Urun sınıfına ait her nesne oluşturulduğunda urunsayisini bir artıralım. 
            urunsayisi++; 
        } 
    }
Yukarıda bulunan sınıfta 4 adet nesne değişkeni ve 1 adet sınıf değişkeni bulunmaktadır. urunadi, marka,model ve fiyat değişkenleri nesne, urunsayisi değişkeni ise sınıf değişkeni olarak belirlenmiştir. Şimdi aşağıda bulunan StaticOrnekProgram sınıfı içerisinde Urun sınıfına ait nesneler oluşturalım ve urunsayisinin sonuclarını ekrana basalım.
  1. package com.yazilimdersi.info.statickullanimi; 
    
    public class StaticOrnekProgram { 
         
        public static void main(String args[]) { 
    
            System.out.println("ürün sayısı: " + Urun.urunsayisi); 
    
            #üc tane urun nesnesi olusturalım. 
            Urun urun1 = new Urun("Pals Oximeter", "Erne", "UT 100", 1200); 
            Urun urun2 = new Urun("Ateşölçer", "Thermoflash", "LX-26", 1000); 
            Urun urun3 = new Urun("FLOWMETRE", "Özen", "Perfect Aneroid", 240); 
    
            int urunsayisi = Urun.urunsayisi;
            System.out.println("Nesnelerden sonra ürün sayısı: " + urunsayisi); 
    
            urunsayisi1 = urun1.urunsayisi; 
            System.out.println("İlk nesnede ürün sayısı: " + urunsayisi1); 
    
            urunsayisi2 = urun2.urunsayisi; 
            System.out.println("İkinci nesnede ürün sayısı: " + urunsayisi2); 
    
            urunsayisi3 = urun3.urunsayisi; 
            System.out.println("Üçüncü nesnede ürün sayısı: " + urunsayisi3);
     
        } 
    }
StaticOrnekProgram sınıfı çalıştırıldığında oluşacak olan ekran çıktıları şu şekilde olacaktır:
  1. ürün sayısı: 0 
    Nesnelerden sonra ürün sayısı: 3 
    İlk nesnede ürün sayısı: 3 
    İkinci nesnede ürün sayısı: 3
    Üçüncü nesnede ürün sayısı: 3
Ekran çıktısında gördüğünüz üzere nesneler oluşturulduktan sonra setlenen ürün sayısı bilgisi static değişkene bağlı olduğundan her zaman aynı sonucu dönmektedir. Farklı nesneler içinde her zaman 3 rakamını dönmüştür. Ayrıca kodlamada da gördüğünüz üzere bu değişkenlere sınıflar aracılığıyla erişelebilindiği gibi, nesneler aracılığıyla da erişilebilmektedir. Dikkat ederseniz yapıcı(constructor) metodu içerisinde yapılan urunsayisina ait +1 artırımı her oluşturulan nesne ile birlikte gerçekleştirilmektedir. Daha önceden belirtiğim gibi bu değişkenler program başlatıldığında bellekte oluşturulmaktadır ve erişimler hep aynı bellek alanındaki değere gerçekleştirilmektedir.

2. Method seviyesinde static kullanımı:
Java'da sınıflar içerisinde bulunan methodlarda static anahtar kelimesi kullanılarak oluşturulabilmektedir. Normalde herhangi bir sınıfa bağlı metoda erişmek istiyorsanız, öncelikle bu sınıfa bağlı nesneyi oluşturmanız gerekmektedir. Ancak static tanımlı olan methodlarda nesne oluşumuna ihtiyaç duyulmaksızın erişim gerçekleştirilmektedir. Örneğin yukarıda oluşturduğumuz Urun sınıfındaki urunsayisi değişkenine bir metod ile erişmek istersek, bunu aşağıdaki kodlama ile gerçekleştirebiliriz:
  1. package com.yazilimdersi.info.statickullanimi; 
    
    public class Urun{ 
    
        private String urunadi;
        private String marka;
        private String model;
        private int fiyat;
        
        #urunsayisi Sınıf değişkeni. Program çalışır çalışmaz bellekte yer oluşturulur.
        public static int urunsayisi = 0;
    
        public Urun(String urunadi, String marka, String model, int fiyat) { 
            this.urunadi= urunadi; 
            this.marka = marka; 
            this.model = model;
            this.fiyat = fiyat;
    
            #Urun sınıfına ait her nesne oluşturulduğunda urunsayisini bir artıralım. 
            urunsayisi++; 
        }
    
        public static int urunsayisiGetir() {
            return urunsayisi;
        } 
    
    }
Yukarıda bulunan kodlamada urunsayisiGetir() metodu ile normalde Urun.urunsayisi şeklindeki yaptığımız erişimin yerine bu metodu kullanabiliriz. Yapılan çağrı sonucunda dönecek değer aynıdır ancak değişkenlere direkt değilde, methodlar üzerinden erişim daha anlaşılır kabul edilmektedir. Örnek verecek olursak yukarıda kullandığımız StaticOrnekProgramı şu şekilde yazabiliriz artık:
  1. package com.yazilimdersi.info.statickullanimi; 
    
    public class StaticOrnekProgram { 
         
        public static void main(String args[]) { 
    
            System.out.println("ürün sayısı: " + Urun.urunsayisi); 
    
            #üc tane urun nesnesi olusturalım. 
            Urun urun1 = new Urun("Pals Oximeter", "Erne", "UT 100", 1200); 
            Urun urun2 = new Urun("Ateşölçer", "Thermoflash", "LX-26", 1000); 
            Urun urun3 = new Urun("FLOWMETRE", "Özen", "Perfect Aneroid", 240); 
    
            int urunsayisi = Urun.urunsayisiGetir();
            System.out.println("Nesnelerden sonra ürün sayısı: " + urunsayisi); 
     
        } 
    }
Method üzerinden yapılan çağrıda oluşacak çıktı aynı olacaktır :
  1. ürün sayısı: 0 
    Nesnelerden sonra ürün sayısı: 3 
    
Daha öncede belirtiğimiz gibi direkt Urun sınıfına ait urunsayisi değişkenine erişebiliyoruz herhangi bir nesne tanımlanmadan. Ancak kod okunurluğu açısından pek tavsiye edilmediğinden bu işlemi metodlar üzerinden gerçekleştiriyoruz. 

Burada en önemli üzerinde durulması gereken nokta, static metodu içerisinde sadece static değişkenlerine erişim bulunmaktadır. Yani urunsayisi yerine urunadi değişkenini bu metod içerisine yazsaydım uygulama hata verecekti. Static methodlar içerisindeki değişkenler nesne değişkeni olamazlar. Onlar da static anahtar kelimesini kullanan değişkenler olmak zırundadır. Aynı şekilde static method içerisinde nesne metodu çağrılamaz. Bunun açıklamasını şu şekilde gerçekleştirebiliriz: Static metod ve değişken dışındaki nesne değişkenleri program çalıştığı esnada yapılan çağrılarla oluşturulduğundan bunlar sonradan bellekte yer kaplamaktadır. Halbuki static değişkene sahip metodlar daha program çalıştırılır çalıştırılmaz direkt olarak bellekte yer oluşturduğundan metod içerisindeki değişkenlerinde de daha önceden bellekte yer alması gerekmektedir. Bu nedenle bunlarında static olarak tanımlanmış sınıf değişkenleri olması zorunludur.
 
3. Import edilen kütüphane seviyesinde static kullanımı:
Static methodların sınıf adı ile çağrıldığını üstteki maddede detaylı olarak açıkladık. Örnek verecek olursak javada math clasını direkt olarak static biçimde kodumuza import edebilmekteyiz. Bunun sebebi Math classın içerisinde bulunan tüm metodların static olarak tanımlanmasındadır. Math sınıfı içerisinde bulunan metodlara Math.cagrilacakMetodAdi() fonksiyonu ile erişebiliriz. Ayrıca kodumuza direkt olarak Math sınıfını static import olarak ekleyerek Math sınıfını yazmamıza gerek kalmadan direkt metod ismi ile erişim sağlayabiliriz. Aşağıdaki kodlamada Math sınıfı kodumuza static olarak import edilmiştir:
  1. package com.yazilimdersi.info.statickullanimi; 
    
    import static java.lang.Math.*; 
    
    public class OrnekProgram { 
    
        public static void main(String args[]) { 
        
            System.out.println("Cosinus 90: " + cos(90)); 
            System.out.println("Pi sayısı: " + PI); 
        } 
    }
Yukarıda bulunan kodlamada Math.cos() metodu yerine direkt cos() şeklinde bir çağrım gerçekleştirdik. Bunun sebebi de import static olarak kodumuza eklediğimiz java.lang.Math sınıfıdır.

4. Static kullanımlar ne zaman gerçekleştirilmeli?
Static anahtar kelimesine bağlı değişkenler ortak bellekten okuma yapmak istediğimiz durumlarda kullanılmalıdır. Örnekte belirtiğimiz üzere ürünlerin tutulduğu bir programda oluşturulan her ürünle alakalı farklı nesneler kullanılmalıdır. Çünkü her nesneye bağlı ürün adı, markası, model ve fiyatı farklı olabilir ancak depoda bulunan toplam ürün sayısı aynıdır. Toplam ürün sayısını aynı sınıf içerisinde bulunan bir değişken ile tutmak istiyorsak, static metodunu kullanmamız yeterli olacaktır. Böylelikle bu değişkene her erişimde farklı nesneler tanımlanmış olsa bile ortak bellek havuzundan veri okuduğu için değerler her zaman aynı olacaktır. 
]]>
Ubuntuda Node.js Kurulumu http://yazilimdersi.info/makaleler/detay/78/ubuntuda-nodejs-kurulumu Tue, 17 Mar 2015 00:00:00 +0000 mstfchelikNode.js, network bağımlı uygulamalarımızı daha hızlı şekilde oluşturabilmemiz için hazırlanmış server taraflı bir Javascript platformudur. Node.js sayesinde sisteme bağlı back-end ve front-end uygulamalar hızlı şekilde oluşturulabilmektedir. Performans testlerinde birçok programlama dilini geçtiği gözlemlenmiştir. Daha çok karmaşık sistemli olan projelerde tercih edilen Node.js, yazılımcı açısından öğrenilmesi pekde zor olmayan bir dildir. Şimdi sırasıyla Node.js platformunun Ubuntu kurulu makinanıza nasıl yüklenebileceği hakkında açıklamalara başlayalım. Farklı yöntemlerle kurulum işlemi gerçekleştirilebilmektedir:

1.a apt üzerinden stable versiyonun kurulumu:
Ubuntu default repositorilerinde stabil çalışan Node.js programına ait farklı versiyonda yazılımlar bulunmaktadır. Bu platformlar son versiyonda olmayabilirler, ancak stabil olarak Ubuntu sunucularda çalışabilmektedirler. Repositorilerden stabil versiyonu indirmek için apt komutu kullanılmaktadır. Aşağıda bulunan komutlarla ilk olarak repositorilerdeki paket programlar güncellenmektedir. Sonrasında ise node.js kurulumu gerçekleştirilmektedir:
sudo apt-get update 
sudo apt-get install nodejs
Node.js kurulumunun ardından npm olarak adlandırılan Node.js Package Manager programının indirilmesi gerekmektedir. Aslında bu zorunluluk değildir. Ancak nodejs için yazılmış farklı modulleri ve paketleri indirmek istediğimizde bu komutu kullanarak hızlı şekilde implementasyonları gerçekleştirebiliriz. Aşağıda bulunan komutla birlikte npm programı da yüklenmektedir:
sudo apt-get install npm
Böylelikle Node.js ve ona bağlı olan npm programlarının kurulumlarını gerçekleştirmiş olduk. Şimdi diğer yöntemlerle kurulum işlemlerinin nasıl gerçekleştirilebileceğini de inceleyelim.

1.b. PPA ile kurulumun gerçekleştirilmesi: 
Yukarıda anlatılan apt ile kurulumda repositorydeki stable versiyonlu olan program indirilmektedir. Ancak en son versiyona ait indirme işlemini stabil olmadığı durumlarda sağlamamaktadır. Bu maddede PPA yani Personal Package Archive komutunu çalıştırarak node.js programının son versiyonun listelendiği linki sisteme ekleyebilirsiniz. Sonrasında apt komutu ile son versiyona ait linki sisteme eklenen nodejs ile alakalı kurulumu gerçekleştirebilirsiniz:
curl -sL https://deb.nodesource.com/setup | sudo bash -
Yukarıdaki komutla birlikte Node.js programına ait son versiyon linki local packagelerimize eklenmiştir. Bundan sonrasında apt-get install komutu ile güncel versiyonun indirilmesini sağlayabiliriz:
sudo apt-get install nodejs
PPA dan eklenen nodejs sürümünde npm de içerildiğinden bundan ayrı olarak tekrar npm indirilmesine gerek kalmamaktadır. Ancak buna rağmen bazı npm paketlerini kullanmak isteyebileceğinizden build essential indirmeniz iyi olacaktır: 
sudo apt-get install build-essential

]]>
Android de http isteğinde bulunmak http://yazilimdersi.info/makaleler/detay/76/android-de-http-isteginde-bulunmak Wed, 04 Mar 2015 00:00:00 +0000 mstfchelikGET veya POST olarak gerçekleştirilebilmektedir. POST olması durumunda parametrelerin setlenmesi önemli bir konu olarak karşımıza çıkmaktadır. Şimdi http isteğinin nasıl gerçekleştirildiği ile alakalı kodlamayı inceleyelim.

1. HttpClient ve HttpPost oluşturulması : 
Aşağıdaki kodlamada uygulamamıza ait http clienti ve http post isteği oluşturulmaktadır. Örnek link olarak http://yazilimdersi.info/urunlerlistesi kullandım. Bunu kendinize ait herhangi bir link ile değiştirebilirsiniz:
# http clienti oluşturuldu.
HttpClient httpClient = new DefaultHttpClient();
 
# http post oluşturuldu.
HttpPost httpPost = new HttpPost("http://yazilimdersi.info/urunlerlistesi");
2. Post parametrelerinin hazırlanması : 
Aşağıdaki kodlamada örnek verilen linke erişim esnasında gönderilecek parametrelerin setlenmesi sağlanmaktadır:
# ulke ve sehir parametreleri setlenmektedir.
List<NameValuePair> ulkeSehirParametreleri = new ArrayList<NameValuePair>(2); 
ulkeSehirParametreleri.add(new BasicNameValuePair("ulke", "Turkiye")); 
ulkeSehirParametreleri.add(new BasicNameValuePair("sehir", "Ankara"));
3. Post edilecek verilerin urlencode edilmesi : 
Aşağıdaki kodlamada post verisi olarak hazırlanan parametrelerin nasıl urlencode edildiği gösterilmektedir. Burada UrlEncodedFormEntity metodu kullanılmaktadır:
# post parametrelerinin urlencode edilmesi 
try { 
    httpPost.setEntity(new UrlEncodedFormEntity(ulkeSehirParametreleri)); 
    } catch (UnsupportedEncodingException e) { 
    # hataların loglara yazılması
    e.printStackTrace(); 
}
4. Http isteğinin yapılması : 
Son olarak http isteğinin gerçekleştirilmesine geldi sıra. Burada da execute() metodu önemli bir işlem göstermektedir:
# http isteğinin yapılması 
try { 
    HttpResponse response = httpClient.execute(httpPost); 

    # dönen sonuçların görüntülenmesi
    Log.d("Http Response:", response.toString()); 
} catch (ClientProtocolException e) { 
    # hataların loglara yazılması 
    e.printStackTrace(); 
} catch (IOException e) { 
    # hataların loglara yazılması 
    e.printStackTrace(); 
}
Yukarıda yazılan kodlama ile birlikte http isteği gerçekleştirilmiştir. Aşağıda bu kodların tümünün görüntülendiği sınıfa ait kodlama bulunmaktadır:
package com.androidhive.httprequests; 

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.util.ArrayList; 
import java.util.List; 
import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 
import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 

public class AndroidHTTPIstegiActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
  
        # http isteği oluşturuldu. 
        HttpClient httpClient = new DefaultHttpClient(); 
        # http post isteği oluşturuldu. 
        HttpPost httpPost = new HttpPost("http://yazilimdersi.info/urunlerlistesi"); 
        # parametrelerin setlenmesi
        List<NameValuePair> ulkeSehirParametreleri = new ArrayList<NameValuePair>(2); 
        ulkeSehirParametreleri.add(new BasicNameValuePair("ulke", "Turkiye")); 
        ulkeSehirParametreleri.add(new BasicNameValuePair("sehir", "Ankara")); 
        # post parametrelerinin urlencode edilmesi
        try { 
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair)); 
        } catch (UnsupportedEncodingException e) { 
            # hataların loglara yazılması
            e.printStackTrace(); 
        } 
 
        # http isteğinin gerçekleştirilmesi
        try { 
            HttpResponse response = httpClient.execute(httpPost); 
            # hataların loglara yazılması
            Log.d("Http Response:", response.toString()); 
        } catch (ClientProtocolException e) { 
            # hataların loglara yazılması
            e.printStackTrace(); 
        } catch (IOException e) { 
            # hataların loglara yazılması 
            e.printStackTrace(); 
        } 
    } 
}
 
]]>
Mac OS X de Apache Virtual Host kurulumu http://yazilimdersi.info/makaleler/detay/75/mac-os-x-de-apache-virtual-host-kurulumu Mon, 23 Feb 2015 00:00:00 +0000 mstfchelikVirtual Host, aynı IP üzerinden farklı domainlerde sitelerin çalıştırılmasına imkan sunan bir yapıdır. Virtual host kullanılarak tek bir IP ile farklı domainler ilişkilendirilip aynı makina üzerinden çalıştırılabilmemizi sağlamaktadır. Bu özellik aynı makina üzerinde farklı sistemlerin çalıştırıldığı birçok projede etkin olarak kullanılmaktadır. Bu özellik tamamen kurulu olan webserveriniz tarafından size sunulmaktadır. En güzel yanı ise virtual host tanımlanmasında herhangi bir sınırın bulunmamasıdır. Şimdi maddeler halinde Mac OS X kurulu bilgisayarınıza Apache virtual host tanımlamalarının nasıl yapıldığı hakkında bilgileri sunacağız. Öncelikle vim veya nano editörlerinden birini seçip terminali sudo ile root moda çekiniz.

1. Virtual Hostun enable edilmesi: 
Mac OS X bilgisayarda Apache kurulduğunda bazen virtual host yapısı disable halde gelmektedir. Bunun enable yani çalışabilir hale getirilebilmesi için aşağıda bulunan komut satırı terminalde çalıştırılmalıdır.
sudo nano /etc/apache2/httpd.conf
Yukarıdaki komutla birlikte Apache servere ait konfigürasyon dosyasına erişmiş oluyoruz. Bu dosya içerisinde 'vhosts' ifadesini aratıp önünü konulan # karakteri varsa bunu kaldırmamız gerekmektedir. Çünkü bu karakter mevcut bulunan satırın çalışırlığını iptal etmektedir.
# Virtual hostlar 

Include /private/etc/apache2/extra/httpd-vhosts.conf
# karakterini vhosts ifadesinin geçtiği satırdan kaldırmamızla birlikte Virtual Host enable hale getirildi.
 
2. Örnek Virtual Host eklenmesi: 
Şimdi sıra Apache'de yeni virtual host tanımlamalarının yapılmasına geldi. Aşağıda yapılan kodlama ile birlikte httpd-vhosts.conf dosyasına erişebiliriz:
sudo nano /etc/apache2/extra/httpd-vhosts.conf
Örnek olarak domaini yazilimdersi.info olan bir virtual host tanımlaması gerçekleştirmek istediğimizde aşağıda bulunan satırları örnek olarak bu dosyanın en alt satırına ekleyebiliriz:
<VirtualHost *:80> 

    ServerName yazilimdersi.info 
    ServerAlias www.yazilimdersi.info
    DocumentRoot "/Users/yazilim/Sites/yazilimdersi" 
    ErrorLog "/private/var/log/apache2/apple.com-error_log" 
    CustomLog "/private/var/log/apache2/apple.com-access_log" common 
    ServerAdmin [email protected] 
    
    <Directory "/Users/yazilim/Sites/yazilimderi"> 
        Options Indexes FollowSymLinks 
        AllowOverride All 
        Order allow,deny 
        Allow from all 
    </Directory> 

</VirtualHost>
Yukarıdaki kod parçacığında Sites altında yazilimdersi dizini oluşturmanız gerekmektedir. Projenizi bu dizin altına ekleyebilirsiniz.

3. Domainin local makinaya yönlendirilmesi: 
Aşağıda bulunan kodlama ile hosts dosyasına erişim sağlayabiliriz:
sudo nano /etc/hosts
Dosyaya erişim sağladıktan sonra aşağıdaki kodlama ile domainleri locale ekleyelim.
127.0.0.1 yazilimdersi.info www.yazilimdersi.info
Aşağıdaki komutla apache sunucunun restart edilmesi sağlanmalıdır.
sudo apachectl restart
Bu komutla birlikte yaptığınız düzenleme çalışır hale gelecektir. Artık browserinizi açıp http://yazilimdersi.info yazdığınızda localinizde bulunan kodlamanın çalıştığını göreceksiniz.

]]>
Ubuntu da Tomcat kurulumu http://yazilimdersi.info/makaleler/detay/74/ubuntu-da-tomcat-kurulumu Wed, 18 Feb 2015 00:00:00 +0000 mstfchelikApache Tomcat, Java projelerini çalıştırmak amacıyla hazırlanmış bir websunucu yazılımıdır. Apache yazılım ekibinin ürünü olan Java Servlet ve JavaServer Pages kullanılarak hazırlanmış açık kaynak kodlu bir sistemdir. Makalemizde Ubuntu işletim sistemine sahip bilgisayarlara Tomcat kurulumunun en basit şekilde nasıl gerçekleştirilebildiği hakkında bilgiler sunulmaktadır.

1. Tomcat kurulumu: 
Öncelikle sistemimizde bulunan apt-get listesini aşağıdaki komut ile gerçekleştirelim:
sudo apt-get update
Şimdi sistemimiz Tomcat kurulumuna hazır. Aşağıdaki komut ile kurulum işlemini başlatalım:
sudo apt-get install tomcat7
Kurulum süresince gelen tüm sorulara yes seçenegini seçerek geçiniz. Bu komut Tomcat ve bağlı oldugu diger programların kurulmasını sağlamaktadır. Ayrıca bu komut tomcat7 adında bir kullanıcı oluşturacaktır. Tomcat sunucuları default olarak 8080 portu üzerinde çalışmaktadır. Bu komut ile Tomcat kurulumu tümüyle tamamlanmadı ancak default giriş ekranına aşağıda ip adresinizin sonuna 8080 yazarak ulaşabilirsiniz.
http://makinaniza-ait-ip-adresi:8080
2. Ek paketlerin yüklenmesi: 
Aslında burada bulunan adımı yapmak zorunda değiliz. Burası tamamen kullanıcıyı daha efektif şekilde sistemi kullanmasında yardımcı olacak aracların kurulumunu saglamaktadır. Virtualhost, alias tanımlarının gerçekleştirilmesi, projelerin deploy edilmesi vs. gibi islemlerin yapıldıgı admin arayuzunun kurulumunu gerçekleştirmektedir. Konsola aşina bir kişi için bu arayüzler bir anlam ifade etmeyebilir. Ancak işini GUI üzerinden yapmak isteyen programcılar için yararlı araçlar sunmaktadır.

Aşağıda bulunan komutla birlikte online Tomcat dökümanın kurulumu, admin arayüzünün kurulumu ve birkaç örnek projenin kurulumu gerçekleştirilmektedir: 
sudo apt-get install tomcat7-docs tomcat7-admin tomcat7-examples
Kurulum süresince gelen tüm sorulara yes seçenegini seçerek geçiniz. Şimdi daha sonraki maddelerde kullanacagımız ek paketler kurulu hale geldi. Şimdi sırada Tomcat için kullanılan JDK (Java Development Kit) programının kurulumunu gerçekleştireceğiz. 

3. JDK kurulumu (isteğe bağlı): 
Uygulamanızı production sunucusuna attığınızda sorunsuz şekilde çalıştığından emin olmak adına JDK kurulumunu gerçekleştirmeniz büyük önem arz etmektedir. Java Development Kit aracı sayesinde Java programında yazılı olan projelerin çalıştırılması sağlanmaktadır. Aşağıda yazılı olan komutla default-jdk kurulumunu gerçekleştirebilirsiniz: 
sudo apt-get install default-jdk
4. Tomcat Web Yönetim Arayüzünün ayarlanması: 
2. maddede yüklediğimiz ek paketlerin nasıl kullanıldığını bu maddede açıklayacağız. Web yönetim arayüzüne erişimi gerçekleştirmek için kullanıcı adı ve şifre bilgilerinin sisteme girilmesi gerekmektedir. Böylelikle bu arayüze sadece izini olan kişilerin erişimi sağlanmalıdır. Bunu sağlamak için tomcat-users.xml dosyasına aşağıdaki komutla erişmeniz gerekmektedir
sudo nano /etc/tomcat7/tomcat-users.xml
Bu dosya default olarak işlemlerin nasıl gerçekleştirildiği ile alakalı yorum satıları ile doludur. Bu dosyada tomcat-users etiketinin arasında bulunan kısım bizim için önemlidir. Web yönetim arayüzüne erişim için gerekli kullanıcı adı ve şifre bilgilerini ve hangi yetkilere sahip olduğunu bu alana aşağıdaki şekilde yazabiliriz:
<tomcat-users> 
    <user username="kullanıcı adı" password="şifre" roles="manager-gui,admin-gui"/> 
</tomcat-users>
Yukarıdaki komutla birlikte kullanıcı adı ve şifre bilgisine sahip olan kullanıcının manager-gui ve admin-gui sayfalarına erişimine izin verilmektedir. Bu düzenlemenin ardından tomcat webserverin restart edilmesi gerekmektedir:
sudo service tomcat7 restart
5. Tomcat Web Arayüzüne erişim: 
Artık Tomcat web arayüzüne erişimi gerçekleştirebiliriz. Bunun için browsera ip adresi+port numarasını aşağıdaki şekilde yazmanız yeterli olacaktır
http://makinanizin-ip-adresi:8080
Yukarıdaki url verisi browsere yazıldıgında asagıdaki şekilde bir sayfa ile karsılasmanız gerekmektedir:

Bu sayfada 4 farklı link göreceksiniz. Bu linkler daha önceden hazırladığımız web arayüzüne ve sanal makina yönetim arayüzlerine erişimde kullanılan linklerdir. Bu sayfadan istediğiniz linke erişim gerçekleştirip projelerinizi deploy edebilirsiniz.
]]>
Mac OS X cihazlara FFmpeg kurulumu http://yazilimdersi.info/makaleler/detay/73/mac-os-x-cihazlara-ffmpeg-kurulumu Mon, 16 Feb 2015 00:00:00 +0000 mstfchelikHomebrew yazılımıdır. Homebrew, paket programların rahatlıkla indirilmesini ve çalıştırılmasını sağlayan kullanışlı bir araçtır. Aslında MacPorts yazılımına çok benzemektedir. Ancak FFmpeg kurulumunda daha kullanışlı ayarlar sunduğu için HomeBrew yazılımını tercih ettim. Ayrıca HomeBrew in sundugu olanakları ve kolaylıkları gördükten sonra, yazımızın ardından sürekli kullanmayı tercih edeceğinizi düşünüyorum.

1. XCode Kurulumu veya Güncellenmesi:
Homebrew yazılımını kullanmanız için XCode Command Line Tools yazılımını indirmeniz gerekmektedir. Kurulumu gerçekleştirmek için aşağıda bulunan adımları takip ediniz:
  • Mac App Store uygulamasını açıp XCode yazılımını yükleyin. Eğer cihazınızda XCode yazılımı mevcutsa, güncellemeyi unutmayınız.
  • XCode kurulumunun ardından Xcode uygulamasını açın. Preferences-Pane tabına tıklayın.
  • Burada Downloads tabını seçin. Command Line Tools olarak listelenen yazılım paketini yükleyiniz.


2. HomeBrew Kurulumu:
Homebrew yazılımını kurmak oldukça kolaydır. Tek yapmanız gereken bir terminal açmak ve aşağıda bulunan tek satır komutu çalıştırmanızdır.
  1. ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    
Programı yüklemenizin ardından aşağıda bulunan komutla kurulumun başarılı şekilde gerçekleştirildiğini kontrol ediniz:
  1. brew doctor
    
3. FFmpeg Kurulumu:
Yukarıdaki yazılımları kurmamızla birlikte artık FFmpeg kurulumuna geçebiliriz. FFmpeg kurulumu boyunca farklı ayarlarda kurulumların gerçekleştirildiği belirtmiştik. Aşağıda yazılı olan brew komutu sayesinde ffmpeg kurulumunda bize sunulan ayarlar ile alakalı bilgiler listelenecektir.
  1. brew options ffmpeg
    
    #komut çıktısı
    --with-fdk-aac 
        Enable the Fraunhofer FDK AAC library 
    
    --with-ffplay 
        Enable FFplay media player 
    
    --with-freetype 
        Build with freetype support
FFmpeg kurulumunda sunulan ayarları incelemenizin ardından istediğiniz düzenlemeleri komut satırına aşağıdaki şekilde ekleyebilirsiniz. Ancak herhangi bir ayar yapmadan da default olarak yükleme işlemini de gerçekleştirebilirsiniz:
  1. #bazı ayarlar yazılarak yapılan ffmpeg kurulumu için;
    brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-frei0r --with-libass --with-libvo-aacenc 
    --with-libvorbis --with-libvpx --with-opencore-amr --with-openjpeg --with-opus --with-rtmpdump --with-schroedinger 
    --with-speex --with-theora --with-tools
    
    #default ayarlara göre ffmpeg kurulumu için;
    brew install ffmpeg

]]>
Phpde Gerçek IP adresinin tespiti http://yazilimdersi.info/makaleler/detay/72/phpde-gercek-ip-adresinin-tespiti Wed, 14 Jan 2015 00:00:00 +0000 mstfchelik$_SERVER['REMOTE_ADDR'] verisi ile kullanıcının IP adresini almaya mı çalışıyorsunuz? Bu verinin gerçek Ip adresi getirmeyebileceği birçok durum bulunmaktadır. Eğer kullanıcı proxy server üzerinden internete bağlanıp, websitenizi ziyaret ettiyse muhtemelen $_SERVER['REMOTE_ADDR'] sorgusu sonrası dönen IP adresi kullanıcıya ait değil, proxy makinasına ait olan IP verisini dönecektir. Php programlama dilinde HTTP_CLIENT_IP ve HTTP_X_FORWARDED_FOR verileri kullanarak bu işlemleri gerçekleştirebiliyoruz. Aşağıda bulunan fonksiyon sayesinde proxy server üzerinden bağlanılsa bile kullanıcıya ait IP verisini getirmemize sebep olmaktadır:
  1. <?php
    function gercekIPAdresiniGetir() { 
        if (!empty($_SERVER['HTTP_CLIENT_IP']))
        { 
            $ip=$_SERVER['HTTP_CLIENT_IP']; 
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) 
        { 
            $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; 
        } else { 
            $ip=$_SERVER['REMOTE_ADDR']; 
        } 
        
       return $ip; 
    }
    ?>
Yukarıda bulunan kodlama ilk olara makinaya ait gerçek IP verisini çekmeye çalışıyor. Eğer bunu gerçekleştiremezse proxy sunucundan bağlanıldığı düşünülüp makinaya ait veri çekilmeye çalışıyor. Eğer bunda da başarılı olunmazsa direkt gerçek IP adresini çekmemizi sağlamaktadır.]]>
RGB-HEX Dönüştürücü http://yazilimdersi.info/makaleler/detay/71/rgb-hex-donusturucu Tue, 09 Dec 2014 00:00:00 +0000 mstfchelikRgb, İngilizce Red, Blue ve Green kelimelerinin baş harflerinden oluşan bir kısaltmadır. Türkçe'de Red; Kırmızı, Blue; Mavi, Green ise; Yeşil anlamına gelmektedir.Rgb; Kırmızı, Mavi ve Yeşil renkler ve bunların karışımından oluşan renklerin bulunduğu bir renk uzayıdır. Rgb renk modelinde renkler bu üç ana rengin değişik oranlarda eklenmesiyle (additive colors) oluşur. Rgb aynı zamanda renkli resim dosyası uzantısıdır. Sgi tarafından geliştirilmiş resim formatıdır. Güncel birçok resim programı tarafından açılabilir. Çoğunlukla yazılımcılar ve grafikçiler tarafından kullanılmaktadır. Hazırladığımız araç sayesinde RGB2Hex Dönüştürme veya Hex2RGB Dönüştürme işlemlerini rahatlıkla sitemiz üzerinden yapabilirsiniz.]]> Unix Time Stamp Dönüştürücü http://yazilimdersi.info/makaleler/detay/70/unix-time-stamp-donusturucu Tue, 09 Dec 2014 00:00:00 +0000 mstfchelikUnix Timestamp, 1 Ocak 1970 00:00 tarihinden bu yana geçen zamanın milisaniye cinsinden değeridir. Yazılım dillerinin birçoğunda tarih baz alınırken temel kabul edilen değişken olarakda bilinilmektedir. Hazırladığımız araç sayesinde Unix Timestamp'den gerçek tarihe veya gerçek tarihten Unix Timestamp'e dönüşüm işlemlerini sistemimiz üzerinden gerçekleştirebilirsiniz.]]> Ubuntuda Memcache Kurulumu http://yazilimdersi.info/makaleler/detay/68/ubuntuda-memcache-kurulumu Tue, 25 Nov 2014 00:00:00 +0000 mstfchelikMemcache, sunucunuzu hızlandırmak amacıyla kullanılan bir önbellek mekanizmasıdır. Memcache sistemi sayesinde cachelenmiş datanız RAM bellekte tutulmakta ve herhangi bir istek geldiğinde hızlı şekilde veri kullanıcıya iletilmektedir. Örneğin, ilk aşamada data veritabanından getirilmekte ve memcache kayıt edilmektedir. Sonrasındaki isteklerde ise veritabanına erişim yerine RAM de tutulan bu datanın kullanıcıya iletilmesi sağlanmaktadır. Ubuntu 12.04 kurulu olan sisteminizde memcache kurulumuna başlamadan önce sisteminizde bulunan paket programların güncel olduğundan emin olmanız için aşağıda bulunan komutu terminalinize yazıp çalıştırınız:
  1. sudo apt-get update
    
Ayrıca Memcache kurulumu sonrasında örnek çalışmayı gerçekleştirebilmemiz adına sisteminizde Php ve MySQL kurulumunu sağlamanız gerekmektedir:
  1. sudo apt-get install mysql-server php5-mysql php5 php5-memcache
    
1. Memcache Kurulumu:
Memcache kurulumunu kolaylıkla birkaç adımda gerçekleştireceğiz. apt-get komutu ile memcache kurulumunu sağlamak için aşağıda bulunan komutu kullanınız:
  1. sudo apt-get install memcached
Sonrasında ise memcache packagelerinin tutulduğu php-pear packetinin indirilmesi gerekmektedir:
  1. sudo apt-get install php-pear
Eğer serverinizde derleyici bulunmuyorsa, build-essential üzerinden kurulum işlemini yapabilirsiniz:
  1. sudo apt-get install build-essential
Son olarak PECL(PHP Extension Community Library) kullanarak memcache kurulumunu gerçekleştirelim:
  1. sudo pecl install memcache
Kurulum süresince karşınıza gelen tüm sorulara y tuşuna basarak kurulumu bitirebilirsiniz. PECL kullanarak yapılan kurulum sonrasında memcache.ini dosyasına aşağıda bulunan komutla memcache driverini ekleyebilirsiniz:
  1. echo "extension=memcache.so" | sudo tee /etc/php5/conf.d/memcache.ini
Son komutla birlikte artık memcache sistemimizde kurulmuş oldu. Artık memcache kullanımını gerçekleştirebiliriz.

2. Memcache Kontrolü ve Durum Görüntülenmesi:
Memcache serverimizde default olarak 11211 portunu kullanmaktadır. Kurulum işleminin gerçekleştirilmesinin ardından aşağıda bulunan komutla memcachenin çalışıp çalışmadığını kontrol edebiliriz:
  1. ps aux | grep memcache
Ayrıca memcache durumuyla alakalı bilgi almak içinde aşağıda bulunan komutu kullanabilirsiniz:
  1. echo "stats settings" | nc localhost 11211
3. Memcache Nasıl Çalışır:
Memcache sunucularda key,value mantığında çalışmaktadır. Kayıt edilen dataların hepsi unique bir keye sahip olması gerekmektedir. Kullanıcı sunucuya istekte bulunduğunda ilk olarak gelen data ile ilişkilendirilmiş key olup olmadığı Memcache üzerinde kontrol edilir. Eğer mevcut keye ait herhangi bir veri yoksa, veritabanından veri çekilecek şekilde script çalışır. Sonrasında veritabanından getirilen veriler mevcut key ile Memcache kayıt edilmektedir. Artık kayıt Memcachede tutulmaktadır. Bir sonraki kullanıcı isteğinde data artık Memcache üzerinden dönecektir. Kullanıcı memcache yapısına data eklerken expire time verisini de ekleyebilir. Yani kayıt edilen datanın silinme süresi memcacheden. Böylelikle belirli periyotlarla data silinip, güncel hali veritabanından getirilip tekrar içerik güncellemesi yapılması sağlanabilir. Sistemin nasıl çalıştığını daha iyi anlamamız için aşağıda bulunan basit kod parçacığını inceleyebilirsiniz:
  1. function kitapisminigetir(kitap_id) 
        #kitap isminin memcachede kayıtlı olup olmadığını kontrol edelim.
        kitapismi = memcached_get("kitapismi:" . kitap_id) 
        return kitapismi if defined kitapismi 
    
        #veritabanından kitap ismini getirelim.
        kitapismi = veritabanindangetir(kitap_id) 
        #veritabanından getirilen kitapismini memcache kayıt edelim.
        memcached_set("kitapismi:" . kitap_id, kitapismi)
        return kitapismi
    end
Yukarıda bulunan metodda gördüğünüz üzere eğer memcachede kitapismi:kitap_id sine ait herhangi bir kayıt olsaydı metod bunu return edecekti. Eğer kayıt bulunmuyorsa altta bulunan veritabanindangetir() metodu ile icerik getirilip memcache_set() ile memcache e kayıt edilmektedir.

4. Memcache İle Alakalı Basit Örnek:
 Bu bölümümüzde ise Php, MySQL kullanarak memcache mekanizmasının nasıl çalıştığı ile alakalı basit bir örnek program yapacağız. Öncelikle mysql -u root -p komutu ile mysql veritabanına giriş yapmanız gerekmektedir. test adında bir veritabanı oluşturup testkullanici kullanıcı adına sahip ve testsifre şifresinde bir kullanıcı kaydı oluşturalım. Bu kullanıcıyı da test veritabanına erişebilecek şekilde ayarlayalım. Bu işlemleri aşağıda bulunan komutlarla gerçekleştirelim:
  1. mysql -u root -p
    
    use test; 
    
    grant all on test.* to testkullanici@localhost identified by 'testsifre'; 
    
    create table ornek (id int, ad varchar(30)); 
    
    insert into ornek values (1, "ornekveri1"); 
    insert into ornek values (2, "ornekveri2");
    insert into ornek values (3, "ornekveri3");
    
    exit;
Exit komutu ile mysql terminalinden çıktıktan sonra aşağıda bulunan komutla memcachetest.php dosyasını oluşturalım:
  1. nano memcachetest.php
    
Aşağıda dosya içerisine yazılacak olan komutları satır satır sizlerle paylaşıyorum. Detaylı olarak satırlarla ilgili bilgilendirmelerin ardından tüm kodlamayı en altta sizlerle paylaşacağım:
  • Öncelikle aşağıda bulunan komut ile Memcache bağlantı kuralım. Daha önceden belirtiğim üzere Memcache 11211 portu üzerinden çalışmaktadır.
  1. <?php 
    $memcachebaglanti = new Memcache(); 
    $memcachebaglanti->pconnect('localhost', 11211);
  • Bir sonraki aşamada ise MySQL veritabanına bağlanalım. Yukarıdaki maddelerde test isimli bir veritabanına testkullanici adında ve testsifre isimli bir passwordu olan kullanıcı oluşturmuştuk. Bu maddede onları kullanacağız. 
  1. mysql_connect("localhost", "testkullanici", "testsifre") or die(mysql_error()); 
    mysql_select_db("test") or die(mysql_error());
  • Sonrasında Memcachede datanın kayıt edilmesinde kullanılacak bir key belirleyelim. Bunun unique olması önemlidir. Çünkü aynı istekte gelen sorgular için Memcache üzerinden datanın sunulması gerekecektir. Bunun için MySQL sorgusunu bu işlem için kullanabiliriz. Yapılacak sorguyu md5 formatına çekip key olarak kullanalım:
  1. $sorgu = "select id from ornek where ad= 'ornekveri1'"; 
    $sorguAnahtari = "ANAHTARKELIME :" . md5($sorgu);
  • Yukarıda oluşturulan sorguAnahtari ile ilk olarak Memcache kontrol edilecek. Bu key sistemde bulunuyorsa veri direkt bu key üzerinden verilecektir. Eğer yoksa veritabanına sorgu yapılacaktır. Dönen veri ise memcache yapısına yukarıdaki key ile kayıt edilecektir. Verinin tutulma süresi olarakta 300 saniye yani 5 dakikaya kullanacağım. Aşağıda bu konuyla alakalı kodlama bulunmaktadır:
  1. $sonuc = $memcachebaglanti->get($sorguAnahtari); 
    
    if (!$sonuc) { 
        $sonuc = mysql_fetch_array(mysql_query("select id from ornek where ad = 'ornekveri1'")) or die('mysql error'); 
        $memcachebaglanti->set($sorguAnahtari, $sonuc, 0, 300); 
        print "sonuc veritabanından getirildi\n"; 
        return $sonuc; 
    } 
    
    
    print "sonuc memcacheden getirildi\n"; 
    return $sonuc; 
    
    ?>
    
Yukarıda madde madde anlatılan scriptin tam hali şu şekildedir:
  1. <?php 
    $memcachebaglanti = new Memcache(); 
    $memcachebaglanti->pconnect('localhost', 11211); 
    
    mysql_connect("localhost", "testkullanici", "testsifre") or die(mysql_error()); 
    mysql_select_db("test") or die(mysql_error()); 
    
    $sorgu = "select id from ornek where ad= 'ornekveri1'"; 
    $sorguAnahtari = "ANAHTARKELIME: " . md5($sorgu); 
    
    $sonuc = $memcachebaglanti->get($sorguAnahtari); 
    
    if (!$sonuc) { 
    $sonuc = mysql_fetch_array(mysql_query("select id from ornek where ad= 'ornekveri1'")) or die('mysql error'); 
    $memcachebaglanti->set($sorguAnahtari, $sonuc, 0, 300); 
    print "sonuc veritabanından getirildi\n"; 
    return $sonuc; 
    } 
    
    print "sonuc memcacheden getirildi\n"; 
    return $sonuc; 
    
    ?>
    
Aşağıda birkaç kez memcachtest.php scripti çalıştırıldığında ortaya çıkacak çıktı şu şekilde olacaktır:
  1. # php memcachetest.php 
    sonuc veritabanından getirildi
    
    # php memcachetest.php 
    sonuc memcacheden getirildi
    
    # php memcachetest.php 
    sonuc memcacheden getirildi. 
    
    # php memcachetest.php << 5 dakika sonraki sorguda tekrar veritabanından getirilecektir.
    sonuc veritabanından getirildi.
    
    # php memcachetest.php
    sonuc memcachden getirildi.

]]>
Javada ArrayListlerde Ters Sıralama http://yazilimdersi.info/makaleler/detay/66/javada-arraylistlerde-ters-siralama Sun, 23 Nov 2014 00:00:00 +0000 mstfchelikArraylistlerin küçükten büyüğe sıralanması ile alakalı makaleyi bir önceki yazımızda sizlerle paylaşmıştık. Bu metodda Collections.sort(arraylist) kullanılmaktaydı. Ayrıca daha önceki makalelerimizde ArrayListlerin nasıl kullanıldığını sizlerle paylaşmıştık. ArrayListlerde içerikte eğer Integer veya String bulunuyorsa ve içeriklerin büyükten küçüğe listelenmesi isteniyorsa Collections.sort(arraylist, Collections.reverseOrder()) veya Collections.reverse(arraylist)  metodu kullanılmaktadır. Bu metod sayesinde Stringlerde alfabetik olarak, Integerlerda ise büyükten küçüğe sıralama yapılabilmektedir. 
  1. Collections.sort(arraylist, Collections.reverseOrder());
    #veya
    Collections.reverse(arraylist);
    Collections.sort(arraylist);
    
    
Arraylistlerin sıralaması ile alakalı örnek şu şekildedir:
  1. import java.util.*; 
    public class ArrayListTersSiralama { 
    
        public static void main(String args[]){
            ArrayList<String> diller = new ArrayList<String>(); 
            
            #diller arraylistine örnek programlama dilleri ekleyelim.
            diller.add("Java"); 
            diller.add("Android"); 
            diller.add("Php"); 
            diller.add("Ruby On Rails"); 
            diller.add("Linux");
         
            #sıralanmamış arraylisti listeleyelim.
            System.out.println("Sıralanmamış Diller:"); 
            
            for(String dil: diler){ 
                System.out.println(dil); 
            } 
    
            #sıralamayı ters olarak gerçekleştirelim. 
            Collections.sort(diller, Collections.reverseOrder()); 
            
            #sıralanmış arraylisti listeleyelim. 
            System.out.println("Ters Sıralanmış Diller:"); 
            
            for(String dil: diller){ 
                System.out.println(dil); 
            } 
        } 
    }
Yukarıda bulunan programın çıktısı şu şekilde olacaktır: 
  1. Sıralanmamış Diller:
    Java
    Android
    Php
    Ruby On Rails
    Linux
    Ters Sıralanmış Diller:
    Ruby On Rails
    Php
    Linux
    Java
    Android

]]>
Javada ArrayList Sıralama http://yazilimdersi.info/makaleler/detay/65/javada-arraylist-siralama Sun, 23 Nov 2014 00:00:00 +0000 mstfchelikArrayListlerin nasıl kullanıldığını sizlerle paylaşmıştık. Bu makalemizde ise Integer ve String tipindeki içeriklerin bulunduğu arraylistlerin nasıl sıralanabildiği ile alakalı detayları paylaşacağız. ArrayListlerde içerikte eğer Integer veya String bulunuyorsa, Collections.sort(arraylist) metodu kullanılmaktadır. Bu metod sayesinde Stringlerde alfabetik olarak, Integerlerda ise küçükten büyüğe sıralama yapılabilmektedir. 
  1. Collections.sort(arraylist);
String içerikli Arraylistlerin sıralamasına ait örnek şu şekildedir:
  1. import java.util.*; 
    public class ArrayListSiralama { 
    
        public static void main(String args[]){
            ArrayList<String> diller = new ArrayList<String>(); 
            
            #diller arraylistine örnek programlama dilleri ekleyelim.
            diller.add("Java"); 
            diller.add("Android"); 
            diller.add("Php"); 
            diller.add("Ruby On Rails"); 
            diller.add("Linux");
         
            #sıralanmamış arraylisti listeleyelim.
            System.out.println("Sıralanmamış Diller:"); 
            
            for(String dil: diler){ 
                System.out.println(dil); 
            } 
    
            #sıralamayı gerçekleştirelim. 
            Collections.sort(diller); 
            
            #sıralanmış arraylisti listeleyelim. 
            System.out.println("Sıralanmış Diller:"); 
            
            for(String dil: diller){ 
                System.out.println(dil); 
            } 
        } 
    }
Yukarıda bulunan programın çıktısı şu şekilde olacaktır: 
  1. Sıralanmamış Diller:
    Java
    Android
    Php
    Ruby On Rails
    Linux
    Sıralanmış Diller:
    Android
    Java
    Linux
    Php
    Ruby On Rails
Integer içerikli Arraylistlerin sıralamasına ait örnek ise şu şekildedir:
  1. import java.util.*; 
    public class ArrayListIntegerSiralama { 
    
        public static void main(String args[]){
            ArrayList<String> sayilar = new ArrayList<String>(); 
            
            #sayilar arraylistine örnek sayılar ekleyelim.
            sayilar.add(134); 
            sayilar.add(6); 
            sayilar.add(19); 
            sayilar.add(200); 
            sayilar.add(120);
            sayilar.add(2);
         
            #sıralanmamış arraylisti listeleyelim.
            System.out.println("Sıralanmamış Sayılar:"); 
            
            for(String sayi: sayilar){ 
                System.out.println(sayi); 
            } 
    
            #sıralamayı gerçekleştirelim. 
            Collections.sort(sayilar); 
            
            #sıralanmış arraylisti listeleyelim. 
            System.out.println("Sıralanmış Sayılar:"); 
            
            for(String sayi: sayilar){ 
                System.out.println(sayi); 
            } 
        } 
    }
Yukarıda bulunan programın çıktısı şu şekilde olacaktır: 
  1. Sıralanmamış Sayılar:
    134
    6
    19
    200
    120
    2
    Sıralanmış Sayılar:
    2
    6
    19
    120
    134
    200

]]>
Javada ArrayList Kullanımı http://yazilimdersi.info/makaleler/detay/62/javada-arraylist-kullanimi Thu, 20 Nov 2014 00:00:00 +0000 mstfchelikArrayList, dinamik olarak genişleyebilen tek boyutlu dizi yapıları olarak bilinmektedir. Java da util classından türetilen bu yapı için öncelikle kullanılacak classın import kısmına şu kodu eklemeniz gerekmektedir:
  1. import java.util.*;
Sonrasında ise arrayliste ait değişkenin tanımlanması için aşağıda bulunan kod parçacığını class ımız içerisinde tanımlıyoruz:
  1. ArrayList diller = new ArrayList();
Yukarıda yapılan tanımlama ile birlikte diller adı altında String tipinde bir ArrayList oluşturmuş olduk. Eğer String tipinde değil de, Integer tipinde bir ArrrayList oluşturmak istiyorsanız, aşağıda bulunan kodlamayı kullanmanız gerekmektedir: 
  1. ArrayList<Integer> diller = new ArrayList<Integer>();
ArrayList yapısında kullanılan önemli metodlar ve yaptığı işlemler şu şekildedir: 
diller.add(dil objesi) : ArrayListin sonuna eleman eklemek için kullanılır.
diller.remove(index) : ArrayListte kayıtlı elemanın silinmesinde kullanılır. Parametre olarak silinecek dökümana ait index numarası girilir. 
diller.size() : ArrayListin içerisindeki eleman miktarını göstermede kullanılır.
diller.clear() : ArrayListin içerisinde tüm elemanların silinmesinde kullanılır. 
diller.indexOf(aranılan kelime) : ArrayList elemanları içerisinde arama yapar. Eğer bulursa aranılan kelimeyi pozisyonu, bulamazsa -1 verisini döner. 
diller.get(index) : ArrayList içerisindeki indexe karşılık düşen değeri döner.

Şimdi anlattığımız metodları kullanarak bazı örnekler yapalım ve çalışma yapısını daha detaylı olarak inceleyelim.

Öncelikle OrnekArrayList.java adı altında bir java classı oluşturalım. İçerisine aşağıda bulunan kod parçacığını ekleyelim:
  1. import java.util.*; 
    
    public class TekBoyut { 
    
        public static void main(String[] args) { 
            #konsoldan kullanıcının dinamik olarak program dili girmesini sağlayalım.
            Scanner tara=new Scanner(System.in); 
    
            #diller adında arraylist tanımlayalım.
            ArrayList diller=new ArrayList();
    
            for(int i=0;i<3;i++) {  
               System.out.println("Programlama Dili Giriniz ("+(i+1)+") : "); 
               #klavyeden girdiginiz programlama dillerini arrayliste ekliyoruz.
               diller.add(tara.next());
             } 
        
            for(int i=0;i<3;i++) { 
               #eklenen dilleri listeleyelim.
               System.out.println(i+1+". dil:"+diller.get(i)); 
            } 
       
            #kayıtlı dillerin sayısı  
            System.out.println("kayıtlı dil sayısı:"+diller.size()); 
    
            #diller arraylistine statik olarak Java dilini ekleyelim.
            diller.add("Java")
            
            #kayıtlı dillerin sayısı 
            System.out.println("'java' ekli kayıtlı dil sayısı:"+diller.size());
    
            #diller arraylistindeki 2. elemanı silelim.
            diller.remove(1); 
       
            System.out.println("2. eleman silindi" );
    
            for(int i=0;i<diller.size();i++) { 
                #diller arraylistinin son halini listeleyelim. 
                System.out.println(i+1+". dil:"+diller.get(i)); 
            } 
            
            #dillerin tümü silindi
            diller.clear();
            System.out.println("tüm diller silindi.");
            System.out.println("kayıtlı dil sayısı: "+diller.size());
    
        } 
    }
Kod parçacığını çalıştırdığımız zaman Scanner(System.in) metodu ile kullanıcıdan 4 adet programlama dili girmesini isteyeceğiz. Her girilen programlama dili arraylist içerisine aktarılacaktır. Sonrasında girilen tüm programlama dilllerini consolde diller.get(i) metodu ile listeleyeceğiz. Daha sonrasında toplam kayıtlı dil sayısını gireceğiz. Ekstra olarak kendimiz "Java" programlama dilini gireceğiz. Eklemenin ardından 2. elemanı silip arraylistin boyutunu görüntüleyecegiz. En son olarak clear() metodu ile tüm kayıtları silip toplam kayıtlı dil sayısını konsolda göstereceğiz. Oluşacak çıktı şu şekilde olacaktır: 
  1. Programlama Dili Giriniz (1) : << Ruby on Rails
    Programlama Dili Giriniz (2) : << Android
    Programlama Dili Giriniz (3) : << C#
    Programlama Dili Giriniz (4) : << PHP
    
    1. dil: Ruby on Rails
    2. dil: Android
    3. dil: C#
    4. dil: PHP
    
    kayıtlı dil sayısı: 4
    'java' ekli kayıtlı dil sayısı: 5
    
    2. eleman silindi.
    
    1. dil: Ruby on Rails
    2. dil: C#
    3. dil: PHP
    4. dil: Java
    
    tüm diller silindi.
    kayıtlı dil sayısı: 0
    
    

]]>
Java ile MongoDB Kullanımı http://yazilimdersi.info/makaleler/detay/61/java-ile-mongodb-kullanimi Mon, 17 Nov 2014 00:00:00 +0000 mstfchelikMongoDB, 10Gen isimli şirket tarafından geliştirilen NoSQL veritabanıdır. Tamamen ücretsiz ve açık kaynak kodludur. Performans olarak ilişkili veritabanlarından daha hızlı olduğı kanıtlanmıştır. İçeriği önemli olmayan sektörlerde kullanılması tavsiye edilmektedir. Bankacılık veya devlete ait kurumsal bilgilerde kullanılması pek tavsiye edilmemektedir. Anlık olarak çok fazla işlem yapılması gerektiğinde veya önbellek kullanılmak istendiğinde tercih edilebilir. Önemli birçok uygulamada MongoDB kullanıldığı bilinmektedir. Makalemizde aşağıda bulunan maddeler sırasıyla anlatılacaktır:
  1. Java/MongoDB Sürücü Kurulumu
  2. MongoDB Bağlantısı Kurmak
  3. MongoDB ile Kayıtları Listelemek
  4. MongoDB ile Kayıt Eklemek
  5. MongoDB ile Kayıt Güncelemek
  6. MongoDB ile Kayıt Silmek
  7. MongoDB ile Collection Silmek
  8. MongoDB ile Veritabanı Silmek
1. Java/MongoDB Sürücü Kurulumu:
MongoDB sunucusuna bağlanabilmek için java diline ait mongoDB sürücüsünü yüklemeniz gerekmektedir. Hem Linux hem Windows tabanlı sistemlerde, http://central.maven.org/maven2/org/mongodb/mongo-java-driver/ linkinden jar dosyasını indirip projenize ekleyebilirsiniz. Ayrıca Maven destekli olan projenize aşağıda bulunan kodlamayla gerekli jar dosyasını ekleyebilirsiniz:
  1. <dependency>
        <groupId>org.mongodb</groupId> 
        <artifactId>mongo-java-driver</artifactId> 
        <version>2.12.4</version> 
    </dependency>
Yukarıda bulunan kod parçasında görüldüğü üzere jar dosyası en son olarak 2.12.4 versiyonunda bulunmaktadır.  
 
2. MongoDB Bağlantısı Kurmak:
MongoDB sürücüsünü projenize eklemenizin ardından artık bağlantı işlemlerine başlayabiliriz. Normalde mongoDB kurulumunda bağlantı için authentication gerekmemektedir. Yani sistem kimlik doğrulama özelliği olmadan kurulmaktadır. Ancak sonrasında istenilirse kullanıcı tarafından username, password ile sisteme erişim sağlanabilir. Ayrıca MongoDB default host olarak localhost, default port olarak ise 27017 portunu kullanmaktadır. Aşağıda bulunan komutla MongoDB ye örnek bir bağlantı oluşturalım:
  1. MongoClient mongoClient = new MongoClient("localhost", 27017);
    DB database = mongoClient.getDB("yazilimdersi_db");
Eğer authentication özelliğini aktif hale getirdiyseniz, aşağıdaki şekilde mongoDB'ye bağlantı sağlayabilirsiniz:
  1. MongoCredential credential = MongoCredential.createCredential("kullanıcıadı", "mongodb", "şifre".toCharArray());
    MongoClient mongoClient = new MongoClient(new ServerAddress("localhost"), Arrays.asList(credential));
    DB database = mongoClient.getDB("yazilimdersi_db");
3. MongoDB ile Kayıtları Listelemek:
MongoDB bağlantısının ardından artık collectionları inceleyebiliriz. Collectionlar, mongoDB'nin odacıkları olarak isimlendirilebilir. MySQL de tablo yapısına karşılık gelmektedir ve veriler bu hücrelerde tutulmaktadır. En önemli özelliği MySQLde bulunan tablosundan farklı olarak alan ad tanımlanmasının zorunlu olmamasıdır. Ayrıca ortak şema gereksinimi de bulunmamaktadır. Veriler bu collectionlar içerisinde json olarak tutulmaktadır. Aşağıda bulunan kodlama ile belirlediğimiz herhangi bir collectiona bağlanalım. Sonrasında bu collectiona örnek data ekleyelim.
  1. #ulkeler isimli collectiona bağlantı gerçekleştirelim.
    DBCollection col = database.getCollection("ulkeler");
    
    #bu collectiona örnek kayıt atalım.
    BasicDBObject obj = new BasicDBObject() 
            .append("id", 1) 
            .append("ulke", "Brezilya") 
            .append("ulkenufusu", 1000000); 
    WriteResult result = col.insert(obj, WriteConcern.JOURNAL_SAFE);
    
Yukarıda yapılan kodlama ile örnek kayıtlar ulkeler collectiona eklendi. Bu kayıtlara ait tüm sayıya ulaşmak için count() metodu kullanılmaktadır: 
  1. #kayıtlı ulke sayısını yazalım.
    System.out.println("kayıtlı ulke sayısı : ".$col->count());
    
Collectionlara eklenmiş olan tüm kayıtların listelenmesi için find() komutu kullanılmaktadır. Aşağıda bulunan kodlama ile kayıtlı olan tüm ulkelerin adını ve nufus sayısını görüntüleyebilirsiniz:
  1. import com.mongodb.MongoClient; 
    import com.mongodb.DBCollection; 
    import com.mongodb.DB; 
    import com.mongodb.BasicDBObject; 
    import com.mongodb.DBCursor; 
    import java.net.UnknownHostException; 
    
    public class MongoDBClass 
    { 
        public static void main(String[] args) { 
            try { 
                MongoClient mongo = new MongoClient("localhost"); 
                DB db = mongo.getDB("yazilimdersi_db"); 
                DBCollection dbcol = db.getCollection("ulkeler"); 
                DBCursor result = dbcol.find(); 
                while (result.hasNext()) { 
                    System.out.println(result.next()); 
                } 
            } catch(UnknownHostException e) { 
                System.out.println("Sunucu Hatası!"); 
            } 
        } 
    }
Yukarıda bulunan kodlama ile ulkeler collectiona ait tüm kayıtları çekip, listeledik. Eğer sadece nüfusu=1000 olan ülkeleri listelemek gibi bir özellik istiyorsanız find() metoduna koşulunuzu yazabilirsiniz. Örnek olarak aşağıda bulunan komut ile sadece nüfusu=1000 olan dilleri listeleyelim: 
  1. import com.mongodb.MongoClient; 
    import com.mongodb.DBCollection; 
    import com.mongodb.DB; 
    import com.mongodb.BasicDBObject; 
    import com.mongodb.DBCursor; 
    import java.net.UnknownHostException; 
    
    public class MongoDBClass 
    { 
        public static void main(String[] args) { 
            try { 
                MongoClient mongo = new MongoClient("localhost"); 
                DB db = mongo.getDB("yazilimdersi_db"); 
                DBCollection dbcol = db.getCollection("ulkeler"); 
                DBCursor result = dbcol.find("{ulkenufusu: 1000}"); 
                while (result.hasNext()) { 
                    System.out.println(result.next()); 
                } 
            } catch(UnknownHostException e) { 
                System.out.println("Sunucu Hatası!"); 
            } 
        } 
    }
Aşağıda yukarıdaki kodun çıktısı bulunmaktadır: 
  1. { "_id" : { "$oid" : "4fc68190a09ef7490a0b3b40"} , "ulke" : "Brezilya" , "ulkenufusu" : "100000"}
Eğer sadece bir kayıt çekmek istiyorsanız find() yerine findOne() metodunu kullanmanız yeterlidir.

4. MongoDB ile Kayıt Eklemek:
Yukarıdaki maddeler collectiona nasıl kayıt atıldığı ile alakalı örnek verdim. Ancak burada biraz daha detaylı olarak size sistemin nasıl çalıştığını anlatacağım. Collectionlara kayıt eklenirken insert() metodu kullanılmaktadır ve içerikler array olarak girilmektedir. Konuyla alakalı örnek kodlama şu şekildedir:
  1. import com.mongodb.MongoClient; 
    import com.mongodb.DBCollection; 
    import com.mongodb.DB; 
    import com.mongodb.BasicDBObject; 
    import com.mongodb.WriteResult; 
    import java.net.UnknownHostException; 
    import java.util.Date; 
    
    public class MongoDBClass
    { 
        public static void main(String[] args) { 
            Date date = new Date(); 
            try { 
                MongoClient mongo = new MongoClient("localhost"); 
                DB db = mongo.getDB("ornekdb"); 
                DBCollection dbcol = db.getCollection("kullanicilar"); 
                BasicDBObject obj = new BasicDBObject() 
                            .append("id", "1") 
                            .append("kullanici", "test user") 
                            .append("sifre", "1q2w3e") 
                            .append("date", date.getTime()); 
    
                WriteResult result = dbcol.insert(obj, WriteConcern.JOURNAL_SAFE); 
                System.out.println(result); 
            } catch(UnknownHostException e) { 
                System.out.println("Sunucu Hatası!"); 
            } 
        } 
    }
5. MongoDB ile Kayıt Güncellemek:
Collectionlarda mevcut herhangi bir kaydın güncellenmesinde ise $set ve update() keywordleri önemli bir yer tutmaktadır.Aşağıdaki kodlamada collectionlarda bulunan herhangi bir kaydın nasıl güncellediği ile alakalı örnek kodlama bulunmaktadır:
  1. import com.mongodb.MongoClient; 
    import com.mongodb.DBCollection; 
    import com.mongodb.DB; 
    import com.mongodb.BasicDBObject; 
    import com.mongodb.WriteResult; 
    import java.net.UnknownHostException; 
    import java.util.Date; 
    
    public class MongoDBClass
    { 
        public static void main(String[] args) { 
            Date date = new Date(); 
            try { 
                MongoClient mongo = new MongoClient("localhost"); 
                DB db = mongo.getDB("ornekdb"); 
                DBCollection dbcol = db.getCollection("kullanicilar"); 
                BasicDBObject obj = new BasicDBObject() 
                            .append("id", "1") 
                            .append("kullanici", "test user2") 
                            .append("sifre", "1q2w3e") 
                            .append("date", date.getTime()); 
    
                WriteResult result = _dbcol.update( 
                new BasicDBObject("kullanici", "test user"), 
                new BasicDBObject("$set", obj) 
                ); 
             
                if (result.getLastError().ok()) { 
                    System.out.println("Güncelleme başarılı"); 
                } else { 
                    System.out.println("Hata mesajı : " + result.getLastError().getErrorMessage()); 
                }
            } catch(UnknownHostException e) { 
                System.out.println("Sunucu Hatası!"); 
            } 
        } 
    }
6. MongoDB ile Kayıt Silmek:
Aşağıdaki kodlamada collectionlarda bulunan herhangi bir kaydın nasıl silindiği ile alakalı örnek kodlama bulunmaktadır. Burada keyword olarak remove() metodu kullanılmaktadır:
  1. BasicDBObject document = new BasicDBObject(); 
    document.put("number", 2);
    collection.remove(document);
Yukarıda bulunan komutla birlikte 2 numaralı kayıt collection içerisinde silinecektir.

7. MongoDB ile Collection Silmek:
Aşağıdaki kodlamada mevcut collectionın nasıl silindiği ile alakalı örnek kodlama bulunmaktadır. Burada keyword olarak drop() metodu kullanılmaktadır:
  1. #silinecek collectionun belirleyelim.
    collection.drop();
    
8. MongoDB ile Veritabanı Silmek:
Aşağıdaki kodlamada veritabanın nasıl silindiği ile alakalı örnek kodlama bulunmaktadır. Burada keyword olarak dropDatabase() metodu kullanılmaktadır:
  1. #veritabanı silinecektir.
    db.dropDatabase();

]]>
MySQL de AutoIncrement sayısını değiştirmek http://yazilimdersi.info/makaleler/detay/58/mysql-de-autoincrement-sayisini-degistirmek Fri, 14 Nov 2014 00:00:00 +0000 mstfchelik AutoIncrement index yapısını sunmaktadır. Bu yapı sayesinde oluşturduğumuz tablolarda primary key olarak belirlediğimiz sütunun unique kalması sağlanmaktadır. Bu durum ise her eklenen kayıtla birlikte bu sütun verisinin artırılması ile sağlanmaktadır. Her eklenen verinin ardından MySQL bu sütuna ait değeri bir artırıp içeriği sisteme eklemektedir. Ancak bazen bu alanın sıfırlanması veya herhangi bir sayıya setlenmesi gerekebilmektedir. Örneğin bir proje için tablo oluşturdunuz ve içerisine bazı test verileri eklediniz. Sonrasında bu tablodaki içerikleri silip autoincrement edilecek sütunun tekrardan resetlenmesini isteyebilirsiniz. Bu yöntemlerden bazıları şu şekildedir:
  1. AutoIncrement Verisinin Direkt Sıfırlanması
  2. Tablonun Truncate Edilmesi
  3. Tablonun Silinip Tekrardan Oluşturulması
1. AutoIncrement Verisinin Direkt Sıfırlanması: 
Aşağıda bulunan alter table komutu ile auto_increment verisinin 1 olarak setlenmesi sağlanmaktadır:
ALTER TABLE {TABLOISMI} AUTO_INCREMENT = 1;
Not: Tabloda bulunan kayıtın değerinin altını veya aynısını setleyemezsiniz. Yani tablonuzda 4 idli herhangi bir veri varsa, ve yukarıda bulunan komutu 4 olarak setleyerek çalıştırmak isterseniz, hata ile karşılaşacaksınızdır. MyISAM yapısı kullanılan tablolarda eger yukarıdaki belirtilen sekilde bir yanlıs kayıt setlenmek istenirse, sistem otomatik olarak en yüksek olan kayıt +1 olarak setlemeyi gerçekleştirecektir. InnoDB yapısındaki tablolarda ise komut calısmayacaktır.

2. Tablonun Truncate Edilmesi: 
Aşağıda bulunan truncate table komutu ile auto_increment verisinin 0 olarak setlenmesi sağlanmaktadır:
TRUNCATE TABLE {TABLOISMI};
3. Tablonun Silinip Tekrardan Oluşturulması: 
Dİğer bir yöntemde tablonun silinip tekrardan oluşturulmasıdır. Pek kullanışlı bir yöntem olmasa da bu işlemde isteneni sağlamaktadır:
DROP TABLE {TABLOISMI}; 
CREATE TABLE {TABLOISMI} { ... };

]]>
Linux da RAM miktarını öğrenme http://yazilimdersi.info/makaleler/detay/57/linux-da-ram-miktarini-ogrenme Fri, 14 Nov 2014 00:00:00 +0000 mstfchelik
  • free komutu
  • top komutu
  • vmstat komutu
  • /proc/meminfo dosyası
  • Makalemizde örnek komut olarak free komutunu kullanalım. Öncelikle terminali açınız ve aşağıda bulunan free -m komutunu yazınız. Bu komut bizlere cihazımızla alakalı kullanılan, kullanılmayan ve toplamda RAM miktarı ile alakalı bilgiler listeleyecektir.
    free -m
    Yazılan komut sonrasında terminalde listelenecek içerik örnek olarak şu şekilde olacaktır.
                 total    used     free    shared    buffers    cached 
    Mem:          7997    2618    5378      0         126       1353 
    -/+ buffers/cache:    1139    6858 
    Swap:        15623      0     15623
    Ayrıca /proc/meminfo dosya içeriğinden cihanıza ait RAM ile alakalı bazı bilgiler alabilirsiniz. Aşağıda yazılı olan komutu kullanmanız yeterli olacaktır:
    grep MemTotal /proc/meminfo
    Yukarıda bulunan metod /proc/meminfo dosyasında MemTotal kelimesini aratmaktadır. Sonrasında bu satırı terminalde aşağıdaki şekilde görüntülemektedir:
    MemTotal: 8121112 kB
    Yukarıda bulunan metod /proc/meminfo dosyasında MemTotal kelimesini aratmaktadır. Sonrasında bu satırı terminalde aşağıdaki şekilde görüntülemektedir. Gördüğünüz üzere yukarıda bulunan çıktıda cihazımızın 8GB kapasiteye sahip bir RAM belleği bulunmaktadır.

    ]]>
    Linux da İşlemci Sayısının Görüntülenmesi http://yazilimdersi.info/makaleler/detay/56/linux-da-islemci-sayisinin-goruntulenmesi Fri, 14 Nov 2014 00:00:00 +0000 mstfchelikLinux tabanlı makinanızda kaç işlemci bulunduğunu öğrenmek istiyorsanız bunun çok basit bir yolu bulunmaktadır. Linux işletim sistemine sahip cihazlarda /proc/cpuinfo altında tüm işlemciler hakkında detaylı bilgiler tutulmaktadır. Burada işlemcilerin hızı, chip-cache miktarı, işlemci tipi ve kaç çekirdekli işlemci olduğu ile alakalı bilgilerde sunulmaktadır. Aşağıda bulunan komut ile cihazınızda bulunan toplam işlemci sayısını rahatlıkla öğrenebilirsiniz:
    cat /proc/cpuinfo | grep processor | wc -l
    
    #makinamdaki islemci sayısını listeler.
    4
    Yukarıda bulunan komutla yapılan işlem aslında şu şekildedir. /proc/cpuinfo icerisinde bulunan dataları pipe yöntemi ile grep komutuna aktarmakta. Sonrasında içerisinde "processor" geçen kelimeleri getirmekte. En solda bulunan wc -l komutu ile de gelen kelimelerin miktarı hesasplanmaktadır.

    ]]>
    Php ile MongoDB Kullanımı http://yazilimdersi.info/makaleler/detay/55/php-ile-mongodb-kullanimi Thu, 13 Nov 2014 00:00:00 +0000 mstfchelikMongoDB, 10Gen isimli şirket tarafından geliştirilen NoSQL veritabanıdır. Tamamen ücretsiz ve açık kaynak kodludur. Performans olarak ilişkili veritabanlarından daha hızlı olduğı kanıtlanmıştır. İçeriği önemli olmayan sektörlerde kullanılması tavsiye edilmektedir. Bankacılık veya devlete ait kurumsal bilgilerde kullanılması pek tavsiye edilmemektedir. Anlık olarak çok fazla işlem yapılması gerektiğinde veya önbellek kullanılmak istendiğinde tercih edilebilir. Önemli birçok uygulamada MongoDB kullanıldığı bilinmektedir. Makalemizde aşağıda bulunan maddeler sırasıyla anlatılacaktır:
    1. Php/MongoDB Sürücü Kurulumu (Windows veya Linux sistemler için)
    2. MongoDB Bağlantısı Kurmak
    3. MongoDB ile Kayıtları Listelemek
    4. MongoDB ile Kayıt Eklemek
    5. MongoDB ile Kayıt Güncelemek
    6. MongoDB ile Kayıt Silmek
    7. MongoDB ile Collection Silmek
    8. MongoDB ile Veritabanı Silmek
    1. Php/MongoDB Sürücü Kurulumu (Windows veya Linux sistemler için):
    MongoDB sunucusuna bağlanabilmek için php'ye mongoDB sürücüsünü yüklemeniz gerekmektedir. Eğer Linux işletim sistemine sahip bir cihaz kullanıyorsanız, https://github.com/mongodb/mongo-php-driver linkinden sürücüyü indiriniz. Aslında yapılması gereken işlemlerle alakalı komutlar aşağıdaki gibi olacaktır:
    1. #Kodlamayı git hesabından indirelim.
      git clone https://github.com/mongodb/mongo-php-driver
      
      #sürücünün derlenebilmesi için php-dev yükleyelim.
      sudo apt-get install php5-dev
      
      #kodlamanın bulunduğu dizin içerisine girelim.
      cd mongo-php-driver
      
      #Kodu derleyip yükleme işlemini gerçekleştirelim.
      phpize 
      ./configure 
      make 
      sudo make install
      
      #Son olarak Php eklentisini aktif hale getirelim.
      sudo echo "extension=mongo.so" > /etc/php5/conf.d/10-mongo.ini
    Yukarıda bulunan komutlarla Linux işletim sistemine sahip cihazında yükleme gerçekleştirilmiş oldu.

    Eğer cihazınız Windows işletim sistemine sahip bir cihaz ise, o zaman http://pecl.php.net/package/mongo linkinden php versiyonunuza, 32-64 bit sisteminize bağlı olarak en uygun dll dosyasını indirmeniz gerekmektedir. Sonrasında indirilen php_mongo.dll dosyasını php sürücülerinin bulunduğu dizine kopyalayınız. Son olarakta php.ini dosyasına extension=php_mongo.dll satırını ekleyiniz. Bu işlem ile birlikte mongo sürücüsü sisteminizde kullanılır hale gelmiştir.

    Not: Her iki sistemde de konfigürasyonlar üzerinde işlemler gerçekleştirildiğinden dolayı sunucunun restart edilmesi gerekebilir.
     
    2. MongoDB Bağlantısı Kurmak:
    MongoDB kurulumunun ardından artık bağlantı işlemlerine başlayabiliriz. Normalde mongoDB kurulumunda bağlantı için authentication gerekmemektedir. Yani sistem kimlik doğrulama özelliği olmadan kurulmaktadır. Ancak sonrasında istenilirse kullanıcı tarafından username, password ile sisteme erişim sağlanabilir. Ayrıca MongoDB default host olarak localhost, default port olarak ise 27017 portunu kullanmaktadır. Aşağıda bulunan komutla MongoDB ye örnek bir bağlantı oluşturalım:
    1. <?php 
      try {  
         // Mongo Sunucusuna bağlanalım 
         $mongo = new Mongo('mongodb://localhost:27017'); 
      
         // Veritabanını Seçelim 
         $db = $mongo->selectDB('YazilimDersiDb'); 
      } catch(MongoConnectionException $e) { 
          die('Bağlantı kurulumunda sorun ile karşılaşıldı: ' . $e->getMessage()); 
      } 
      ?>
    Eğer authentication özelliğini aktif hale getirdiyseniz, aşağıdaki şekilde mongoDB'ye bağlantı sağlayabilirsiniz:
    1. $mongo = new Mongo('mongodb://kullanıcıadı:şifre@localhost:27017');
    3. MongoDB ile Kayıtları Listelemek:
    MongoDB bağlantısının ardından artık collectionları inceleyebiliriz. Collectionlar, mongoDB'nin odacıkları olarak isimlendirilebilir. MySQL de tablo yapısına karşılık gelmektedir ve veriler bu hücrelerde tutulmaktadır. En önemli özelliği MySQLde bulunan tablosundan farklı olarak alan ad tanımlanmasının zorunlu olmamasıdır. Ayrıca ortak şema gereksinimi de bulunmamaktadır. Aşağıda bulunan kodlama ile belirlediğimiz herhangi bir collectiona bağlanalım. Sonrasında bu collectiona örnek data ekleyelim.
    1. <?php
      #diller isimli collectiona bağlantı gerçekleştirelim.
      $diller = new MongoCollection($db, 'diller');
      
      #bu collectiona örnek kayıt atalım.
      $diller->insert(array('dil' => 'Android', 'makalesayisi' => 12));
      $diller->insert(array('dil' => 'Php', 'makalesayisi' => 22));
      $diller->insert(array('dil' => 'Ruby On Rails', 'makalesayisi' => 34));
      $diller->insert(array('dil' => 'Linux', 'makalesayisi' => 56));
      ?>
    Yukarıda yapılan kodlama ile örnek kayıtlar diller collectiona eklendi. Bu kayıtlara ait tüm sayıya ulaşmak için count() metodu kullanılmaktadır. Eğer Php'de array yapısına aşina iseniz, count() ifadesinin aslında arraylara ait sayıları getirmede de kullanıldığını bilirsiniz. 
    1. <?php
      #kayıtlı dil sayısını yazalım.
      echo "kayıtlı dil sayısı : ".$diller->count();
      ?>
    Collectionlara eklenmiş olan tüm kayıtların listelenmesi için find() komutu kullanılmaktadır. Aşağıda bulunan kodlama ile kayıtlı olan tüm dillerin adını ve makale sayısını görüntüleyebilirsiniz:
    1. <?php 
      #tüm dilleri çekelim. 
      $dilListesi = $diller->find(); 
      
      #kayıtlı dilleri listeleyelim. 
      foreach($dilListesi as $dil) { 
          printf('Dil : %s - Miktar : %s <br>', $dil['dil'], $dil['makalesayisi']); 
      }
      ?>
    Yukarıda bulunan kodlama ile diller collectiona ait tüm kayıtları çekip, listeledik. Eğer sadece makalesayisi=12 olan dilleri listelemek gibi bir özellik istiyorsanız where() metodunu kullanabilirsiniz. Örnek olarak aşağıda bulunan komut ile sadece makalesayisi=12 olan dilleri listeleyelim: 
    1. <?php 
      #koşulu belirleyelim.
      $where = array('makalesayisi' => '12');
      
      #makalesayisi 12 olan dilleri çekelim. 
      $dilListesi = $diller->find($where); 
      
      #sonuçları listeleyelim. 
      foreach($dilListesi as $dil) { 
          printf('Dil : %s - Miktar : %s <br>', $dil['dil'], $dil['makalesayisi']); 
      }
      ?>
    Ayrıca limit() metodu ile istenilen kadar kaydın listelenmesi, orderBy() metodu ile de kayıtların sıralanması sağlanabilmektedir. Örnek olarak sadece 2 kaydın listelenmesini ve bu listelemenin büyükten küçüğe yapılmasını istiyorsanız aşağıda bulunan kodlama işinizi görecektir. 
    1. <?php 
      #Sıralamayı belirleyelim. (1 : ASC , -1 : DESC)
      $orderBy = array('dil' => -1);
      
      #limit ver orderBy metodlarını uygulayalım. 
      $dilListesi = $diller->find()->limit(2)->orderBy($orderBy); 
      ?>
    Eğer sadece bir kayıt çekmek istiyorsanız find() yerine findOne() metodunu kullanmanız yeterlidir.

    4. MongoDB ile Kayıt Eklemek:
    Yukarıdaki maddeler collectiona nasıl kayıt atıldığı ile alakalı örnek verdim. Ancak burada biraz daha detaylı olarak size sistemin nasıl çalıştığını anlatacağım. Collectionlara kayıt eklenirken insert() metodu kullanılmaktadır ve içerikler array olarak girilmektedir. Konuyla alakalı örnek kodlama şu şekildedir:
    1. <?php 
      #eklenecek dil bilgilerini tanımlayalım.
      $yeniDil = array( 'dil' => 'Java', 'makalesayisi' => 122 ); 
      
      try { 
          $diller->insert($yeniDil); 
      } catch(MongoCursorException $e) { 
          die('Yeni dil eklenirken teknik bir sorunla karşılaşıldı ' . $e->getMessage()); 
      } 
      ?>
    5. MongoDB ile Kayıt Güncellemek:
    Collectionlarda mevcut herhangi bir kaydın güncellenmesinde ise where ve update() keywordleri önemli bir yer tutmaktadır.Aşağıdaki kodlamada collectionlarda bulunan herhangi bir kaydın nasıl güncellediği ile alakalı örnek kodlama bulunmaktadır:
    1. <?php 
      #güncellenecek kaydın koşulunu belirleyelim.
      $where = array('dil' => 'Java'); 
      
      #güncellenecek alanı belirleyelim.
      $guncelDil = array('makalesayisi' => 435); 
      
      #içeriği güncelleyelim.
      $diller->update($where, $guncelDil); 
      ?>
    6. MongoDB ile Kayıt Silmek:
    Aşağıdaki kodlamada collectionlarda bulunan herhangi bir kaydın nasıl silindiği ile alakalı örnek kodlama bulunmaktadır. Burada keyword olarak remove() metodu kullanılmaktadır:
    1. <?php 
      #silenecek kaydın koşullarını belirliyoruz.
      $where = array('dil' => 'Android'); 
      
      #kaydı collection içerisinden siliyoruz. 
      $diller->remove($where);
       
      ?>
    7. MongoDB ile Collection Silmek:
    Aşağıdaki kodlamada mevcut collectionın nasıl silindiği ile alakalı örnek kodlama bulunmaktadır. Burada keyword olarak drop() metodu kullanılmaktadır:
    1. <?php 
      #silinecek collectionun belirleyelim.
      $diller->drop();
      ?>
    8. MongoDB ile Veritabanı Silmek:
    Aşağıdaki kodlamada veritabanın nasıl silindiği ile alakalı örnek kodlama bulunmaktadır. Burada keyword olarak dropDatabase() metodu kullanılmaktadır:
    1. <?php  
      $db->dropDatabase();
      ?>

    ]]>
    Android de EditText kullanımı ve örnek uygulama http://yazilimdersi.info/makaleler/detay/54/android-de-edittext-kullanimi-ve-ornek-uygulama Wed, 12 Nov 2014 00:00:00 +0000 mstfchelikAndroid uygulamalarda EditText önemli bir yer tutmaktadır. Kullanıcıların veri girmesi için activitylere eklenilmektedir. Makalemizde öncelikle normal EditText'in nasıl oluşturulduğunu açıklayacağız. Sonrasnda EditText alanına yazılan verinin enter tuşuna basıldığında veya 5 rakamına basıldığında Toast mesajında gösterimini sağlayacağız.

    1. Android EditText Örneği: 
    Aşağıdaki kodlamada uygulamamızda  ilk olarak EditText oluşturacağız. Öncelikle butonun gösterileciği sayfanın arayüzünü aşağıda bulunan layout yapısından alalım. res/layout/activity_main.xml dosyası oluşturup aşağıda bulunan kodlamayı dosyanın içerisine yapıştıralım.
    <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" 
        android:background="#FFFFFF" > 
    
        <ImageView
            android:id="@+id/yazilimdersiImageView" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_alignParentBottom="true" 
            android:layout_centerHorizontal="true" 
            android:padding="10dp" 
            android:src="@drawable/ic_launcher" /> 
    
        <EditText 
            android:id="@+id/editText" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_centerHorizontal="true" 
            android:layout_centerVertical="true" 
            android:ems="10" /> 
    
        <TextView 
            android:id="@+id/TextView" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_above="@+id/editText" 
            android:layout_centerHorizontal="true" 
            android:layout_marginBottom="17dp" 
            android:padding="10dp" 
            android:gravity="center" 
            android:text="@string/sampletext" /> 
    
        <ImageView 
            android:id="@+id/yazilimdersiheaderImageView" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_alignParentTop="true" 
            android:layout_centerHorizontal="true" 
            android:src="@drawable/logo" /> 
    </RelativeLayout>
    Uygulamanın ekran görüntüsü aşağıdaki gibi olacaktır.
     

    Sonrasında EditText elementine onKeyListener eventinin eklenmesini sağlayacağız. Böylelikle kullanıcının 5 rakamına veya enter tuşuna bastığını anlamış olacağız. Sonrasında ise Toast mesajının görüntülemesi için gerekli kodlamayı MainActivity.java dosyasına yapıştırabilirsiniz. setOnKeyListener() metodu sayesinde butona tıklanıldığında toast gösterimine ait mesaj çağrılmaktadır.
    public class MainActivity extends Activity { 
        public Button openbrowserButton; 
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.activity_main); 
            editText = (EditText) findViewById(R.id.editText); 
    
            editText.setOnKeyListener(new OnKeyListener() { 
    
                public boolean onKey(View v, int keyCode, KeyEvent event) { 
    
                    if ((event.getAction() == KeyEvent.ACTION_DOWN) 
                        && (keyCode == KeyEvent.KEYCODE_ENTER)) { 
                
                        Toast.makeText(MainActivity.this, editText.getText(), Toast.LENGTH_LONG).show(); 
                        return true; 
                    } else if ((event.getAction() == KeyEvent.ACTION_DOWN)
                        && (keyCode == KeyEvent.KEYCODE_5)) { 
    
                        Toast.makeText(MainActivity.this, "5 tuşuna basıldı!", Toast.LENGTH_LONG).show(); 
                        return true; 
                    } 
                
                    return false; 
                } 
            });
    
        } 
    }
    Yukarıdaki kodlamada gördüğünüz üzere  cursor EditText alanında iken KeyEvent.KEYCODE_ENTER tıklanıldığında Toast mesajında EditText içerisinde yazılı olan ifadelerin gösterimi sağlandı. Eğer kullanıcı 5 tuşuna basarsa, Toast mesajı olarak "5 tuşuna basıldı!" mesajının gösterimi sağlandı. Kodlamada 5 rakamının algılanmasını ise KeyEvent.KEYCODE_5 ile sağlayabiliyoruz. Örnek EditText Uygulaması ile alakalı kodu aşağıdaki butona tıklayarak indirebilirsiniz:
    ]]>
    Android de Button kullanımı ve örnek uygulama http://yazilimdersi.info/makaleler/detay/53/android-de-button-kullanimi-ve-ornek-uygulama Wed, 12 Nov 2014 00:00:00 +0000 mstfchelikAndroid uygulamalarda buton önemli bir yer tutmaktadır. Kullanıcıların farklı activitylere geçişlerinde veya formlarda kullanılmaktadır. Makalemizde öncelikle normal butonun nasıl oluşturulduğu ve tıklanıldığında browserin açılması ile alakalı bir örnek kod sunacağız.

    1. Android Button Örneği: 
    Aşağıdaki kodlamada uygulamamızda  ilk olarak "Browserı Aç" butonu oluşturacağız. Öncelikle butonun gösterileciği sayfanın arayüzünü aşağıda bulunan layout yapısından alalım. res/layout/activity_main.xml dosyası oluşturup aşağıda bulunan kodlamayı dosyanın içerisine yapıştıralım.
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:tools="http://schemas.android.com/tools" 
       android:layout_width="match_parent" 
       android:background="#FFFFFF" 
       android:layout_height="match_parent" > 
    
       <Button 
           android:id="@+id/displayOpenBrowserButton" 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content" 
           android:layout_centerHorizontal="true" 
           android:layout_centerVertical="true" 
           android:textSize="20dp" 
           android:text="@string/open_browser" /> 
       
       <ImageView 
           android:id="@+id/yazilimdersiImageView" 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content" 
           android:layout_alignParentBottom="true" 
           android:layout_centerHorizontal="true" 
           android:padding="10dp" 
           android:src="@drawable/ic_launcher" /> 
    
    </RelativeLayout>
    Uygulamanın ekran görüntüsü aşağıdaki gibi olacaktır.
     

    Sonrasında butona tıklanıldığında browserin açılması ve yazilimdersi.info sitesinin açılması için aşağıda bulunan kodlamayı MainActivity.java dosyasına yapıştırabilirsiniz. setonClickListener() metodu sayesinde butona tıklanıldığında toast gösterimine ait mesaj çağrılmaktadır.
    public class MainActivity extends Activity { 
        public Button openbrowserButton; 
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.activity_main); 
            openbrowserButton= (Button) findViewById(R.id.displayOpenBrowserButton); 
            openbrowserButton.setOnClickListener(new OnClickListener() { 
             
                @Override 
                public void onClick(View v) { 
                    Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.yazilimdersi.info")); 
                    startActivity(browserIntent);
                } 
            }); 
        } 
    }
    Yukarıdaki kodlamada gördüğünüz üzere  butona tıklanıldığında Intent metodu çağrılmakta ve startActivity ile browserin açılması sağlanmaktadır. Intent.ACTION_VIEW, çağrılacak olan activitynin görüntülenmek amacıyla kullanacağı belirlemektedir. Örnek Button Uygulaması ile alakalı kodu aşağıdaki butona tıklayarak indirebilirsiniz:
    ]]>
    Android de Toast kullanımı ve örnek uygulama http://yazilimdersi.info/makaleler/detay/52/android-de-toast-kullanimi-ve-ornek-uygulama Sat, 11 Oct 2014 00:00:00 +0000 mstfchelikToast, Android geliştiriciler tarafından çoğunlukla uyarı mesajı gösterimlerinde kullanılmaktadır. Ayrıca kullanıcılara kısa sürelide olsa bilgilendirme mesajı gösterilmek istenildiğinde de kullanılabilmektedir. Gösterim süresinin geliştiriciler tarafından parametrik olarak atanılması sağlanmakla birlikte yazılı olacak text mesajını da bir diğer parametre olarak fonksiyona vermektedir. Makalemizde öncelikle normal toast mesajının nasıl yapıldığı ve custom toast mesajının oluşturulması hakkında bilgiler sunup, örnek kod paylaşımına gideceğiz.
    • Normal Toast Mesajı Gösterimi
    • Custom Toast Mesajı Gösterimi
    1. Normal Toast Mesajı Gösterimi: 
    Aşağıdaki kodlamada uygulamamızda "Normal Toast Mesajı Göster" butonu oluşturacağız. Kullanıcı bu butona tıkladığında normal toast mesajının gösterimini sağlayacağız. Öncelikle butonun gösterileciği sayfanın arayüzünü aşağıda bulunan layout yapısından alalım. res/layout/activity_main.xml dosyası oluşturup aşağıda bulunan kodlamayı dosyanın içerisine yapıştıralım.
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:tools="http://schemas.android.com/tools" 
       android:layout_width="match_parent" 
       android:background="#FFFFFF" 
       android:layout_height="match_parent" > 
    
       <Button 
           android:id="@+id/displayNormalToastMessageButton" 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content" 
           android:layout_centerHorizontal="true" 
           android:layout_centerVertical="true" 
           android:textSize="20dp" 
           android:text="@string/display_normal_toast_message" /> 
       
       <ImageView 
           android:id="@+id/yazilimdersiImageView" 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content" 
           android:layout_alignParentBottom="true" 
           android:layout_centerHorizontal="true" 
           android:padding="10dp" 
           android:src="@drawable/ic_launcher" /> 
    
    </RelativeLayout>
    Uygulamanın ekran görüntüsü aşağıdaki gibi olacaktır.
     

    Sonrasında butona tıklanıldığında standard toast mesajının gösterimi için aşağıda bulunan kodlamayı MainActivity.java dosyasına yapıştırabilirsiniz. setonClickListener() metodu sayesinde butona tıklanıldığında toast gösterimine ait mesaj çağrılmaktadır.
    public class MainActivity extends Activity { 
        public Button displayNormalToastMessageButton; 
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.activity_main); 
            displayNormalToastMessageButton = (Button) findViewById(R.id.displayNormalToastMessageButton); 
            displayNormalToastMessageButton.setOnClickListener(new OnClickListener() { 
             
                @Override 
                public void onClick(View v) { 
                    Toast.makeText(getApplicationContext(), getString(R.string.normaltoastmesaji), Toast.LENGTH_LONG).show(); 
                } 
            }); 
        } 
    }
    Yukarıdaki kodlamada gördüğünüz üzere  butona tıklanıldığında Toast.makeText(context,textmesajı,süre) metodu çağrılmaktadır. Context, çalışan uygulamayla alakalı ilgili contextin setlenmesiyle gerçekleştirilir. text mesajı, gösterilmesi planlanan mesajı ifade etmektedir. süre ise milisaniye cinsinden toastın gösterim sürecini belirlemede kullanılmaktadır. Burada süre olarak genelde Toast.LENGTH_LONG veya Toast.LENGTH_SHORT ifadeleri kullanılmaktadır. Normal Toast Uygulaması ile alakalı kodu aşağıdaki butona tıklayarak indirebilirsiniz:
    2. CustomToast Mesajı Gösterimi: 
    Aşağıdaki kodlamada uygulamamızda "Custom Toast Mesajı Göster" butonu oluşturacağız. Kullanıcı bu butona tıkladığında custom olarak hazırladığımız toast mesajının gösterimini sağlayacağız. Öncelikle butonun gösterileciği sayfanın arayüzünü aşağıda bulunan layout yapısından alalım. res/layout/activity_main.xml dosyası oluşturup aşağıda bulunan kodlamayı dosyanın içerisine yapıştıralım.
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:tools="http://schemas.android.com/tools" 
       android:layout_width="match_parent" 
       android:background="#FFFFFF" 
       android:layout_height="match_parent" > 
    
       <Button 
           android:id="@+id/displayCustomToastMessageButton" 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content" 
           android:layout_centerHorizontal="true" 
           android:layout_centerVertical="true" 
           android:textSize="20dp" 
           android:text="@string/display_custom_toast_message" /> 
       
       <ImageView 
           android:id="@+id/yazilimdersiImageView" 
           android:layout_width="wrap_content" 
           android:layout_height="wrap_content" 
           android:layout_alignParentBottom="true" 
           android:layout_centerHorizontal="true" 
           android:padding="10dp" 
           android:src="@drawable/ic_launcher" /> 
    
    </RelativeLayout>
    Burada custom toast oluşturmak istediğimizden dolayı ayrı bir layout dosyası hazırlanması gerekmektedir. Bu layout dısyasında da istediğimiz şekilde tasarımı belirleyip Toast.setView() metodu sayesinde gösterilecek mesaja uygulayabilmekteyiz. Aşağıda bulunan kod parçacığı sayesinde toast mesajının görünümü isteğimiz doğrultusunda güncelleyelim.

    Sonrasında butona tıklanıldığında custom toast mesajının gösterimi için aşağıda bulunan kodlamayı MainActivity.java dosyasına yapıştırabilirsiniz. setonClickListener() metodu sayesinde butona tıklanıldığında toast gösterimine ait mesaj çağrılmaktadır.
    public class MainActivity extends Activity { 
        public Button displayCustomToastMessageButton; 
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
           super.onCreate(savedInstanceState); 
           setContentView(R.layout.activity_main); 
           displayCustomToastMessageButton = (Button) findViewById(R.id.displayCustomToastMessageButton); 
           displayCustomToastMessageButton.setOnClickListener(new OnClickListener() { 
       
               @Override 
               public void onClick(View v) { 
                   LayoutInflater inflater = getLayoutInflater(); 
           
                   View layout = inflater.inflate(R.layout.custom_toast, (ViewGroup) findViewById(R.id.mainLinearLayout)); 
                   ImageView image = (ImageView) layout.findViewById(R.id.yazilimdersiImageView); 
                   image.setImageResource(R.drawable.ic_launcher); 
                   
                   TextView text = (TextView) layout.findViewById(R.id.customToastTextView); 
                   text.setText(getString(R.string.customtoastmesaji)); 
                  
                   Toast toast = new Toast(getApplicationContext()); 
                   toast.setGravity(Gravity.CENTER_VERTICAL, 0, 150); 
                   toast.setDuration(Toast.LENGTH_LONG); 
                   toast.setView(layout); 
                   toast.show(); 
               } 
           }); 
         } 
    }

    Yukarıdaki kodlamada gördüğünüz üzere  butona tıklanıldığında layoutInflater metodu çağrılmaktadır. Bu metod mevcut uygulama ile alakalı layout segmentini getirimektedir. Bu segment içerisinden hazırlamış olduğumuz custom_toast.xml dosyasını setlemekteyiz. Sonrasında layout içerisinde ImageView alanlarına istediğimiz resimlerin setlenmesi gerçekleştirmekte ve text yazı fontları ile alakalı düzenlemeler yapabilmekteyiz. Toast.setGravity metodu sayesinde toast mesajının gösterileceği konumu belirleyebilmekteyiz. Default olarak toast mesajları bottom yani altta görüntülenmektedir. Ancak biz uygulamamızda center kullanarak mesajın ortada gösterimini sağlayacağız. Toast.setDuration ile mesajın gösterileceği süreyi setlemekteyiz Ayrıca son olarak toast mesajı icin hazırlanmış viewi Toast.setView metodu ile programımıza uygulamaktayız. Uygulamanın çalıştırılmasıyla birlikte butona tıklanıldığında açılacak Toast mesajı aşağıdaki şekilde olacaktır:


    Custom Toast Uygulaması ile alakalı kodu aşağıdaki butona tıklayarak indirebilirsiniz:

    ]]>
    Android de örnek login ve registration sayfası dizaynı http://yazilimdersi.info/makaleler/detay/51/android-de-ornek-login-ve-registration-sayfasi-dizayni Sun, 12 Oct 2014 00:00:00 +0000 mstfchelikAndroid uygulamaların birçoğunda kullanıcılarla sürekli irtibat içerisinde kalmak ve onlara ait dataları güvenilir şekilde saklamak için bazı bilgilere ihtiyaç duyulmaktadır. Bu bilgilerin alınmasında registration formu, kontrolünde ise login formu önemli bir yere sahiptir. Makalemizde bu iki önemli sayfa ile alakalı basit bir design oluşturup sizlerle paylaşacağız. 
    Kodlamalar sonucunda oluşacak login ve registration sayfa tasarımları şu şekilde olacaktır:

     
    1. Login Ekranının Dizayn Edilmesi: 
    Aşağıdaki kodlamada uygulamamızda hazılanacak login sayfası ile alakalı design gerçekleştirilecektir. Layout yapıları içerisinde RelativeLayout en kullanışlı olduğundan her iki sayfanın tasarımında da kullandım. Uygulamada res/layout/activity_login.xml dosyası oluşturup aşağıda bulunan kodlamayı dosyanın içerisine yapıştıralım.
    <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" 
        android:background="#FFFFFF" 
        android:padding="20dp" > 
    
        <ImageView 
            android:id="@+id/yazilimdersiImageView" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_alignParentTop="true" 
            android:layout_centerHorizontal="true" 
            android:src="@drawable/logo" /> 
    
        <EditText 
            android:id="@+id/usernameEditText" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:layout_centerHorizontal="true" 
            android:layout_centerVertical="true" 
            android:background="@drawable/customedittext" 
            android:ems="10" 
            android:hint="@string/username" 
            android:inputType="textPersonName" 
            android:textColor="#969696" 
            android:textColorHint="#C7C7CD" 
            android:textCursorDrawable="@null" > 
            
            <requestFocus /> 
         </EditText> 
    
         <EditText 
            android:id="@+id/passwordEditText" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:layout_below="@+id/usernameEditText" 
            android:layout_centerHorizontal="true" 
            android:layout_marginTop="20dp" 
            android:background="@drawable/customedittext" 
            android:ems="10" android:hint="@string/password" 
            android:inputType="textPassword" 
            android:textColor="#969696" 
            android:textColorHint="#C7C7CD" 
            android:textCursorDrawable="@null" /> 
    
         <Button 
            android:id="@+id/loginButton" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:layout_below="@+id/passwordEditText" 
            android:layout_centerHorizontal="true" 
            android:layout_marginTop="10dp" 
            android:background="#265376" 
            android:padding="10dp"  
            android:textSize="16sp" 
            android:textColor="#FFFFFF" 
            android:text="@string/loginText" /> 
       
         <TextView 
            android:id="@+id/registerTextView" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:layout_alignLeft="@+id/passwordEditText" 
            android:layout_below="@+id/loginButton" 
            android:layout_marginTop="10dp" 
            android:clickable="true" 
            android:gravity="center" 
            android:singleLine="true" 
            android:text="@string/register" 
            android:textColor="#969696" 
            android:textSize="14sp" /> 
    
    </RelativeLayout>
    Kodlamada dikkat ederseniz Edit Textlerin görünümünde yenilik oluşturmak adına @drawable/customedittext dosyası kullanıldı. Bu dosyada yapılan kodlama sayesinde Android'in son sürümlerinde ortaya çıkan tasarım etkisi eski sürümlerde de gözlemlencek hale getirildi. Bu tasarım etkisinin oluşturulması için res/drawable/customedittext.xml dosyası oluşturup aşağıda bulunan kodlamayı dosya içerisine eklemeniz gerekmektedir. 
    <?xml version="1.0" encoding="utf-8"?> 
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 
       <item> 
           <shape android:shape="rectangle" > 
                <solid android:color="#ABABAB" />          
                <padding android:bottom="1dp" /> 
           </shape> 
       </item> 
       <item android:bottom="5dp"> 
           <shape android:shape="rectangle" > 
                 <solid android:color="#fff" /> 
                 <padding android:left="1dp" android:right="1dp" /> 
           </shape> 
       </item> 
       <item> 
           <shape android:shape="rectangle" > 
                 <solid android:color="#fff" /> 
                 <padding android:left="8dp" android:top="4dp" android:bottom="4dp"/> 
           </shape> 
       </item> 
    </layer-list>
    Login ekranın ekran görüntüsü aşağıdaki gibi olacaktır.
     

    2. Registration Ekranının Dizayn Edilmesi: 
    Aşağıdaki kodlamada uygulamamızda hazılanacak registration sayfası ile alakalı design gerçekleştirilecektir. Uygulamada res/layout/activity_tegister.xml dosyası oluşturup aşağıda bulunan kodlamayı dosyanın içerisine yapıştıralım.
    <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" 
       android:background="#FFFFFF" 
       android:padding="20dp" > 
    
       <ImageView 
          android:id="@+id/yazilimdersiImageView" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:layout_alignParentTop="true" 
          android:layout_centerHorizontal="true" 
          android:src="@drawable/logo" /> 
    
       <EditText 
          android:id="@+id/usernameEditText" 
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:layout_centerHorizontal="true" 
          android:layout_centerVertical="true" 
          android:background="@drawable/customedittext" 
          android:ems="10" 
          android:hint="@string/username" 
          android:inputType="textPersonName" 
          android:textColor="#969696" 
          android:textColorHint="#C7C7CD" 
          android:textCursorDrawable="@null" > 
     
          <requestFocus /> 
      </EditText> 
    
      <EditText 
          android:id="@+id/emailEditText" 
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:layout_below="@+id/usernameEditText" 
          android:layout_centerHorizontal="true" 
          android:layout_centerVertical="true" 
          android:layout_marginTop="20dp" 
          android:background="@drawable/customedittext" 
          android:ems="10" 
          android:hint="@string/email" 
          android:inputType="textEmailAddress" 
          android:textColor="#969696" 
          android:textColorHint="#C7C7CD" 
          android:textCursorDrawable="@null" > 
      </EditText> 
    
      <EditText 
          android:id="@+id/passwordEditText" 
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:layout_below="@+id/emailEditText" 
          android:layout_centerHorizontal="true" 
          android:layout_marginTop="20dp" 
          android:background="@drawable/customedittext" 
          android:ems="10" 
          android:hint="@string/password" 
          android:inputType="textPassword" 
          android:textColor="#969696"
          android:textColorHint="#C7C7CD" 
          android:textCursorDrawable="@null" /> 
    
      <Button 
          android:id="@+id/registerButton" 
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:layout_below="@+id/passwordEditText" 
          android:layout_centerHorizontal="true" 
          android:layout_marginTop="10dp" 
          android:background="#265376" 
          android:padding="10dp" 
          android:text="@string/registerText" 
          android:textColor="#FFFFFF" 
          android:textSize="16sp" /> 
    
      <TextView 
          android:id="@+id/loginTextView" 
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:layout_alignLeft="@+id/passwordEditText" 
          android:layout_below="@+id/registerButton" 
          android:layout_marginTop="10dp" 
          android:clickable="true" 
          android:gravity="center" 
          android:singleLine="true" 
          android:text="@string/login" 
          android:textColor="#969696" 
          android:textSize="14sp" /> 
    
    </RelativeLayout>
    Registration ekranın ekran görüntüsü aşağıdaki gibi olacaktır.
     
     
    3. Login Ekranından Registration Ekranına Geçiş: 
    Her iki maddenin tamamlanması ile birlikte ekranlara ait tasarımlar tamamlanmış oldu. Sırada bu ekranlar arası geçişlerin yapılmasını nasıl sağlayabileceğimiz ile alakalı kodlamada. Uygulama ilk açıldığında kullanıcıya login ekranı gösterilecektir. "Üye değil misiniz? Kaydolun" textine tıklanıldığında kullanıcının registration sayfasına yönlendirilmesini sağlayalım. Öncelikle LoginActivity.java dosyasını oluşturup aşağıda bulunan kodları dosya içerisine ekleyiniz:
    public class LoginActivity extends Activity { 
        public TextView registerTextView; 
    
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_login);  
             registerTextView = (TextView) findViewById(R.id.registerTextView); 
             registerTextView.setOnClickListener(new OnClickListener() { 
       
                 @Override 
                 public void onClick(View v) { 
                     Intent i = new Intent(getApplicationContext(), RegisterActivity.class); 
                     startActivity(i); 
                 } 
              }); 
       } 
    }
    Yukarıdaki kodlamada gördüğünüz üzere registrationTextView a tıklanıldığında startActivity() metodu sayesinde RegisterActivity.class çağrılmaktadır. Böylelikle Login ekranından Registration ekranına geçiş sağlanmaktadır.
     
    4. Registration Ekranından Login Ekranına Geçiş: 
    Uygulamada registration ekranında bulunan kullanıcının tekrar login ekranına yönlendirilmesini sağlamamız gerekebilir. "Üye misiniz? Giriş yapın" textine tıklanıldığında kullanıcının login sayfasına yönlendirilmesini sağlayalım. Öncelikle RegisterActivity.java dosyasını oluşturup aşağıda bulunan kodları dosya içerisine ekleyiniz:
    public class RegisterActivity extends Activity { 
        public TextView loginTextView; 
    
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.activity_register); 
            loginTextView = (TextView) findViewById(R.id.loginTextView); 
            loginTextView.setOnClickListener(new OnClickListener() { 
                
                @Override 
                public void onClick(View v) { 
                    finish(); 
                } 
            }); 
         } 
    }
    Yukarıdaki kodlamada gördüğünüz üzere loginTextView a tıklanıldığında finish() metodu sayesinde  mevcut activity kapatılmakta ve daha önceden çağrılan LoginActivity.java ekranı çağrılmaktadır. Böylelikle Registration ekranından Login ekranına geçişte sağlandı.

    5. Activitylerin AndroidManifest.xml Dosyasına Eklenmesi: 
    Uygulama ile alakalı tüm işlemler şu an için gerçekleştirildi. Ekranların tasarımları ve tıklanıldığında aktif hale gelecek activityler hazırlandı. Bunların son olarak AndroidManifest.xml dosyası içerisine konulmasına sıra geldi. Genelde uygulamalarımda tema olarak başlıksız tam ekranı beğendiğimden dolayı uygulama teması olarak android:theme="@android:style/Theme.NoTitleBar.Fullscreen" setledimAndroidManifest.xml dosyasının içeriği ise aşağıdaki gibi olmalıdır:
    <?xml version="1.0" encoding="utf-8"?> 
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
        package="com.yazilimdersi.info.example.registration" 
        android:versionCode="1" android:versionName="1.0" > 
    
    <uses-sdk 
        android:minSdkVersion="14" 
        android:targetSdkVersion="14" /> 
    
    <application 
        android:allowBackup="true" 
        android:icon="@drawable/ic_launcher" 
        android:label="@string/app_name" 
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" > 
        <activity 
            android:name=".LoginActivity" 
            android:label="@string/app_name" > 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
        <activity 
            android:name=".RegisterActivity" 
            android:label="@string/app_name" > 
        </activity> 
    </application>
    
    </manifest>
    Tüm işlemlerin ardından proje üzerinde sağa tıklayıp Run As => 1 Android Applicationa tıklayarak projeyi çalıştırınız.
     

    ]]>
    Android de dialog oluşturma http://yazilimdersi.info/makaleler/detay/50/android-de-dialog-olusturma Sat, 27 Sep 2014 00:00:00 +0000 mstfchelik
  • Tek butonlu uyarı dialogu oluşturmak ( tamam butonlu ) 
  • Çift butonlu uyarı dialogu oluşturmak ( evet ve hayır butonlu )
  • Üç butonlu uyarı dialogu oluşturmak ( evet, hayır ve iptal butonlu )
  • 1. Tek butonlu uyarı dialogu oluşturmak ( tamam butonlu ) : 
    Aşağıdaki kodlama "Tamam" isimli bir butondan oluşan basit bir dialog oluşturmanızı sağlayacaktır. setTitle() metodu ile oluşturulan dialoga başlık setlenmesi, setMessage() metodu ile de dialogun iceriginin setlenmesi, setIcon() metodu ile de dialoga ait ikonun setlenmesi saglanmaktadır. Ayrıca show() metodu sayesinde dialogun görüntülenmesi sağlanmaktadır.
    AlertDialog alertDialog = new AlertDialog.Builder( MainActivity.this).create(); 
    
    // Dialogun başlığını ayarlayalım
    alertDialog.setTitle("Tek Butonlu Uyarı Dialogu"); 
    
    // Dialogun içeriğini ayarlayalım
    alertDialog.setMessage("yazilimdersi.info sitesine hoşgeldiniz"); 
    
    // Dialogun ikonunu ayarlayalım 
    alertDialog.setIcon(R.drawable.home_normal); 
    
    // Tamam butonunu ayarlayalım
    alertDialog.setButton("Tamam", 
        new DialogInterface.OnClickListener() { 
            public void onClick(DialogInterface dialog, int which) { 
               Toast.makeText(getApplicationContext(), "Tamam butonuna tıkladınız!", Toast.LENGTH_SHORT).show(); 
            } 
        }); 
    
    // Dialogu görüntüleyelim 
    alertDialog.show();
    Uygulamanın ekran görüntüsü aşağıdaki gibi olacaktır.

    2. Çift butonlu uyarı dialogu oluşturmak ( evet ve hayır butonlu ) : 
    Aşağıdaki kodlama "Evet" ve "Hayır" isimli iki butondan oluşan dialog oluşturmanızı sağlayacaktır. setTitle() metodu ile oluşturulan dialoga başlık setlenmesi, setMessage() metodu ile de dialogun iceriginin setlenmesi, setIcon() metodu ile de dialoga ait ikonun setlenmesi saglanmaktadır. Ayrıca show() metodu sayesinde dialogun görüntülenmesi sağlanmaktadır.
    AlertDialog.Builder confirmDialog = new AlertDialog.Builder( MainActivity.this); 
    
    // Dialogun başlığını ayarlayalım
    confirmDialog.setTitle("Müşteri Silme"); 
    
    // Dialogun içeriğini ayarlayalım
    confirmDialog.setMessage("Silmek istediğinizden emin misiniz?"); 
    
    // Dialogun ikonunu ayarlayalım 
    confirmDialog.setIcon(R.drawable.home_normal); 
    
    // Evet butonunu ayarlayalım
    
    confirmDialog.setPositiveButton("Evet", 
        new DialogInterface.OnClickListener() { 
            public void onClick(DialogInterface dialog,int which) { 
                   Toast.makeText(getApplicationContext(), "Evet butonuna tıkladınız", Toast.LENGTH_SHORT).show(); 
            }
    }); 
    
    
    // Hayır butonunu ayarlayalım
    
    confirmDialog.setNegativeButton("Hayır", 
         new DialogInterface.OnClickListener() { 
             public void onClick(DialogInterface dialog, int which) { 
                    Toast.makeText(getApplicationContext(), "Hayır butonuna tıkladınız", Toast.LENGTH_SHORT).show(); 
                    dialog.cancel(); 
             } 
    });
    
    // Dialogu görüntüleyelim 
    confirmDialog.show();
    Uygulamanın ekran görüntüsü aşağıdaki gibi olacaktır.

    3. Üç butonlu uyarı dialogu oluşturmak ( evet, hayır ve iptal butonlu ) : 
    Aşağıdaki kodlama "Evet", "Hayır" ve "İptal" isimli üç butondan oluşan dialog oluşturmanızı sağlayacaktır. setTitle() metodu ile oluşturulan dialoga başlık setlenmesi, setMessage() metodu ile de dialogun iceriginin setlenmesi, setIcon() metodu ile de dialoga ait ikonun setlenmesi saglanmaktadır. Ayrıca show() metodu sayesinde dialogun görüntülenmesi sağlanmaktadır.
    AlertDialog.Builder confirmDialog = new AlertDialog.Builder( MainActivity.this); 
    
    // Dialogun başlığını ayarlayalım
    confirmDialog.setTitle("Dosyayı Kaydet..."); 
    
    // Dialogun içeriğini ayarlayalım
    confirmDialog.setMessage("Dosyayı kaydetmek ister misin?"); 
    
    // Dialogun ikonunu ayarlayalım 
    confirmDialog.setIcon(R.drawable.home_normal); 
    
    // Evet butonunu ayarlayalım
    
    confirmDialog.setPositiveButton("Evet", 
        new DialogInterface.OnClickListener() { 
            public void onClick(DialogInterface dialog,int which) { 
                   Toast.makeText(getApplicationContext(), "Evet butonuna tıkladınız", Toast.LENGTH_SHORT).show(); 
            }
    }); 
    
    
    // Hayır butonunu ayarlayalım
    
    confirmDialog.setNegativeButton("Hayır", 
         new DialogInterface.OnClickListener() { 
             public void onClick(DialogInterface dialog, int which) { 
                    Toast.makeText(getApplicationContext(), "Hayır butonuna tıkladınız", Toast.LENGTH_SHORT).show(); 
             } 
    });
    
    //İptal butonunu ayarlayalım
    
    
    confirmDialog.setNeutralButton("İptal", new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), "İptal butonuna tıkladınız", Toast.LENGTH_SHORT).show();
              } });
    // Dialogu görüntüleyelim confirmDialog.show();Uygulamanın ekran görüntüsü aşağıdaki gibi olacaktır.
    ]]>
    Android de menü oluşturma http://yazilimdersi.info/makaleler/detay/49/android-de-menu-olusturma Sat, 27 Sep 2014 00:00:00 +0000 mstfchelikAndroid cihazlarda menü yapısı önemli bir yer tutmaktadır. Birçok popüler uygulamada menü butonu aktif olarak kullanılmaktadır ve sayfalara göre farklı aksiyon alınacak şekilde dizayn edilmektedir. Bu makalemizde basit bir menü yapısının nasıl oluşturulduğu ile alakalı bilgi vereceğiz. Aşağıda makaleyi takip etmeniz halinde oluşturacağınız menü görüntüsünü paylaşıyorum:

     
    Şimdi Android programlama dili kullanarak basit bir menü uygulaması oluşturalım. Uygulamamızda resimde de gördüğünüz üzere 5 farklı menü elemanı oluşturulacaktır. Tıklanılan menü elemanında Toast mesajıyla hangi elemana tıklanıldığı görüntülenecektir.
    1. Eclipse programında File->New->Android Project linklerine tıklayarak MainActivity isimli bir java dosyası oluşturun.
    2. Sonrasında /res/layout/ dizini altında menu.xml dosyası oluşturun. 
    3. Bu dosyayı açıp içerisine resimde gördüğümüz menü itemlerini eklememiz gerekmektedir. Yani bu xml dosyasının içerisinde itemlere ait ikonlar ve textler listelenecektir. Burada android:icon kullanılacak ikon setini, android:title menü başlığını ve android:id ise her itemin idsini temsil etmektedir. Aşağıda bulunan kodlamaya göre ekleme yapmanız gerekmektedir.
      <?xml version="1.0" encoding="utf-8"?> 
      <menu xmlns:android="http://schemas.android.com/apk/res/android"> 
      
         <item android:id="@+id/menu_home" 
               android:icon="@drawable/home_normal" 
               android:title="Home" /> 
      
         <item android:id="@+id/menu_conversation" 
               android:icon="@drawable/conversation_normal" 
               android:title="Conversations" /> 
      
         <item android:id="@+id/menu_lastadded" 
               android:icon="@drawable/lastadded_normal" 
               android:title="Last Added" /> 
      
         <item android:id="@+id/menu_videos" 
               android:icon="@drawable/videos_normal" 
               android:title="Videos" /> 
      
         <item android:id="@+id/menu_more" 
               android:icon="@drawable/more_normal" 
               android:title="More" /> 
      
      </menu>
      
    4. İlk madde oluşturduğumuz MainActivity.java dosyasını açıp aşağıda yazılı olan kod parçacığını ekleyin.
      public class MainActivity extends Activity { 
      
          @Override 
          protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.activity_main); 
          } 
          
          @Override 
          public boolean onCreateOptionsMenu(Menu menu) { 
            MenuInflater menuInflater = getMenuInflater(); 
            menuInflater.inflate(R.layout.menu, menu); 
            return true; 
          } 
      
          @Override public boolean onOptionsItemSelected(MenuItem item) { 
            
            switch (item.getItemId()) 
            { 
            case R.id.menu_home: 
                 Toast.makeText(MainActivity.this, "Home is Selected", Toast.LENGTH_SHORT).show(); 
                 return true; 
      
            case R.id.menu_conversation: 
                 Toast.makeText(MainActivity.this, "Conversation is Selected", Toast.LENGTH_SHORT).show(); 
                 return true; 
      
            case R.id.menu_lastadded: 
                 Toast.makeText(MainActivity.this, "Last Added is Selected", Toast.LENGTH_SHORT).show(); 
                 return true; 
       
            case R.id.menu_videos: 
                 Toast.makeText(MainActivity.this, "Videos is Selected", Toast.LENGTH_SHORT).show(); 
                 return true; 
      
            case R.id.menu_more: 
                 Toast.makeText(MainActivity.this, "More is Selected", Toast.LENGTH_SHORT).show(); 
                 return true; 
      
            default: 
                 return super.onOptionsItemSelected(item); 
            } 
         }
      }
    5. Son olarak projenin dosyasının üzerinde sağa tıklayıp Run As -> Android Application seceneğine tıklayın. Aşağıdaki gibi emülatöre ait keypad görüntülenecektir. Menü  butonuna tıklayarak oluşturduğunuz menüleri görebilirsiniz.
    ]]>
    SQL sorgularında rastgele kayıt getirilmesi http://yazilimdersi.info/makaleler/detay/48/sql-sorgularinda-rastgele-kayit-getirilmesi Tue, 23 Sep 2014 00:00:00 +0000 mstfchelikSQL programlama dili kullanılarak farklı platformlarda veritabanından random olarak kayıtların nasıl getirildiği ile alakalı sorgular şu şekildedir. Bu sorgulamalar aslında yapısal olarak birbirlerinden pekte farklı değillerdir.
     
    SELECT column FROM table 
    ORDER BY RAND() 
    LIMIT 1
    SELECT column FROM table
    ORDER BY RANDOM() 
    LIMIT 1
    SELECT TOP 1 column 
    FROM table 
    ORDER BY NEWID()
    SELECT column, RAND() as IDX 
    FROM table 
    ORDER BY IDX FETCH FIRST 1 ROWS ONLY
    SELECT column FROM 
    ( SELECT column FROM table 
    ORDER BY dbms_random.value ) 
    WHERE rownum = 1
    Gördüğünüz gibi farklı platformlarda SQL diline ait syntax farklılık gösterebilmektedir. 

    ]]>
    SQL sorgularında ilk N kaydın getirilmesi http://yazilimdersi.info/makaleler/detay/47/sql-sorgularinda-ilk-n-kaydin-getirilmesi Tue, 23 Sep 2014 00:00:00 +0000 mstfchelik
     
    SELECT TOP 10 sütun FROM tablo
    SELECT sütun FROM tablo LIMIT 10
    SELECT sütun FROM tablo WHERE ROWNUM <= 10
    SET rowcount 10 
    SELECT sütun FROM tablo
    SELECT FIRST 10 sütun FROM tablo
    Gördüğünüz gibi farklı platformlarda SQL diline ait syntax farklılık gösterebilmektedir. Eğer uygulamalarınızı veritabanı bağımsız şekilde kullanmak isterseniz Coldfusion bunu rahatlıkla sağlamaktadır. Yapmanız gereken aşağıda yazıldığı gibi cfquery etiketine maxrows parametresini setlemenizdir.
    <cfquery datasource="#ds#" maxrows="10"> 
        SELECT column FROM table 
    </cfquery>

    ]]>
    Android programına arama fonksiyonu eklemek http://yazilimdersi.info/makaleler/detay/46/android-programina-arama-fonksiyonu-eklemek Fri, 19 Sep 2014 00:00:00 +0000 mstfchelikACTION_CALL intentini çağırmanız yeterli olacaktır. Örneğin uygulamanıza şirketinizle alakalı telefon numarasını eklediniz ve kullanıcı bu text alana tıkladığında direkt arama yapmasını istiyorsanız tek yapmanız gereken aşağıdaki kod parçacığına telefon numaranızı parametre olarak göndermenizdir.
    private void call(String telefonnumarasi) {
     
            try { 
                Intent callIntent = new Intent(Intent.ACTION_CALL); 
                callIntent.setData(Uri.parse("tel:" + telefonnumarasi)); 
                startActivity(callIntent); 
            } catch (ActivityNotFoundException e) { 
                Log.e("TAG", "Call failed", e); 
            } 
    
    }

    ]]>
    Php de CURL Post ve Get Kullanımı http://yazilimdersi.info/makaleler/detay/45/php-de-curl-post-ve-get-kullanimi Mon, 15 Sep 2014 00:00:00 +0000 mstfchelikPhp'de curl fonksiyonunu kullanarak websitelerinin iceriklerine rahatlıkla ulaşabilirsiniz. Yapılması gereken curl fonksiyonunda gerekli parametrelerin setlenmesiyle gerçekleşmektedir. Bunlardan en önemlisi tabiki içeriği alınması planlanan website adresinin tanımlanmasıdır. Bazı içeriklere POST metodu ile erişebilirken bazılarına GET ile istekte bulunmamız gerekmektedir. Makalemizde farklı başlıklar altında bu işlemlerin nasıl gerçekleştirildiği ile alakalı örnekler ve açıklamalar sunacağız. HTTP Get isteği file_get_contents() metodu kullanılarak sayfa içeriğini getirmede kullanılabilir.
    file_get_contens('http://yazilimdersi.info');
    
    Bu metod GET requesti ile sonuç dönen siteler için uygundur. Ancak POST ile gönderilmesi gereken isteklerde bu metod ne yazıkki hatayı handle etmenizde yeterli olmamaktadır. Burada curl metodu devreye girmektedir. Php curl metodunu çalıştırmanız için aşağıda açıklanan dört adımı takip etmeniz gerekmektedir:
    1. Curl fonksiyonunu tanımlanması
      $ch = curl_init();
      
    2. Curl fonksiyonuna parametrelerin girilmesi
      curl_setopt($ch,CURLOPT_URL,"http://yazilimdersi.info");
      curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
      //curl_setopt($ch,CURLOPT_HEADER, true); //if you want headers
      CURLOPT_URL -> Website içeriği getirilecek URL adresi
      CURLOPT_HEADER -> Header gönderilip gönderilmeyeceğinin belirlenmesi
      CURLOPT_RETURNTRANSFER -> true olarak setlenmesi durumunda çıktılar string olarak sitede listelenecektir.
    3. Curl fonksiyonunun çalıştırması
      $output=curl_exec($ch);
      
    4. Curl fonksiyonun kapatılması
      curl_close($ch);
      
    Php programlama dilinde CURL modülünün aktif olup olmadığını aşağıda bulunan kodlama ile anlayabilirsiniz:
    1. if(is_callable('curl_init')){ 
          echo "curl aktif modda"; 
      } else { 
          echo "curl pasif modda"; 
      }
      
    1. PHP Curl ile GET Metodu Örneği:
    Aşağıda yazılı olan fonksiyonu kullanarak siteye Get isteğinde bulunabilirsiniz:
    1. function GetMetodu($url) { 
          $ch = curl_init(); 
          curl_setopt($ch,CURLOPT_URL,$url); 
          curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); 
       // curl_setopt($ch,CURLOPT_HEADER, false); 
          
          $output=curl_exec($ch); 
          curl_close($ch); 
          return $output; 
      } 
      
      echo GetMetodu("http://yazilimdersi.info");
    Metodda görüldüğü üzere yazilimdersi.info sitesine ait içerikler GET isteğiyle içerikleri getirilmektedir.
     
    2. PHP Curl ile POST Metodu Örneği:
    Aşağıda yazılı olan fonksiyonu kullanarak siteye POST isteğinde bulunabilirsiniz:
    1. function httpPost($url,$params) { 
          $postData = '';
          foreach($params as $k => $v) { 
              $postData .= $k . '='.$v.'&'; 
          } 
          rtrim($postData, '&'); 
          
          $ch = curl_init(); 
      
          curl_setopt($ch,CURLOPT_URL,$url); 
          curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); 
          curl_setopt($ch,CURLOPT_HEADER, false); 
          curl_setopt($ch, CURLOPT_POST, count($postData));
          curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 
          
          $output=curl_exec($ch); 
      
          curl_close($ch); 
          return $output; 
      }
    Yukarıda yazılı olan fonksiyonu aşağıdaki şekilde çağırabiliriz:
    1. $params = array( 
          "name" => "Mustafa Çelik", 
          "age" => "26",
          "location" => "Istanbul" 
      );
       
      echo httpPost("http://yazilimdersi.info/php/postcurl.php",$params);
     3. Rastgele şekilde User-Agent Bilgisinin Gönderilmesi:
    Aşağıda yazılı olan fonksiyonu kullanarak curl isteğinize rastgele user-agent ataması yapabilirsiniz. Bazı siteler user-agent bilgisi olmadan içeriklerini sunmamaktadır. Bu tip durumlarda farklı user-agent bilgilerinin gönderilmesi uygun olan durumdur.
    1. function getRandomUserAgent() { 
          $userAgents=array( 
              "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6", 
              "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)", 
              "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)",
              "Opera/9.20 (Windows NT 6.0; U; en)", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.50", 
              "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.02 [en]", 
              "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; fr; rv:1.7) Gecko/20040624 Firefox/0.9", 
              "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/48 (like Gecko) Safari/48" 
          ); 
      
          $rastgele = rand(0,count($userAgents)-1); 
          return $userAgents[$rastgele]; 
      }
     CURLOPT_USERAGENT değişkeni aşağıdaki şekilde kullanılmaktadır.
    1. curl_setopt($ch,CURLOPT_USERAGENT,getRandomUserAgent());
     4. Curl Hatalarının Handle edilmesi
    Aşağıda yazılı olan fonksiyonu kullanarak curl isteğinizde oluşan hataları hem string olarak hemde error numarasına göre listeleyebilmektedir. Burada kullanılan metodlar ise curl_errno() ve curl_error()  metodlardır.
    1. function httpGetWithErros($url) 
      { 
          $ch = curl_init(); 
          curl_setopt($ch,CURLOPT_URL,$url); 
          curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); 
      
          $output=curl_exec($ch); 
      
          if($output === false) 
          { 
                 echo "Error Number:".curl_errno($ch)."<br>"; 
                 echo "Error String:".curl_error($ch); 
          } 
          curl_close($ch); 
          return $output; 
      }

    ]]>
    SQL de LIMIT ve OFFSET kullanımı http://yazilimdersi.info/makaleler/detay/44/sql-de-limit-ve-offset-kullanimi Wed, 10 Sep 2014 00:00:00 +0000 mstfchelikOFFSET ve LIMIT olarak adlandırılan anahtar komutları desteklemektedir. Bu komutlar kullanılarak veritabanından sorgu çekilirken sayfalama özelliğinin olması sağlanmaktadır. 
    LIMIT komutunu kullanılarak veritabanından dönecek sonuçlarda sayı sınırı getirebilmekteyiz. Örneğin 3000 kayıta sahip veritabanından sadece 100 kayıt çekmek istediğmizde aşağıdaki gibi LIMIT komutunu kullanmaktayız.
    SELECT sütun FROM tablo LIMIT 10
    Bu komut Microsoft SQL Serverde bulunan TOP anahtar kelimesine karşılık gelmektedir. Ancak LIMIT komutu hem MySQL hemde PostgreSQL dillerinde sorgunun sonuna eklenirken, TOP komutu SELECT komutundan sonra kullanılmaktadır.
    OFFSET komutunu ise veritabanından dönecek sonuçların başlangıç noktasını belirlemede kullanırız. Örneğin 100 kayıtlı veritabanından sadece 21-30 arasındaki kayıtları listelemek istiyorsanız aşağıdaki sorguyu kullanabilirsiniz:
    SELECT sütun FROM tablo LIMIT 10 OFFSET 20
    Bu komutlar sayesinde veritabanı seviyesinde sayfalama işleminin yapılması sağlanmaktadır. 

    ]]>
    Php de kullanıcının browser dilinin belirlenmesi http://yazilimdersi.info/makaleler/detay/42/php-de-kullanicinin-browser-dilinin-belirlenmesi Mon, 25 Aug 2014 00:00:00 +0000 mstfchelik
    function get_client_language($availableLanguages, $default='tr')
    { 
        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { 
            $langs=explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']); 
    
            foreach ($langs as $value){ 
                    $choice=substr($value,0,2); 
                    if(in_array($choice, $availableLanguages)){ 
                        return $choice; 
                    } 
            } 
         } 
    
         return $default; 
    }
    
    ]]>
    Php de iki konum arasındaki mesafeyi hesaplama http://yazilimdersi.info/makaleler/detay/40/php-de-iki-konum-arasindaki-mesafeyi-hesaplama Mon, 25 Aug 2014 00:00:00 +0000 mstfchelik"Wamp Server kurulumu ve kullanımı" başlıklı makalemizde daha önceden detaylı şekilde gerçekleştirmiştik. Kodlama için yapmanız gereken aşağıda bulunan fonksiyonu wamp server kurulu olan sisteminizde mesafe.php isminde bir dosya oluşturup içerisine kopyalamaktadır.

    function konumlarArasiMesafeyiGetir($enlem1, $boylam1, $enlem2, $boylam2) 
    {
        $theta = $boylam1 - $boylam2; 
        $mil = (sin(deg2rad($enlem1)) * sin(deg2rad($enlem2))) + 
               (cos(deg2rad($enlem1)) * cos(deg2rad($enlem2)) * cos(deg2rad($theta))); 
        $mil = acos($mil); 
        $mil = rad2deg($mil); 
        $mil = $mil * 60 * 1.1515; 
        $feet = $mil * 5280; 
        $yard = $feet / 3; 
        $kilometre = $mil * 1.609344; 
        $metre = $kilometre * 1000; 
        return compact('mil','feet','yard','kilometre','metre'); 
    }
    
    Yukarıda hazırlanan metodda öncelikle parametre olarak girilen enlem boylam bilgilerinden boylam bilgilerinin birbirinden çıkarılması sağlanmıştır. Elde edilen değer ise deg2grad() fonksiyonu sayesinde dereceden radiusa dönüştürülmüştür. Ortaya çıkan değerin sin() ve cos() fonksiyonları ile sayesinde cosinüs ve sinüs değerleri elde edilmiştir. Aslında geometride kullanılan hipotenüs verisinin bulunmasında kullanılan yöntemin aynısı bu fonksiyonda da kullanılarak sonuç metre,kilometre,feet e yard ölçü birimlerine bağlı olarak elde edilmiştir. Fonksiyonu çağırmak için aşağıda bulunan kod parçacığını konumlarArasiMesafeyiGetir fonksiyonun hemen altına ekleyelim.
     
    $konum1 = array('enlem' => 40.6167, 'boylam' => 43.1000); // Kars iline ait enlem-boylam bilgisi
    $konum2 = array('enlem' => 41.0136, 'boylam' => 28.9550); // İstanbul iline ait enlem-boylam bilgisi
    
    $mesafe = konumlarArasiMesafeyiGetir($konum1['enlem'], $konum1['boylam'], $konum2['enlem'], $konum2['boylam']); 
    
    foreach ($mesafe as $birim => $deger) 
    { 
        echo $birim.': '.number_format($deger,4).'<br />'; 
    }
    

    Örnek veri olarak Kars-İstanbul illeri arası mesafenin hesaplanmasını sağladım. Bilgisayarımın browser alanına http://localhost/mesafe.php yazdığımda aşağıda bulunan sonuçlar listelendi.

    mil: 739.3247 
    feet: 3,903,634.4912 
    yard: 1,301,211.4971 
    kilometre: 1,189.8278 
    metre: 1,189,827.7929
    

    ]]>
    Php de zararlı kodları temizleme http://yazilimdersi.info/makaleler/detay/39/php-de-zararli-kodlari-temizleme Mon, 25 Aug 2014 00:00:00 +0000 mstfchelik
    <?php
    
    function cleanInput($input) { 
    
        $search = array( 
          '@<script[^>]*?>.*?</script>@si', // Strip out javascript 
          '@<[\/\!]*?[^<>]*?>@si', // Strip out HTML tags 
          '@<style[^>]*?>.*?</style>@siU', // Strip style tags properly 
          '@<![\s\S]*?--[ \t\n\r]*>@' // Strip multi-line comments 
        ); 
        
        $output = preg_replace($search, '', $input); 
        return $output; 
    
    }
    
    function sanitize($input) { 
        
        if (is_array($input)) { 
            foreach($input as $var=>$val) { $output[$var] = sanitize($val); } 
        } else { 
            if (get_magic_quotes_gpc()) { $input = stripslashes($input); } 
            $input = cleanInput($input); 
            $output = mysql_real_escape_string($input); 
        } 
        return $output; 
    
    }
    
    ?>
    Yukarıdaki metod ile sisteme zarar verecek içeriklerden kurtulmuş oluruz. Aşağıda bulunan örnekle metodu nasıl çağıracağımızı inceleyelim ve nasıl bir sonuç aldığımızı görelim:
    <?php 
    
    $bad_string = "Hello! <script src='http://www.yazilimdersi.info/bad_script.js'></script> It's a good day!"; 
    $good_string = sanitize($bad_string); // $good_string sonuç olarak "Hello! It\'s a good day!" verisini döner. 
    // Bu metodu ayrıca POST ve GET isteklerinde de kullanabilirsiniz.
    $_POST = sanitize($_POST); 
    $_GET = sanitize($_GET); 
    ?>

    ]]>
    Php de diziler yapısı (array) http://yazilimdersi.info/makaleler/detay/38/php-de-diziler-yapisi-(array) Mon, 25 Aug 2014 00:00:00 +0000 mstfchelik Php programlama dilinde array yapısı çok önemli bir yere sahiptir. Array yapıları sayesinde aynı türden birçok veriyi tek bir değişken altında toplayabiliriz. Örnek verecek olursak; arabalar değişkenine Mercedes, BMW, Audi, Ferrari, Alfa Romeo tarzı araçları içerik olarak ekleyebiliriz. Ayrıca istediğimiz zaman arabalar değişkenine yeni arabalar ekleyip, çıkarabilir ve sıralamalarda farklılıklar gerçekleştirebiliriz. Aşağıda array yapısına bir örnek oluşturdum:
    $arabalar = array("Mercedes","BMW","Audi","Ferrari","Alfa Romeo");
    
    Ayrıca aynı işlemi şu şekilde de ifade edebiliriz:
    
    $arabalar[0] = "Mercedes";
    $arabalar[1] = "BMW";
    $arabalar[2] = "Audi";
    $arabalar[3] = "Ferrari";
    $arabalar[4] = "Alfa Romeo";

    Yukarıda diziler dikkat ederseniz key alanları 0,1,2,3,4 gibi rakamsal keylerden oluşmuştur. Ancak böyle olmak zorunda değillerdir. Bu key alanları anlamlı ifadelerle de tanımlanabilir. Mesela araçların model numaralarını baz alalım. Örnek yapı şu şekilde olabilir:

    $arabalar = array(
        "MX120"=>"Mercedes" , 
        "B12" => "BMW" , 
        "A6" => "Audi" ,
        "F6" => "Ferrari" , 
        "AR900" => "Alfa Romeo"
    );
    
    Bu tanım aslında şuna da karşılık gelmektedir: 
    
    $arabalar["MX120"] = "Mercedes";
    $arabalar["B12"] = "BMW";
    $arabalar["A6"] = "Audi";
    $arabalar["F6"] = "Ferrari";
    $arabalar["AR900"] = "Alfa Romeo";

    Gördüğünüz gibi dizilerin key alanlarına daha anlamlı ifadeler eklenebilmektedir. Ayrıca dize içerisinde dizilerde Php programlama dilinde yaygın kullanılan bir durumdur. Bu yapı sayesinde içiçe birçok dize tanımlaması yapılabilmektedir. Buna örnek verecek olursak ;

    $arabalar = array(
        "pahalilar"=> array("Mercedes" , "Ferrari", "Audi"), 
        "ucuzlar" => array("Toyota","Renault","Fiat") 
    );
    
    

    Eğer sizden ucuz arabaların listesini istersem tek yapmanız gereken $arabalar["ucuzlar"] değişkenine ait çıktıyı söylemenizdir. Eğer $arabalar["pahalilar"] değişkenini çağırırsanız pahali araçların isimleri listelenecektir.


    ]]>
    FeedBurner Hatası: The feed does not have subscriptions by email enabled http://yazilimdersi.info/makaleler/detay/37/feedburner-hatasi-the-feed-does-not-have-subscriptions-by-email-enabled Thu, 21 Aug 2014 00:00:00 +0000 mstfchelikFeedburner, websitenize ait içeriklerin xml olarak tanımlandığı linkten yararlanarak yeni içerik yazıldığı anda sitenizle ilişkilendirilmiş feede abone olan kişilere otomatik mail gönderimini sağlayan bir servistir. Tek yapmanız gereken sitenizde makale ve içeriklerinizin listelendiği bir xml linki oluşturmak ve bunu feedburner sistemine eklemenizdir. Sonrasında sitenizi ziyaret eden kullanıcılar eğer yeni makaleleriniz hakkında bilgilendirilmek isterlerse email adreslerini sizin eklendiğiniz FeedBurner sistemine ekleyecektir. yazilimdersi.info sitesinde de en altta bulunan Abone Ol alanı Feedburner üzerinde çalışacak şekilde kurgulanmıştır. Eklenmesi olabildiğine kolay olan bu sistemde karşılaşılan en yaygın hata şu şekildedir: 

    The feed does not have subscriptions by email enabled

    Sorunun çözümü ise şu şekildedir: Feedburner sitesinden kopyalanan html kodun değiştirilmeden websitenize yapıştırmanızdan kaynaklanmaktadır. Aşağıdaki gibi size HTML içerik veren feedburner kod parçacığına feedi eklediğiniz sisteminizle alakalı kullanıcı ismini uri alanına girmeniz gerekmektedir.
    <form style="border:1px solid #ccc;padding:3px;text-align:center;" 
        action="http://feedburner.google.com/fb/a/mailverify" method="post" target="popupwindow" 
        onsubmit="window.open('http://feedburner.google.com/fb/a/mailverify?uri=yazilimdersi', 'popupwindow', 'scrollbars=yes,width=550,height=520');
        return true">
    <p>E-Posta Adresiniz:</p>
    <p><input type="text" style="width:140px" name="email"/></p>
    <input type="hidden" value="yazilimdersi" name="uri"/>
    <input type="hidden" name="loc" value="en_US"/><input type="submit" value="Kaydol" />
    <p>Delivered by <a href="http://feedburner.google.com" target="_blank">FeedBurner</a></p>
    </form>
    Yukarıda bulunan kod parçacığında yazilimdersi yerine size ait feedburner hesabının kullanıcı ismini girmeniz yeterli olacaktır. Böylelikle hatadan kurtulacaksınız.

    ]]>
    Php ile Facebook sayfanıza ait beğeni sayısını ve diğer detayları gösterme http://yazilimdersi.info/makaleler/detay/35/php-ile-facebook-sayfaniza-ait-begeni-sayisini-ve-diger-detaylari-gosterme Tue, 19 Aug 2014 00:00:00 +0000 mstfchelikhttps://www.facebook.com/yazilimdersi şeklindedir. Graph yapısına göre sayfanın ismini: http://graph.facebook.com/+[SAYFA_ISMI] linke eklediğimizde bu sayfayla alakalı detaylı bilgiler json formatında listelenecektir. Websitemizle alakalı link
    http://graph.facebook.com/yazilimdersi şeklindedir. Bu linke gittiğinizde göreceğiniz içerik şu şekilde olacaktır muhtemelen.


    Gördüğünüz gibi facebook sayfasında bulunan birçok veriler burada listelenmektedir. Sayfanın beğeni sayısı, kaç kişini sayfada yazıştığı, açıklama ve sayfa linki vs. birçok veriye ulaşmanızı sağlamaktadır. Şimdi sırada Php programlama dilini kullanarak bu sayfa içeriklerinden beğeni sayısını nasıl çekeceğimizi inceleyelim. 

    Daha önceki konularda sizlere Php'de Curl yapısını anlatmıştım. Öncelikle curl ile alakalı bilgisi bulunmayan arkadaşlar linkteki makaleyi okuyabilirler. Sonrasında aşağıda bulunan kodlama ile sayfamıza ait graph linkine erişim yapmamız gerekmektedir.
     
    <?php 
    function getfacebooklikecount($url){ 
        
        $ch = curl_init($url); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
        $raw = curl_exec($ch); 
        curl_close($ch); 
        $data = json_decode($raw); 
        $content = $data->likes; 
        return $content; 
    } 
    
    $facebooklikes = getfacebooklikecount("http://graph.facebook.com/yazilimdersi"); 
    echo $facebooklikes; 
    
    ?>
    
    Yukarıdaki metodda görüldüğü üzere getfacebooklikecount($url) metoduna parametre olarak graph.facebook.com/yazilimdersi adresi verilmekte. curl_init metodu ile içeriğe erişilmektedir. Sonrasında json_decode metodu ile json formatındaki veri çözümlenip $data->likes ile sayfanın beğeni sayısı çekilmektedir. Sizde artık aynı fonksiyona parametre olarak kendi sitenize ait facebook linkini ekleyebilir ve beğeni sayısını online olarak facebook serverlerinden çekebilirsiniz.]]>
    Rockchip USB Sürücüsü kurulumu http://yazilimdersi.info/makaleler/detay/34/rockchip-usb-surucusu-kurulumu Sun, 10 Aug 2014 00:00:00 +0000 mstfchelik
    1. USB sürücüsünü şu linkten indirin ve zip dosyasından çıkarın.
    2. Release_DriverAsistant dizini altındaki DriverInstall.exe dosyasına iki kere tıklayın ve kurulumu başlatın.
    3. Eğer daha önceden Rockchip USB sürücüsünü kurduysanız, Uninstall Driver tuşuna basın. Eğer kurulum yapmadıysanız daha önceden direkt olarak Install Driver butonuna tıklayın.

    1. Install Driver butonuna tıklamanızla birlikte kullandıgınız Windows sürümüne göre güvenlik amacıyla uyarı mesajı cıkacaktır. Buna da evet diyerek kurulumu başlatınız.
    2. Kurulum tamamlandı. Şu an USB cihazınızı tekrardan bilgisayarınıza takın. Geliştirmenize kaldığınız yerden devam edebilirsiniz.
    ]]>
    Php de MySQL veritabanı işlemleri http://yazilimdersi.info/makaleler/detay/33/php-de-mysql-veritabani-islemleri Thu, 07 Aug 2014 00:00:00 +0000 mstfchelikEğer Php programlama dili kullanarak oluşturduğunuz websitenizin dinamik bir içeriğe sahip olmasını ve istediğiniz zaman kolaylıkla değiştirilebilmesini istiyorsanız veritabanı modüllerini kullanmanız gerekmektedir. Veritabanını bilgilerinizin tutulduğu bir mahzen gibi düşünebilirsiniz. Sadece sizde erişim bilgileri bulunan bir mahzen. Peki Php programında bu mahzene erişim için kullanılan metodlar nelerdir ?
    Bunlardan en önemlisi ve ilki olan mysql_connect() metodudur. Bu metod sayesinde mysql veritabanına erişim imkanı sunulmaktadır. Aslında bu metodun genişletilmiş hali mysql_connect(sunucu-adresi,kullanıcı-adı,şifre) şeklindedir. Burada ilk parametreye veritabanı sunucunuzun ip adresi girilmekte, ikinci parametreye veritabanı erişiminde kulllanılan kullanıcı adı ve üçüncü parametre olarak ise bu kullanıcıya ait şifre girilmektedir. Bu metod bize bağlantıyı başarılı şekilde gerçekleştirmemiz halinde true, aksi takdirde false dönecektir. 
    <?php 
        $baglanti = mysql_connect( "sunucu ip adresi", "kullanıcı adı", "şifre" ); 
    
        if ( !$baglanti ) 
            exit( "Veritabanı ile bağlantı sağlanamadı." );
    
    ?>
    Yukarıda bulunan kodlama ile veritabanına erişim yapmaya çalışırız. Eğer bağlantı kabul edilmezse hata mesajı olarak ekranda "Veritabanı ile bağlantı sağlanamadı." görüntülenecektir. Bağlantının kurulmasının ardından mysql_select_db( veritabanı_adı ) metodu ile hangi veritabanına bağlanacağımızı sunucuya söyleriz. 
    <?php 
        $baglanti = mysql_connect( "sunucu ip adresi", "kullanıcı adı", "şifre" ); 
    
        if ( !$baglanti ) 
            exit( "Veritabanı ile bağlantı sağlanamadı." );
        
        mysql_select_db( "yazilimdersi" );
    
    ?>
    Veritabanına yapılan bağlantıların kapatılmasında ise mysql_close() metodu kullanılmaktadır. Bu metod sayesinde veritabanına yapılan açık bağlantılar kesilir. Eğer açılan bağlantılar kesilmezse yüksek ziyaretcisi bulunan sitelerde sorunlar oluşabilir.

    Php programlama dilinde  MySQL sorgusu çalıştırmak için mysql_query(sorgu) metodu kullanılmaktadır. Bu metod sayesinde veritabanına eklemeler, silmeler, düzenlemeler ve listelemeler gerçekleştirilmektedir. Örnek kullanım şu şekildedir: 
    <?php 
        mysql_query( "INSERT INTO kullanici_bilgisi (isim,soyisim,meslek,durum) VALUES('Serkan','Karataş','Muhasebeci','1');" ); 
    ?>
    Eğer veritabanında bulunan verilerin çekilmesini ve sitenizde listelenmesini istiyorsanız mysql_fetch_array(sorgu) metodunu kullanabilirsiniz. Bu metod sayesinde daha önceden veritabanıza eklenmiş tüm kullanıcı bilgilerini rahatlıkla listeleyebilirsiniz. Örnek sorgulama şu şekildedir: 
    <?php 
    
        $baglanti = mysql_connect( "sunucu ip adresi", "kullanıcı adı", "şifre" ); 
        if ( !$baglanti ) exit( "Veritabanı ile bağlantı sağlanamadı." );
        
        mysql_select_db( "yazilimdersi" ); 
        $sorgu = mysql_query( "SELECT * FROM kullanici_bilgisi WHERE durum = '1';" ); 
        while( $row = mysql_fetch_array( $sorgu ) ) 
        { 
           echo $row['isim']." ".$row['soyisim']. " ın mesleği : " . $row['meslek']; 
           }
          
           mysql_close();
    
    ?>
    Böylelikle Php programı üzerinden MySQL veritabanına bağlantı kurmuş olduk. Sitenizi belirtilen metodlarla artık dinamik hale getirebilirsiniz.
     

    ]]>
    Php mail fonksiyonu kullanımı http://yazilimdersi.info/makaleler/detay/32/php-mail-fonksiyonu-kullanimi Thu, 07 Aug 2014 00:00:00 +0000 mstfchelikmail (alıcı,başlık,mesaj,ayarlar) şeklindedir.
    alıcı : Mesajı alacak olan kişinin email adresinin girildiği parametredir.
    başlık: Gönderilecek mesajın başlığının girildiği parametredir.
    mesaj: Gönderilecek mesaj içeriği ile alakalı bilgilerin girildiği parametredir.
    ayarlar: Mesaj ile alakalı yapılacak ayarların bulunduğu parametredir.
    Aşağıda mail fonksiyonu kullanarak hazırlanmış bir kodlama bulunmaktadır:
    <?php 
    
    $alici = "[email protected]"; 
    $baslik = "yazilimdersi.info sitesine hoşgeldiniz"; 
    $mesaj = "Merhaba Serap Hanım \n YazılımDersi sitesinde farklı programlama dilleriyle ilişkili birçok döküman bulabilirsiniz."; 
    $gonderen = "[email protected]"; 
    $ayarlar = "From: $gonderen"; 
    mail( $alici, $baslik, $mesaj, $ayarlar ); 
    
    ?>

    ]]>
    Php de sessions (oturumlar) http://yazilimdersi.info/makaleler/detay/31/php-de-sessions-(oturumlar) Thu, 07 Aug 2014 00:00:00 +0000 mstfchelikişlediğimizde sizlere bu bilgilerin kullanıcının browserinde tutulduğunu dile getirmiştik. Php'de oturumlar ise sunucuda tutulmaktadır. Bu yapıda kullanıcı ile alakalı bilgiler sunucular üzerinde tutulmakta ve admin tarafından kolaylıkla kontrol altına alınabilmektedir. Session yapısının çalışabilmesi için session_start() metodunun Php dosyalarının başına eklenmesi gerekmektedir. Sessionların setlenmesi ise $_SESSION["degisken"] = "deger" şeklindedir.
    <?php 
        session_start(); 
        $_SESSION['kullanici_adi'] = "Serap"; 
    ?>
    Yukarıda yapılan setlemeyle birlikte websitenizin herhangi bir yerinden kullanici_adi degiskenine ait degere Sessionlar üzerinden erişebilirsiniz. Peki herhangi bir değişkene ait sessionın setlenip setlenmediği konusunu nasıl çözebiliriz ? Bunun kontrolü için ise isset() metodu kullanılmaktadır.
    <?php 
        session_start(); 
        if ( isset( $_SESSION['sayac'] ) ) 
            $_SESSION['sayac'] = $_SESSION['sayac'] + 1; 
        else 
            $_SESSION['sayac'] = 1; 
        
        echo "Bu sayfa " . $_SESSION['sayac'] . " kez görüntülendi."; 
    
    ?>
    Yukarıda yazılan kodlamada isset ile sayac degiskine ait herhangi bir setlemenin olup olmadığı kontrol edilmekte. Eğer setleme bulunmuyorsa 1 rakamı setlenmekte, eger setleme yapılmıssa daha önceden bu durumda da mevcut degere +1 eklenerek deger yükseltilmektedir.

    Mevcutta bulunan bir session degiskeninin tamamen silinmesi için unset() metodu kullanılmaktadır. Bu metoda parametre olarak silinecek session degiskeni bilgisi girilir. Böylelikle bu sessiona ait degisken ve degerler tamamen silinmiş olacaktır. Session silinmesi işlemi aşağıdaki gibidir:
    <?php 
        unset( $_SESSION['sayac'] ); 
    ?>

    ]]>
    Php de cookies (çerezler) http://yazilimdersi.info/makaleler/detay/30/php-de-cookies-(cerezler) Thu, 07 Aug 2014 00:00:00 +0000 mstfchelik
    // setcookies ( isim, deger, süre) şeklinde kullanılmaktadır.
    setcookie( "language", "tr", time() + (24*3600) ); // 1 gün geçerlidir.
    Bir çerezin daha önceden setlenmiş değerlerini almak için aşağıdaki metodu kullanabiliriz:
    <?php 
        echo $_COOKIE['language']; // language adlı çerezin değerini getirir.
    ?>
    Sitenizin setlediği tüm çerezlerin görüntülenmesini sağlamak için aşağıdaki metodu kullanabiliriz:
    <?php 
         print_r( $_COOKIE ); // Kullanıcıya ait sitenizle alakalı tüm çerezler listelenecektir. 
    ?>
    Mevcut çerezlerin silinmesinde ise aşağıdaki metodu kullanabiliriz:
    <?php 
         setcookie( "language", "tr", time() - 3600 ); // çerez 1 saatten fazla geçmiş olacaktır. 
    ?>

    ]]>
    Php de dosya işlemleri http://yazilimdersi.info/makaleler/detay/29/php-de-dosya-islemleri Thu, 07 Aug 2014 00:00:00 +0000 mstfchelik 1. Dosya açılması: 
    Dosyaların açılmasında fopen() metodu kullanılmaktadır. Bu metodda iki parametre fopen(dosya adı, dosya açma amacı ) bulunmaktadır. İlk parametre olan dosya adı parametresi sayesinde açılması hedeflenen dosyanın ismi yazılmaktadır ve bu alan zorunludur. İkinci parametrede ise dosyanın ne amaçla kullanılacağını belirlemede kullanılmaktadır. Bu alana "r","w","a" değiskenleri getirilebilinebilir. 
    r -> sadece dosyayı okumak için
    w -> sadece dosyaya yazmak için
    a -> hem okumak hem yazmak için
    dosyanın açıldığını belirlemede kullanılmaktadır.]]>
    Php de include ifadesi http://yazilimdersi.info/makaleler/detay/28/php-de-include-ifadesi Thu, 07 Aug 2014 00:00:00 +0000 mstfchelikinclude ve require komutları Php programlamada en önemli kullanılan kaynaklardır. Bu komutlar sayesinde tekrarlı olarak  kullanılacak verilerin bir dosyada tutulmasını ve her tekrarlanması gerektigi dosyada hazırlanmış dosyanın include edilmesi saglanmaktadır. Yani örnegin herhangi bir websitesi yaptıgınızda bu sitenin header ve footer alanları bulunmaktadır. Bu alanların tümünü ayrı ayrı tüm php dosyalarının icerisine eklemek yerine header.php ve footer.php isimli dosyalar oluşturup diğer php dosyalarına eklemeniz daha kullanışlı olacaktır. Cünkü ilerde header ve footerde yapılmasını istediginiz herhangi bir güncelleme oldugunda diger tüm eklenmis dosyalara girip o alanları da güncellemeniz gerekecektir. Ancak include fonsiyonu sayesinde sadece header.php ve footer.php dosyalarında düzenlemeleri yapmanız yeterli olacaktır.
    require ve include arasındaki en önemli farklılık include metodu kullanıldıgında herhangi bir hata ile karsılasıldıgında kodunuz çalışmaya devam eder uyarı verse bile. Ancak require kullanıldığında herhangi bir hata ile karşılaşıldığınıda kodunuz çalışmayı durdurur. Sorun giderilmeden tekrar çalışır hale gelmez. Kullanılış yönü ise birbirinin aynısıdır.
    Örnek verecek olursak; 
    Bir website oluşturdugumuzda temelde kullanılan header.php, main.php ve footer.php dosyalarını hazırlayalım.
    <?php
            echo "<html>
                    <head>
                      <title>YazılımDersi.info</title>
                    </head>
                  <body>";
    ?>
    <?php
            echo "Test Mesajı";
    ?>
    <?php
            echo "</body></html>"; 
    ?>

    Bu üç dosyayı birleştirip anasayfa olarak kabul ettiğimiz index.php dosyasına aşağıdaki şekilde yazalım:
    <?php
            include("header.php");
            include("main.php");
            include("footer.php"); 
    ?>
    

    Bu işlemin sonrasında sitenize ait kaynak kodu incelediğinizde aşağıdaki şekilde bir mesaj ile karşılaşacaksınız :
    <html>
      <head>
        <title>YazilimDersi.info
      </head>
      <body>
        Test Mesajı
      </body>
    </html>  
    
    ]]>
    Php de tarih ve saat http://yazilimdersi.info/makaleler/detay/27/php-de-tarih-ve-saat Thu, 07 Aug 2014 00:00:00 +0000 mstfchelikdate() fonksiyonu ile alabiliriz. date fonskiyonu iki parametre alabilmektedir date(biçim,zaman damgası) olarak. İlk parametre olan biçim, kullanılacak olan zamanın nasıl formatta getirilmesi gerektiğini belirlemede kullanılmaktadır. İkinci parametre olan zaman damgası ise tanımlanmış herhangi bir zaman diliminin formatlanarak gösteriminde kullanılmaktadır. Bu değer ise time() fonksiyonuna uygun formatta ayarlanmaktadır. Örnek verecek olursak;
    <?php
            date('d.m.Y H:i'); // d->(gün) m->ay Y->yıl H->saat i->dakikaya karşılık gelmektedir.
            Çıktı olarak ise aşağıdaki sonuç elde edilmektedir:
            14.08.2014 01:54
    ?> 
    
    Zaman damgası kullanılarak yapılan çalışmaya örnek olarak ise aşağıdaki kodlama kullanılabilir.
    <?php 
            echo time(); // o anki zaman dilimini UNIX zaman dilimine uygun şekilde gösterir 141611541 gibi. 
            echo date("d/m/Y H:i:s", time()); // Bu kod ise mevcut zaman dilimini belirlenen formatta gösterir.
            13/05/2014 11:10:04 gibi 
    ?>
    Ayrıca mktime() fonksiyonu kullanılarak mevcut zaman diliminden 1 gün,2 hafta,9 yıl önceye veya sonraya gitmenizi sağlayabilmektedir. Örneğin bulundugunuz günden 2 gün öncesini ekrana yazdıralım:
     
    <?php 
            $ikigunonce = mktime(0,0,0,date("m"),date("d")-2,date("Y"));         
            echo date("d/m/Y G:i:s", $ikigunonce); // İki gün önceki zamanı verir. 
    ?>
    Datanın formatlanmasında kullanılan biçimlere ait harfler aşağıdaki şekilde anlamlaştırılmıştır.
    Aşağıdaki karakterler biçim değiştirge dizgesi içinde tanınır.
    biçim karakteri Açıklama Örnek sonuç
    Gün --- ---
    d Ay günlerinin sıfır dolgulu iki haneli gösterimi 01'den 31'e
    D Ay günlerinin üç harfli metinsel gösterimi Pzt'den Paz'a
    j Ay günlerinin sıfır dolgusuz gösterimi 1'den 31'e
    l (küçük 'L' harfi) Hafta günlerinin tam metinsel gösterimi Pazar'dan Cumartesi'ye
    N Hafta günlerinin ISO-8601 standardında sayısal gösterimi (PHP 5.1.0'da eklenmiştir) 1'den (Pazartesi için) 7'ye (Pazar için)
    S Ay günleri için 2 karakterli İngilizce sıralama ekleri st, nd, rd ya da th. j ile uyumlu çalışmaktadır.
    w Hafta günlerinin sayısal gösterimi 0'dan (Pazar için) 6'ya (Cumartesi için)
    z Yılın günleri (0'dan başlar) 0'dan 365'e
    Hafta --- ---
    W ISO-8601 standartına göre yılın hafta numarası, hafta başlangıcı Pazartesi'dir (PHP 4.1.0 sürümüyle eklenmiştir) Örneğin: 42 (Yılın 42'inci haftası)
    Ay --- ---
    F Ayın tam metinsel gösterimi, Ocak ya da Mart gibi January'den December'a
    m Ayın sıfır dolgulu sayısal gösterimi 01'den 12'ye
    M Ayın üç karakterli, metinsel kısa gösterimi Jan'dan Dec'e kadar
    n Ayın sıfır dolgusuz sayısal gösterimi 1'den 12'ye kadar
    t Belirtilen ayın gün sayısı 28'den 31'e
    Yıl --- ---
    L Artık yıl olduğunda Eğer artık yılsa 1, değilse 0.
    o ISO-8601 standardı yıl numarası. ISO hafta numaralarının (W) ait olduğu yılın gösterilmesi dışında Y ile aynı değere sahiptir. (PHP 5.1.0 sürümünde eklenmiştir) Örnekler: 1999 ya da 2003 gibi
    Y Yılın 4 haneli sayısal, tam gösterimi Örnekler: 1999 ya da 2003 gibi
    y Yılın iki haneli gösterimi Örnekler: 99 ya da 03 gibi
    Saat --- ---
    a Küçük harfli öğleden önce ve öğleden sonra am ya da pm
    A Büyük harfli öğleden önce ve öğleden sonra AM ya da PM
    B Swatch İnternet saati 000'dan 999'a
    g Saatin, 12-saatlik sıfır dolgusuz gösterimi 1'den 12'ye
    G Saatin, 24-saatlik sıfır dolgusuz gösterimi 0'dan 23'e
    h Saatin, 12-saatlik sıfır dolgulu gösterimi 01'den 12'ye
    H Saatin, 24-saatlik sıfır dolgulu gösterimi 00'dan 23'e
    i Sıfır dolgulu dakika gösterimi 00 ile 59 arasında
    s Sıfır dolgulu saniye gösterimi 00 ile 59 arasında
    u Mikrosaniye (PHP 5.2.2 sürümüyle eklenmiştir) Örneğin: 654321
    Zaman dilimi --- ---
    e Zaman dilimi belirteci (PHP 5.1.0 sürümüyle eklenmiştir) Örnekler: UTC, GMT, Europe/Istanbul
    I (büyük ı) Yaz saati uygulaması var mı? Varsa 1, yoksa 0.
    O Saat olarak Greenwich zamanı (GMT) farkı Örneğin: +0200
    P Saat ve dakika olarak Greenwich zamanı (GMT) farkı (PHP 5.1.3 sürümüyle eklenmiştir) Örneğin: +02:00
    T Zaman dilimi kısaltması Örnekler: EST, EET gibi
    Z Saniye cinsinden saat farkı. UTC'nin batısı daima negatif, doğusu ise daima pozitif değerlidir. -43200'den 50400'e

    ]]>
    Ubuntu da Wordpress kurulumu http://yazilimdersi.info/makaleler/detay/26/ubuntu-da-wordpress-kurulumu Sat, 02 Aug 2014 00:00:00 +0000 mstfchelikUbuntu'da Linux, Apache, MySQL, Php (LAMP) kurulumu)
    1. Wordpress dosyalarının indirilmesi: 
    Öncelikle wordpress sitesinden dosyaları aşağıda bulunan komut ile indiriniz:
    wget http://wordpress.org/latest.tar.gz
     Bu komut wordpress sitesiyle alakalı son ziplenmiş ve tarlanmış dosyayı home dizinine indirecektir. Aşağıda bulunan komut ile ziplenmiş dosya unzip hale getirilecektir.
    tar -xzvf latest.tar.gz
    2. Wordpress veritabanı ve kullanıcısının oluşturulması: 
    Wordpress dosyasının home dizininde açılması üzerine wordpress isimli bir klasör oluşacaktır. Sırada wordpress için veritabanı ve yeni kullanıcı oluşturacağız. Öncelikle root kullanıcısı ile MySQL e giriş yapalım:
    mysql -u root -p
     Şifre girilmesiyle birlikte wordpress isimli veritabanı oluşturulmasına geldi sıra. Aşağıda bulunan komut ile veritabanı oluşturulmaktadır.
    CREATE DATABASE wordpress;
    Query OK, 1 row affected (0.00 sec)
     Yeni veritabanının oluşturulmasının ardından yeni kullanıcı oluşturmada sıra. Bunu da aşağıda bulunan komut ile gerçekleştirebilmekteyiz: 
    CREATE USER wordpressuser@localhost; 
    Query OK, 0 rows affected (0.00 sec)
    Yeni oluşturulan kullanıcının şifresini setleyelim:
    SET PASSWORD FOR wordpressuser@localhost= PASSWORD("sifre"); 
    Query OK, 0 rows affected (0.00 sec)
    Yeni kullanıcının oluşturulması ve şifresinin ayarlanmasının ardından kullanıcının erişebileceği veritabanlarının ayarlanmasını gerçekleştirelim. Bu komut olmadan wordpress sitesine erişim olamaz:
    GRANT ALL PRIVILEGES ON wordpress.* TO wordpressuser@localhost IDENTIFIED BY 'sifre'; 
    Query OK, 0 rows affected (0.00 sec)
    Yukarıda bulunan komutla wordpressuser isimli kullanıcının sadece wordpress veritabanına erişebileceğine dair yetkiyi verdik. Yetkilendirmelerle alakalı yapılan düzenlemeler aşağıda bulunan komutla aktif hale getirilebilmektedir: 
    FLUSH PRIVILEGES; 
    Query OK, 0 rows affected (0.00 sec)
    exit komutu ile de MySQL programından çıkış yapınız.
    3. Wordpress konfigürasyonlarının ayarlanması: 
    Wordpress dosyasının home dizininde açılması üzerine wordpress isimli bir klasör oluşacaktır. Sırada wordpress için veritabanı ve yeni kullanıcı oluşturacağız. Öncelikle root kullanıcısı ile MySQL e giriş yapalım:
    mysql -u root -p
     Şifre girilmesiyle birlikte wordpress isimli veritabanı oluşturulmasına geldi sıra. Aşağıda bulunan komut ile veritabanı oluşturulmaktadır.
    CREATE DATABASE wordpress;
    Query OK, 1 row affected (0.00 sec)
     Yeni veritabanının oluşturulmasının ardından yeni kullanıcı oluşturmada sıra. Bunu da aşağıda bulunan komut ile gerçekleştirebilmekteyiz: 
    CREATE USER wordpressuser@localhost; 
    Query OK, 0 rows affected (0.00 sec)
    Yeni oluşturulan kullanıcının şifresini setleyelim:
    SET PASSWORD FOR wordpressuser@localhost= PASSWORD("sifre"); 
    Query OK, 0 rows affected (0.00 sec)
    Yeni kullanıcının oluşturulması ve şifresinin ayarlanmasının ardından kullanıcının erişebileceği veritabanlarının ayarlanmasını gerçekleştirelim. Bu komut olmadan wordpress sitesine erişim olamaz:
    GRANT ALL PRIVILEGES ON wordpress.* TO wordpressuser@localhost IDENTIFIED BY 'sifre'; 
    Query OK, 0 rows affected (0.00 sec)
    Yukarıda bulunan komutla wordpressuser isimli kullanıcının sadece wordpress veritabanına erişebileceğine dair yetkiyi verdik. Yetkilendirmelerle alakalı yapılan düzenlemeler aşağıda bulunan komutla aktif hale getirilebilmektedir: 
    FLUSH PRIVILEGES; 
    Query OK, 0 rows affected (0.00 sec)
    exit komutu ile de MySQL programından çıkış yapınız.
    4. Wordpress konfigürasyonlarının kurulumu: 
    Wordpress ile alakalı konfigürasyonun kopyalanması ve yeni oluşturulan wordpress dizini altına aşağıda bulunan komutla kopyalanmasıdır:
    cp ~/wordpress/wp-config-sample.php ~/wordpress/wp-config.php
     Sonrasında wordpress configürasyonun dosyasını açınız:
    sudo nano ~/wordpress/wp-config.php
     Bu dosyada bulunan veritabanı ismi, kullanıcı ismi ve şifresinin değiştirilmesi gerekmektedir. Sonrasında dosyayı kayıt edip çıkınız: 
    // ** MySQL settings - You can get this info from your web host ** // 
    /** The name of the database for WordPress */
     
    define('DB_NAME', 'wordpress'); 
    
    /** MySQL database username */ 
    define('DB_USER', 'wordpressuser'); 
    
    /** MySQL database password */ 
    define('DB_PASSWORD', 'sifre');
    
    5. Wordpress dosyalarının kopyalanması: 
    Wordpress dosyalarının /var/www dizini altına taşınması gerekmektedir:
    sudo rsync -avP ~/wordpress/ /var/www/
     Son olarak wordpress dosyaları ile alakalı dosya izinlerinin ayarlanması gerekmektedir. Kopyalanan web dizinine girelim: 
    cd /var/www/
     Dosyalara apache kullanıcısının erişimi için izinlerin verilmesi gerekmektedir : 
    sudo chown yenikullaniciadi:www-data /var/www -R 
    sudo chmod g+w /var/www -R
    
    Wordpress kurulumunda Php modüllerinde sadece php-gd yüklenmesi gerekmektedir: 
    sudo apt-get install php5-gd
    
    6. Wordpress sitesinin kurulumu: 
    Wordpress sitesinin kurulumu için serverinizle alakalı IP adresi+"/wp-admin/install.php" şeklinde yazılması gerekmektedir:
    http://149.86.54.10/wp-admin/install.php

    ]]>
    CentOS da kullanıcı işlemleri http://yazilimdersi.info/makaleler/detay/25/centos-da-kullanici-islemleri Sat, 02 Aug 2014 00:00:00 +0000 mstfchelik 1. Yeni kullanıcı oluşturulması: 
    CentOS serverde aşağıda yazılı olan komut ile yeni kullanıcı eklenmesi sağlanmaktadır. Tek yapmanız gereken "yenikullaniciadi" alanını belirlediginiz kullanıcı adı ile değiştirmenizdir:
    sudo adduser yenikullaniciadi
    Yeni kullanıcı girilmesi ile birlikte mevcut kullanıcının şifresini girmek için aşağıda bulunan komutu terminale giriniz:
    sudo passwd yenikullaniciadi
    Tebrikler yeni kullanıcı oluşturulması ile alakalı işlem tamamlanmış oldu. root olarak girilmiş olan sistemden exit yazarak çıkabilirsiniz. Yeni kullanıcı adı ve şifrenizle sisteme giriş yapabilirsiniz artık.
    2. Yeni oluşturulan kullanıcıya root yetkisinin verilmesi: 
    CentOS serverde yeni kullanıcı oluşturulduktan sonra, bu kullanıcının root seviyesinde yetkilere sahip olması için aşağıda bulunan komutun girilmesi gerekmektedir:
    sudo /usr/sbin/visudo
    Bu komutun ardından istenilen kullanıcının root seviyesinde olması için aşağıda bulunan satırın dosyaya eklenmesi gerekmektedir: 
    ## Allow root to run any commands anywhere 
    root ALL=(ALL) ALL 
    yenikullaniciadi ALL=(ALL) ALL
    'Shift' ZZ tuşuna basarak dosyadan çıkıp değişikliğin kayıt edilmesini sağlayın.
     
    3. Kullanıcının silinmesi: 
    CentOS serverde kullanmadığınız ve daha önceden oluşturduğunuz kullanıcılara basit bir şekilde tek satır kod ile silebilirsiniz:
    sudo userdel yenikullaniciadi
    Kullanıcıya ait tüm bilgilerin silinmesi için tek yapmanız gereken -r ifadesinin yazılmasıdır: 
    sudo userdel -r yenikullaniciadi
     
    ]]>
    Ubuntu da kullanıcı işlemleri http://yazilimdersi.info/makaleler/detay/24/ubuntu-da-kullanici-islemleri Sat, 02 Aug 2014 00:00:00 +0000 mstfchelik 1. Yeni kullanıcı oluşturulması: 
    Ubuntu serverde aşağıda yazılı olan komut ile yeni kullanıcı eklenmesi sağlanmaktadır. Tek yapmanız gereken "yenikullaniciadi" alanını belirlediginiz kullanıcı adı ile değiştirmenizdir:
    sudo adduser yenikullaniciadi
     Bu komutu girmenizle birlikte şifre sorulacaktır. Şifrenin girilmesinden sonra kullanıcı bilgilerini sunmanız istenecektir. Bu alan zorunlu olmadıgndan entere basarak geçebilirsiniz. Son olarak işlemleri onayladıgınız ile alakalı Y (Yes) harfine tıklayıp onay vermeniz gerekmektedir. Tebrikler yeni kullanıcı oluşturulması ile alakalı işlem tamamlanmış oldu. root olarak girilmiş olan sistemden exit yazarak çıkabilirsiniz. Yeni kullanıcı adı ve şifrenizle sisteme giriş yapabilirsiniz artık.
    2. Yeni oluşturulan kullanıcıya root yetkisinin verilmesi: 
    Ubuntu serverde yeni kullanıcı oluşturulduktan sonra, bu kullanıcının root seviyesinde yetkilere sahip olması için aşağıda bulunan komutun girilmesi gerekmektedir:
    sudo /usr/sbin/visudo
    Bu komutun ardından istenilen kullanıcının root seviyesinde olması için aşağıda bulunan satırın dosyaya eklenmesi gerekmektedir: 
    # User privilege specification 
    root ALL=(ALL:ALL) ALL 
    yenikullaniciadi  ALL=(ALL:ALL) ALL
    'X' tuşuna basarak dosyadan çıkıp 'Y' tuşu ile yapılan değişikliğin kayıt edilmesini sağlayın.
     
    3. Kullanıcının silinmesi: 
    Ubuntu serverde kullanmadığınız ve daha önceden oluşturduğunuz kullanıcılara basit bir şekilde tek satır kod ile silebilirsiniz:
    sudo userdel yenikullaniciadi
    Kullanıcıya ait dosyaların silinmesi ile birlikte kullanıcılar tamamen sistemden silinmiş olacaktır: 
    sudo rm -rf /home/yenikullaniciadi

    ]]>
    Ubuntu da Git kurulumu http://yazilimdersi.info/makaleler/detay/23/ubuntu-da-git-kurulumu Sat, 02 Aug 2014 00:00:00 +0000 mstfchelik 1.a Apt-get ile Git programının yüklenmesi: 
    Ubuntu serverde apt-get kullanılarak git programının kurulumu oldukça kolay ve hızlıdır. Aşağıda bulunan kodlama ile kurulum işlemi gerçekleştirilmektedir:
    sudo apt-get install git-core
     İndirme işleminin bitmesiyle birlikte git programının kurulumuna hazır haldeyiz.
    1.b Kaynak koddan Git programının yüklenmesi: 
    İkinci yöntemde eğer direkt kaynak dosya üzerinden kurulum yapılmak isteniyorsa bu yöntem izlenmektedir. Ayrıca bu yöntem sayesinde istenilen versiyondaki git kurulumu gerçekleştirilebilmektedir. Aşağıda bulunan kodlama ile yüklü olan programlarla alakalı yeni güncellemeler yüklenmiş olacaktır:
    sudo apt-get update
     Git kurulumundan önce gereksinimlerin giderilmesi için aşağıda bulunan kodlama kullanılmaktadır: 
    sudo apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev build-essential
     Gereksinimlerin yüklenmesinin ardından git programı ile alakalı son versiyonun indirilmesi sağlanmalıdır. Git ile alakalı tüm versiyonlara şu linkten erişebilirsiniz: 
    wget https://git-core.googlecode.com/files/git-1.8.5.5.tar.gz
     Git dosyasının indirilmesinin ardından tarlanmış dosyanın açılması ve mevcut pathe girilmesi gerekmektedir:  
    tar -zxf git-1.8.5.5.tar.gz
    cd git-1.8.5.5.tar.gz
     Eğer git programı ile alakalı güncellemelerin yüklenmesini istiyorsanız, aşağıdaki kod parçacığını kullanabilirsiniz:
    git clone git://git.kernel.org/pub/scm/git/git.git
    2. Git kurulumu: 
    Git pogramının yüklenmesinden sonra git kurulumunda kullanılacak olan email ve isim bilgilerinin konfigürasyon dosyalarına girilmesi gerekmektedir. Yani sizin tarafından git kaynağına herhangi bir dosya gönderildiğinde hangi isim ve email adresinin kullanıldığı belirlenmeli ve config dosyalarına girilmelidir 
    sudo nano ~/.gitconfig
     gitconfig dosyasının içeriğine eriştikten sonra aşağıda bulunan kod satırlarını yazmanız gerekmektedir:
    git config --global user.name "Kullanıcı Adınız"
    git config --global user.email [email protected]
     config dosyasına girdiğiniz tüm ayarları aşağıdaki kodlama ile gözlemleyebilirsiniz: 
    git config --list
     Bu komutun çıktısında ise şu şekilde içerikler görüntülenecektir.
    [master 0d9d21d] initial project version 
     Committer: root 
    Your name and email address were configured automatically based 
    on your username and hostname. Please check that they are accurate. 
    You can suppress this message by setting them explicitly: 
    
        git config --global user.name "Your Name" 
        git config --global user.email [email protected]
    
     After doing this, you may fix the identity used for this commit with: 
       
        git commit --amend --reset-author

    ]]>
    CentOS 6 da Linux, Apache, MySQL, Php (LAMP) kurulumu http://yazilimdersi.info/makaleler/detay/22/centos-6-da-linux-apache-mysql-php-(lamp)-kurulumu Sat, 02 Aug 2014 00:00:00 +0000 mstfchelikLinux Apache MySQL Php programlarının baş harfleri kullanılarak oluşturulmuştur. CentOS tabanlı sisteminizde izlenecek adımlar sırasıyla şu şekildedir: 
    1. Apache kurulumu: 
    Apache server açık kaynak kodlu olup dünya genelinde kullanılan en kullanışlı webserver olarak tanımlanmaktadır. Apache kurulumu için CentOSda terminali açın ve aşağıdaki kodu girin:
    sudo yum install httpd
     Ayrıca Apache kurulumunun ardından aşağıdaki kodlama ile Apache'nin başlatılmasını sağlayın:
    sudo service httpd start
    Bu işlemden sonra serverinize ait IP adresini browserinizde yazın http://145.67.89.10 gibi ve karşınızda "It works!" ibareli bir sayfa görmeniz gerekmektedir.
    2. Serverin IP adresinin bulunması: 
    CentOS serverinize ait IP adresini bulmak için aşağıda yazılı olan komutu terminale yazınız :
    ifconfig eth0 | grep inet | awk '{ print $2 }'
    3. MySQL kurulumu: 
    MySQL, projelerle alakalı bilgilerin tutulduğu ve organize edilebildiği güçlü veritabanı yönetim sistemidir. MySQL kurulumu için aşağıdaki komutu terminale giriniz:
    sudo yum install mysql-server
    sudo service mysqld start
    Kurulum süresince MySQL iki kere izin talebinde bulunacaktır. Bu durumlarda Y(Yes) harfini girerek izinlere olumlu cevap verilmesi gerekmektedir. Bunların ardından MySQL kurulumu gerçekleştirilecektir. Kurulum işleminin ardından root şifresinin girilmesi için aşağıda bulunan komutun girilmesi gerekmektedir: 
    sudo /usr/bin/mysql_secure_installation
    Yukarıda bulunan komutun girilmesi ile birlikte terminal az önce setlediğiniz root şifresini isteyecektir. Eğer herhangi bir şifre setlemediyseniz, ENTER tuşuna basmanız gerekmektedir. Terminalde oluşacak olan yazılar şu şekildedir.
    Enter current password for root (enter for none):
    
    OK, successfully used password, moving on...
    Bu işlemin ardından terminal mevcut root şifresini değiştirmek isteyip istemediğiniz ile alakalı sorular soracaktır. N (No) harfine basarak bu soruyu atlayabilirsiniz ve bir sonraki adıma geçebilirsiniz. Sonrasında gelen tüm sorulara Y (Yes) harfine basmanız yeterli olacaktır. Bu işlemlerle birlikte MySQL tüm örnek verileri sisteme girecektir ve yeni değişiklikleri uygulayacaktır.
     
    By default, a MySQL installation has an anonymous user, allowing anyone 
    to log into MySQL without having to have a user account created for 
    them. This is intended only for testing, and to make the installation 
    go a bit smoother. You should remove them before moving into a 
    production environment. 
    
    Remove anonymous users? [Y/n] y 
    ... Success! 
    
    Normally, root should only be allowed to connect from 'localhost'. This 
    ensures that someone cannot guess at the root password from the network. 
    
    Disallow root login remotely? [Y/n] y 
    ... Success! 
    
    By default, MySQL comes with a database named 'test' that anyone can 
    access. This is also intended only for testing, and should be removed 
    before moving into a production environment. 
    
    Remove test database and access to it? [Y/n] y 
    
    - Dropping test database... 
    ... Success! 
    - Removing privileges on test database... 
    ... Success! 
    
    Reloading the privilege tables will ensure that all changes made so far 
    will take effect immediately. 
    
    Reload privilege tables now? [Y/n] y 
    ... Success! 
    
    Cleaning up...
    MySQL kurulumu tamamen bitirilmiş oldu. Şimdi sırada Php kurulumu ile alakalı izlenmesi gereken adımlara geldi. 
    4. Php kurulumu: 
    Php dinamik içerikli site kurulumunda kullanılan en yaygın web programlama dilidir.Tamamen açık kaynak kodludur. Php kurulumu için terminale aşağıda bulunan komutu giriniz:
    sudo yum install php php-mysql
    5. Php modül kurulumu: 
    Php dili tamamen açık kaynak kodlu olduğundan farklı kurum veya kişiler tarafından dinamik modüllerin ve kütüphanelerin yazııldığı bir dildir. Birçok işlemin modüller üzerinden götürüldüğü bir dil olan Php de sizin için gerekli olan modüllerin yüklenmesi gerekmektedir. Örneğin memcache kullacaksanız memcache ile alakalı modülün kurulumu veya mysql bağlantısı kurulacaksa mysql modülü yüklenmelidir. Aşağıda bulunan komutla php için hazırlanmış tüm modüllerin listesini görebilirsiniz:
    yum search php-
    Terminal tüm php modülleri aşağıdaki gibi listeleyecektir: 
    php-bcmath.x86_64 : A module for PHP applications for using the bcmath library 
    php-cli.x86_64 : Command-line interface for PHP 
    php-common.x86_64 : Common files for PHP 
    php-dba.x86_64 : A database abstraction layer module for PHP applications 
    php-devel.x86_64 : Files needed for building PHP extensions 
    php-embedded.x86_64 : PHP library for embedding in applications 
    php-enchant.x86_64 : Human Language and Character Encoding Support 
    php-gd.x86_64 : A module for PHP applications for using the gd graphics library 
    php-imap.x86_64 : A module for PHP applications that use IMAP
    [...]
    Gerekli olan modülleri listelenenler arasından seçip aşağıda bulunan komut ile indirebilirsiniz:
    sudo yum install 'modülün ismi'
    sudo yum install php-cli.x86_64  #php icin komut satırının ayarlanmasını saglar.
    Birçok Php modülünü aynı anda boşluklar girerek kurabilirsiniz. Böylelikle Php kurulumu ile alakalı da adımlarda tamamlanmış oldu. 
    6. Serverinizde örnek Php kodunun çalıştırılması: 
    LAMP kurulumunun tamamlanmasıyla birlikte sistemin stabil çalışıp çalışmadığının kontrolü için örnek Php dosyası oluşturalım ve serverimizde inceleyelim. Php dosyasının oluşturulması için aşağıda bulunan komutu girip info.php isimli bir dosya oluşturalım:
    sudo nano /var/www/html/info.php
    Aşağıda yazılı olan kod parçacıklarını yeni oluşturulan info.php dosyasına giriniz:
    <?php
        phpinfo();
    ?>
    Bu satırları girmenizin ardından dosyayı kayıt edip çıkınız. Apache nin tekrardan kapatılıp açılması ile birlikte yapılan tüm düzenlemelerin aktif hale getirilmesini sağlayın:
     
    sudo chkconfig httpd on
    sudo chkconfig mysqld on
    Bu işlemin ardından serverinizin http://+serverin IP Adresi + /info.php (http://145.67.89.10/info.php adresi gibi) pathini browserinize yazıp örnek php sonuçlarını görebilirsiniz.
     
    ]]>
    Ubuntu da Ruby on Rails kurulumu http://yazilimdersi.info/makaleler/detay/21/ubuntu-da-ruby-on-rails-kurulumu Sat, 02 Aug 2014 00:00:00 +0000 mstfchelik
    1. RVM(Ruby Version Manager) kurulumu: 
    Ruby kurulumu ile alakalı çalışmalara başlamadan önce sistemimizde kurulu olan programlamlarla alakalı herhangi bir güncellemenin olup olmadığını aşağıda bulunan kodu parçacığı ile kontrol edelim:
    sudo apt-get update
    
    Bu işlemden sonra RVM(Ruby Version Manager) sisteminin kurulumuna geçebiliriz. RVM farklı ruby versiyonlarını barındıran bir sistemdir ve rahatlıkla versiyonlar arasında geçiş yapılmasına imkan sunmaktadır. Ancak bizler en son Ruby sürümünü kullanacakmış gibi düşünüp indirmelerimizi bu çerçevede gerçekleştireceğiz. Eğer sisteminizde curl komutu aktif halde değilse aşağıda bulunan kodlama ile indirebilir ve aktif hale getirebilirsiniz. Programların indirilmesinde curl programından yararlanacağız:
    sudo apt-get install curl
    
    RVM programının kurulumu içinse şu kodu terminale yazmanız gerekmektedir: 
    \curl -L https://get.rvm.io | bash -s stable
    
    RVM programını indirmenizin ardından şimdi yüklenmesinde sıra. Ancak bu işlemden önce mevcut shell sessionuzun yenilenmesi için terminali kapatıp açmanız gerekmektedir: 
    source ~/.rvm/scripts/rvm
    
    Bu programın kurulumu öncesinde bazı gereksinimler bulunabilir. Bu gereksinimlerin giderilmesi adına aşağıda bulunan komutu kullanmanız gerekmektedir. Bu komut sayesinde gereksinimlerin tümü otomatik olarak RVM programı üzerinden giderilecektir.
    rvm requirements
    
    Gereksinimlerin indirilmesi sırasında root şifresi terminal tarafından sorulabilir. Şifreyi girmenizle birlikte tüm gereksinimler indirilmiş ve giderilmiş olacaktır. Gereksinimlerin giderilmesi sırasında bazı paketlerin olmadığı ile alakalı uyarılarla karşılaşabilirsiniz. Bu durumda paketlerin direkt source kod üzerinden çalıştırılması için şu linkten yardım alabilirsiniz.
    2. Ruby kurulumu: 
    RVM kurulumunun tamamlanmasının ardında bu sistem üzerinden Ruby kurulumu oldukça basittir. Tek yapmanız gereken aşağıda bulunan kodu terminalde çalıştırmanızdır:
    rvm install ruby
    
    Komutun çalıştırılması ile birlikte Ruby'nin son versiyon indirilmiştir. RVM üzerinden birden çok versiyon bulunduğundan sistemimize hangi Ruby versiyonu kullandığımızla alakalı bilgilendirme yapmamız gerekmektedir. Aşağıda bulunan komut bu işlemi sağlamaktadır:
    rvm use ruby --default
    3. RubyGems kurulumu: 
    Ruby On Rails kurulumundan önce gerekli olan tüm programların yüklü olduğundan emin olmamız gerekmektedir. Bunlardan en önemlileri ise gems olarak adlandırılan library havuzlarıdır. Gem lerin yüklenmesine RVM programı üzerinden devam edebiliriz:
    rvm rubygems current
    4. Rails kurulumu: 
    Gem programının kurulumu ile birlikte rails programının kurulumuna da geçebiliriz:
    gem install rails
    Bu işlem uzun sürebilmektedir. İşlemin sonuçlanması ile birlikte artık Ubuntu serverinizde Ruby on Rails sistemine sahip olacaksınız.
     
    ]]>
    Ubuntu da Linux, Apache, MySQL, Php (LAMP) kurulumu http://yazilimdersi.info/makaleler/detay/20/ubuntu-da-linux-apache-mysql-php-(lamp)-kurulumu Fri, 01 Aug 2014 00:00:00 +0000 mstfchelikLinux Apache MySQL Php programlarının baş harfleri kullanılarak oluşturulmuştur. Ubuntu tabanlı sisteminizde izlenecek adımlar sırasıyla şu şekildedir: 
    1. Apache kurulumu: 
    Apache server açık kaynak kodlu olup dünya genelinde kullanılan en kullanışlı webserver olarak tanımlanmaktadır. Apache kurulumu için Ubuntuda terminali açın ve aşağıdaki kodu girin:
    sudo apt-get update
    sudo apt-get install apache2
    Bu işlemden sonra serverinize ait IP adresini browserinizde yazın http://145.67.89.10 gibi ve karşınızda "It works!" ibareli bir sayfa görmeniz gerekmektedir.
    2. Serverin IP adresinin bulunması: 
    Ubuntu serverinize ait IP adresini bulmak için aşağıda yazılı olan komutu terminale yazınız :
    ifconfig eth0 | grep inet | awk '{ print $2 }'
    3. MySQL kurulumu: 
    MySQL, projelerle alakalı bilgilerin tutulduğu ve organize edilebildiği güçlü veritabanı yönetim sistemidir. MySQL kurulumu için aşağıdaki komutu terminale giriniz:
    sudo apt-get install mysql-server libapache2-mod-auth-mysql php5-mysql
    Kurulum süresince MySQL default olarak setlenen root kullanıcısı için şifre girilmesini soracaktır. root şifresini kurulum süresince setlemeseniz bile sonradan da bu işlemi gerçekleştirmek oldukça kolaydır. MySQL kurulumunun ardından gerekli aktivasyon için aşağıda bulunan kodu terminale girmeniz gerekmektedir: 
    sudo mysql_install_db
    Kuruluma ait işlemlerin bitmesi için aşağıda bulunan komutu terminale giriniz: 
    sudo /usr/bin/mysql_secure_installation
    Yukarıda bulunan komutun girilmesi ile birlikte terminal az önce setlediğiniz root şifresini isteyecektir. Eğer herhangi bir şifre setlemediyseniz, ENTER tuşuna basmanız gerekmektedir. Terminalde oluşacak olan yazılar şu şekildedir.
    Enter current password for root (enter for none):
    
    OK, successfully used password, moving on...
    Bu işlemin ardından terminal mevcut root şifresini değiştirmek isteyip istemediğiniz ile alakalı sorular soracaktır. N (No) harfine basarak bu soruyu atlayabilirsiniz ve bir sonraki adıma geçebilirsiniz. Sonrasında gelen tüm sorulara Y (Yes) harfine basmanız yeterli olacaktır. Bu işlemlerle birlikte MySQL tüm örnek verileri sisteme girecektir ve yeni değişiklikleri uygulayacaktır.
     
    By default, a MySQL installation has an anonymous user, allowing anyone 
    to log into MySQL without having to have a user account created for 
    them. This is intended only for testing, and to make the installation 
    go a bit smoother. You should remove them before moving into a 
    production environment. 
    
    Remove anonymous users? [Y/n] y 
    ... Success! 
    
    Normally, root should only be allowed to connect from 'localhost'. This 
    ensures that someone cannot guess at the root password from the network. 
    
    Disallow root login remotely? [Y/n] y 
    ... Success! 
    
    By default, MySQL comes with a database named 'test' that anyone can 
    access. This is also intended only for testing, and should be removed 
    before moving into a production environment. 
    
    Remove test database and access to it? [Y/n] y 
    
    - Dropping test database... 
    ... Success! 
    - Removing privileges on test database... 
    ... Success! 
    
    Reloading the privilege tables will ensure that all changes made so far 
    will take effect immediately. 
    
    Reload privilege tables now? [Y/n] y 
    ... Success! 
    
    Cleaning up...
    MySQL kurulumu tamamen bitirilmiş oldu. Şimdi sırada Php kurulumu ile alakalı izlenmesi gereken adımlara geldi. 
    4. Php kurulumu: 
    Php dinamik içerikli site kurulumunda kullanılan en yaygın web programlama dilidir.Tamamen açık kaynak kodludur. Php kurulumu için terminale aşağıda bulunan komutu giriniz:
    sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt
    Terminalin 2 kere sordugu sorulara Y ( Yes) harfine tıklamanızla birlikte kurulum işlemi gerçekleştirilecektir. Bu işlemin ardından Apache programına ait config dosyasına php ile alakalı default index.php yazısını girmemiz gerekebilir. Bu işlem için aşağıda bulunan komutu terminale giriniz:
    sudo nano /etc/apache2/mods-enabled/dir.conf
    Bu dosyayı açtığınızda içeriğinde index geçen satıra gidip en başına index.php girmeniz gerekmektedir. Bu işlem ile birlikte dosyanızın son hali şu şekilde olacaktır:
    <IfModule mod_dir.c> 
    
            DirectoryIndex index.php index.html index.cgi index.pl index.php index.xhtml index.htm 
    
    </IfModule>
    5. Php modül kurulumu: 
    Php dili tamamen açık kaynak kodlu olduğundan farklı kurum veya kişiler tarafından dinamik modüllerin ve kütüphanelerin yazııldığı bir dildir. Birçok işlemin modüller üzerinden götürüldüğü bir dil olan Php de sizin için gerekli olan modüllerin yüklenmesi gerekmektedir. Örneğin memcache kullacaksanız memcache ile alakalı modülün kurulumu veya mysql bağlantısı kurulacaksa mysql modülü yüklenmelidir. Aşağıda bulunan komutla php için hazırlanmış tüm modüllerin listesini görebilirsiniz:
    apt-cache search php5-
    Terminal tüm php modülleri aşağıdaki gibi listeleyecektir: 
    php5-cgi - server-side, HTML-embedded scripting language (CGI binary) 
    php5-cli - command-line interpreter for the php5 scripting language 
    php5-common - Common files for packages built from the php5 source 
    php5-curl - CURL module for php5 php5-dbg - Debug symbols for PHP5 
    php5-dev - Files for PHP5 module development 
    php5-gd - GD module for php5 
    php5-gmp - GMP module for php5 
    php5-ldap - LDAP module for php5 
    php5-mysql - MySQL module for php5 
    php5-odbc - ODBC module for php5 
    php5-pgsql - PostgreSQL module for php5 
    php5-pspell - pspell module for php5 
    php5-recode - recode module for php5 
    php5-snmp - SNMP module for php5 
    php5-sqlite - SQLite module for php5 
    php5-tidy - tidy module for php5 
    php5-xmlrpc - XML-RPC module for php5 
    php5-xsl - XSL module for php5 
    php5-adodb - Extension optimising the ADOdb database abstraction library 
    php5-auth-pam - A PHP5 extension for PAM authentication 
    [...]
    Gerekli olan modülleri listelenenler arasından seçip aşağıda bulunan komut ile indirebilirsiniz:
    sudo apt-get install 'modülün ismi'
    sudo apt-get install php5-mysql #mysql bağlantısını sağlayacak olan modülün kurulumunda kullanılacak komut
    Birçok Php modülünü aynı anda boşluklar girerek kurabilirsiniz. Böylelikle Php kurulumu ile alakalı da adımlarda tamamlanmış oldu. 
    6. Serverinizde örnek Php kodunun çalıştırılması: 
    LAMP kurulumunun tamamlanmasıyla birlikte sistemin stabil çalışıp çalışmadığının kontrolü için örnek Php dosyası oluşturalım ve serverimizde inceleyelim. Php dosyasının oluşturulması için aşağıda bulunan komutu girip info.php isimli bir dosya oluşturalım:
    sudo nano /var/www/info.php
    Aşağıda yazılı olan kod parçacıklarını yeni oluşturulan info.php dosyasına giriniz:
    <?php
        phpinfo();
    ?>
    Bu satırları girmenizin ardından dosyayı kayıt edip çıkınız. Apache nin tekrardan kapatılıp açılması ile birlikte yapılan tüm düzenlemelerin aktif hale getirilmesini sağlayın:
     
    sudo service apache2 restart
    Bu işlemin ardından serverinizin http://+serverin IP Adresi + /info.php (http://145.67.89.10/info.php adresi gibi) pathini browserinize yazıp örnek php sonuçlarını görebilirsiniz.
     
    ]]>
    Ubuntu da Apache Virtual Host kurulumu http://yazilimdersi.info/makaleler/detay/19/ubuntu-da-apache-virtual-host-kurulumu Fri, 01 Aug 2014 00:00:00 +0000 mstfchelikVirtual Host, aynı IP üzerinden farklı domainlerde sitelerin çalıştırılmasına imkan sunan bir yapıdır. Virtual host kullanılarak tek bir IP ile farklı domainler ilişkilendirilip aynı makina üzerinden çalıştırılabilmemizi sağlamaktadır. Bu özellik aynı makina üzerinde farklı sistemlerin çalıştırıldığı birçok projede etkin olarak kullanılmaktadır. Bu özellik tamamen kurulu olan webserveriniz tarafından size sunulmaktadır. En güzel yanı ise virtual host tanımlanmasında herhangi bir sınırın bulunmamasıdır. Şimdi maddeler halinde Ubuntu serverinizde Apache kurulumu ve virtual host tanımlamaları hakkında bilgileri sizlere sunacağız.
    1. Apache kurulumu: 
    Ubuntu serverde apache kurulumu oldukça basittir. Aşağıda bulunan kod satırını command line(komut satırına) girmenizle birlikte gerekli kurulum gerçekleştirilecektir.
    sudo apt-get install apache2
    2. Yeni klasör oluşturunuz: 
    Apache kurulumunun ardından aşağıda bulunan komut ile virtual host tanımlayacağınız proje ile alakalı klasör oluşturmanız gerekmektedir.
    sudo mkdir -p /var/www/yazilimdersi.info/public_html
    mkdir: Yeni klasör oluşturmada kullanılmaktadır. Bu komutun ardına -p ekleyerek, oluşturulacak klasöre ait alt klasörlerinde otomatik olarak oluşturulmasını sağlamaktadır. Böylelikle her alt klasör için ayrı ayrı komutların yazılması engellenmiştir.
    3. Yeni klasörlere izinlerin belirlenmesi: 
    Yeni oluşturulan klasörlere kullanıcı izinlerinin belirlenmesi gerekmektedir. Bununla alakalı izinler aşağıdaki komutta tanımlanmıştır:
    sudo chown -R $USER:$USER /var/www/yazilimdersi.info/public_html
    Bu kodlama ile oluşturulan klasörlere ait izinler mevcut kullanıcıya atanmaktadır. -R ifadesi ile birlikte recursive olarak alt dizinlere ait izinlerinde bu kullanıcıya atanması sağlanmıştır. Ayrıca diğer tüm kullanıcıların bu klasörleri okuyabilme yetkisinin olması önemlidir. Bu işlem ise aşağıda bulunan kodlama ile sağlanabilmektedir.
    sudo chmod -R 755 /var/www
    4. Yeni klasörde sayfa oluşturulması: 
    Yeni oluşturulan klasörde sayfa oluşturulması ile alakalı kod aşağıdaki şekilde gerçekleştirilmektedir:
    sudo nano /var/www/yazilimdersi.info/public_html/index.html
    nano komutu ile index.html dosyanın içerisine girip aşağıda bulunan text girilmelidir. Sonrasında IP adresi Ubuntu serverimize yönlendirilmesi ve virtual host ayarlanması ile birlikte bu html icerik browserde görüntülenecektir.
    <html> 
        <head> 
            <title>www.yazilimdersi.info</title> 
        </head> 
        <body> 
            <h1>Virtual Host ile alakalı kurulum başarılı şekilde gerçekleştirildi.</h1> 
        </body> 
    </html>
    5. Yeni Virtual Host Dosyasının Oluşturulması: 
    Şimdi sırada Apache ile alakalı konfigürasyonların yapılmasına geldi. Aşağıda yapılan kodlama ile birlikte default olarak eklenen virtual host yazilimdersi.info domaini için yeniden kopyalanmaktadır:
    sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/yazilimdersi.info
    6. Yeni Virtual Hostun Aktif Hale Getirilmesi: 
    Yukarıda tanımlanan yeni virtual host dosyasını açalım:
    sudo nano /etc/apache2/sites-available/yazilimdersi.info
    Aşağıda bulunan kodlama ile birlikte virtual host oluşturulmasına başlayalım. ServerAdmin satırının altında ServerName satırını eklemeniz gerekmektedir. Bu satır ile birlikte Ubuntu serverinize yönlendirilecek olan domain ismini tanımlamış oluyorsunuz.
    ServerName yazilimdersi.info
    Eğer internet sitenize www ön başlıklı olarakta erişim yapılmasını istiyorsanız ServerAlias ifadesini kullanabilirsiniz.
    ServerAlias www.yazilimdersi.info
    Şimdi sırada bu domaine gelen isteklerin hangi dosya tarafından çalıştırılacağı ile alakalı kısma geldi. Yani bir kişi browserine yazilimdersi.info yazdığı anda gelen isteğin hangi klasör tarafından handle edileceği bilgisini vermemiz gerekmektedir. Bunun için ise DocumentRoot ifadesi kullanılmaktadır. Burada ilk maddeler oluşturduğumuz yeni virtual hosta ait dosya pathini yazmamız gerekmektedir:
    DocumentRoot /var/www/yazilimdersi.info/public_html
    Sonuçta yapılan eklemeler sonucunda oluşan yeni virtual host dosyası şu şekilde görünmelidir:
    <VirtualHost *:80> 
            ServerAdmin [email protected] 
            ServerName yazilimdersi.info 
            ServerAlias www.yazilimdersi.info
            DocumentRoot /var/www/yazilimdersi.info/public_html
    [...]
    Son olarak oluşturulan VirtualHost yapısının aktif hale getirilmesi için şu komutu kullanmanız yeterli olacaktır.
    sudo a2ensite yazilimdersi.info
    Yeni virtual host dosyanız aktif hale getirildi. Şimdi DNS ayarlarınızı Ubuntu serverinize yönlendirmeniz ile birlikte ekranda html dosya içerisinde yazdığımız "Virtual Host ile alakalı kurulum başarılı şekilde gerçekleştirildi." yazısını browserinizde görebilirsiniz. Browsere yazmanız gereken yeni oluşturdugunuz domain ismidir. Makaleyi anlattıgım süre içerisinde yazılımdersi.info domainini kullandım. Siz de farklı bir domain ismi kullanabilirsiniz.]]>
    Wamp Server kurulumu ve kullanımı http://yazilimdersi.info/makaleler/detay/18/wamp-server-kurulumu-ve-kullanimi Wed, 30 Jul 2014 00:00:00 +0000 mstfchelikWamp Server, Windows işletim sistemi üzerinde Apache, Mysql, Php programlarının kurulumu bir arada sunan tümleşik bir yazılımdır. Normalde sisteminizde çalışmasını istediğiniz internet siteleri için her üç programın ayrı ayrı kurulması gerekmektedir. Zaten WAMP ifadesi Windows Apache MySQL Php programlama dillerinin baş harflerinden oluşturulmuştur. Linuxta kullanılan LAMP programına alternatif olarak Windows için hazırlanmıştır ve tamamen açık kaynak kodludur. Bu nedenle kurulum sonrasında da üzerinde düzenlemeler yapılabilmektedir.

    1. Wamp Server kurulumu: 
    Wamp Server kurulumu oldukça basittir ve açık kaynak kodlu olduğundan birçok farklı dili desteklediği gibi Türkçe dilini de desteklemektedir. Burada önemli olan işletim sisteminizin 32 bit mi yoksa 64 bit mi olduğunun bilinmesidir. Kurulum işlemi için linke tıklayınız ve setup.exe dosyasını çalıştırınız. Bilgisayaranızla alakalı bazı bilgilere erişmesi gerektiğinden izinlerle alakalı size dialog açacaktır. Buralara onay vermenizle birlikte kurulum işlemi tamamlanmış olacaktır. Sonuç olarak artık bilgisayarınızda local bir websitesi barındırma yapısı hazırlanmış oldu.  

    2. Wamp Server kullanımı: 
    Wamp Serverın başarılı şekilde kurulmasıyla birlikte nasıl kullanıldıgını basit şekilde inceleyelim. Wamp kurulumunu normalde C:// dizini altına yapmaktadır ve dosyalar C://wamp altında listelenmektedir. Bu dosyanın altında configurasyonlar,ini dosyaları ve host edilecek olan sitelere ait klasör (C://wamp/www) bulunmaktadır. wamp dizini altına atılan tüm php dosyalarına http://localhost linki üzerinden erişebiliriz. Örnek olarak; phpinfo.php dosyası oluşturalım ve içerisine altta bulunan php kodlarını ekleyelim:
    <?php echo phpinfo(); ?>
    Php dosyasına yapılan eklemelerden sonra oluşan phpinfo.php dosyasını C://wamp/www/ dizini altına taşıyalım. Sonrasında browsera http://localhost/phpinfo.php linkini yazdığımızda kurduğumuz Wamp Server ile alakalı tüm bilgiler listelencektir. Hangi Php versiyonunu kurdugumuz, desteklediği modüller, çalışan portlar vs. birçok bilgiye buradan ulaşabilirsiniz.

    3. WampServerde IP adresi üzerinden yayın yapılması: 
    WampServerin sunduğu en güzel özelliklerden birisi localinizde bulunan çalışmaların dışarıdakilere de açabiliyor olmanızdır. Bu sayede arkadaşlarınızın sizin yaptıgınız calısmalara erişimi rahatlıkla yapılabilmektedir. Bunun için yapılması gereken WampServerin localhost için kullandığı 80 portunun modemde dışarıdan erişime açılmasıdır. Ayrıca WampServerde bulunan Put Online ( Çevrimiçi Hale Getir) seçeneğinin ON hale getirilmesidir. Böylelikle artık yaptıgınız calısmalara arkadaslarınızı erisebilirler. Onlara sunmanız gereken bilgisayarınıza ait IP adresini göndermenizdir. ip adresini öğrenme konusunda ise whatsmyip sitesini veya browserler için yazılmış bir çok uzantıyı kullanabilirsiniz. Örneğin IP adresiniz : 31.7.12.90 oldugunu düşünelim. Arkadaslarınız browserine http://31.7.12.90/phpinfo.php yazdığı anda localhostta bulunan projenize erişebilecektir. Unutulmaması gereken konu ise sizin bilgisayarınız açık olduğu sürece projelerinize erişebilirler.

    4. WampServerde port numarasının değiştirilmesi: 
    WampServer localde oluşturulan webserver için http portunu yani 80 portunu kullanmaktadır. Ancak sizin daha önceden 80 portunda bulunan herhangi bir projeniz varsa bunun etkilenmemesi adına wampde bulunan port numarasını değiştirebilirsiniz. Ayrıca son zamanlarda skype uygulaması açıkken wamp çalıştırılmak istenildiğinde 80 portunun kullanıldığı ile alakalı uyarı alabilirsiniz. Tek yapmanız gereken Sağ alt köşede açılan Wamp programına tıklayıp Apache->httpd.conf dosyasında  Listen 80 olarak geçen satırı istediğiniz herhangi bir port numarası ile değiştirebilirsiniz. Listen 1453 gibi. Apache nin tekrar açılıp kapatılması ile birlikte yaptığınız düzenleme yayına alınmış olacaktır. Ancak browserden daha önceden http:://localhost olarak erişebildiğiniz Wamp Servere artık sonunda port numarası ekleyerek erişebilirsiniz. 
    http://localhost:1453
     ]]>
    Android te aktiviteler (activity) arası geçişler http://yazilimdersi.info/makaleler/detay/17/android-te-aktiviteler-(activity)-arasi-gecisler Wed, 30 Jul 2014 00:00:00 +0000 mstfchelik
    1. Yeni Activity oluşturulması: 
    Yeni activitylerin çağrılmasında startActivity() veya startActivityForResult() komutları kullanılmaktadır.
    Intent i = new Intent(getApplicationContext(), İkinciEkran.class); 
    startActivity(i);
    

    2. Activityler arası parametrelerle bilgi aktarımı: 
    Activitylere bilgi aktarımında  putExtra() metodu kullanılmaktadır.
    Intent i = new Intent(getApplicationContext(), İkinciEkran.class); 
    i.putExtra("key", "value"); 
    // Örneğin aşağıdaki email adresi gönderiminde kullanıldığı datalar iletilmektedir.
    // Key = 'email' 
    // value = '[email protected]' 
    i.putExtra("email", "[email protected]"); 
    startActivity(i);
    

    3. Activityden aktarılan bilginin alınması: 
    Activityden aktarılan bilginin alınmasında  getStringExtra() metodu kullanılmaktadır. Gönderilen bilginin tipine göre farklı metodlarda kullanılabilmektedir.
    Intent i = getIntent(); 
    i.getStringExtra("key"); 
    // email adresi gönderilen bilginin activity üzerinde alınması 
    // ve emailadresim değişkeninde setlenmesi örnekteki gibidir.
    String emailadresim = i.getStringExtra("email");
    

    4. Activity geçişlerinden sonra yeni activityde bulunan bilginin önceki activitye iletilmesi: 
    Herhangi bir activity çağrılırken eski activityden bilgi alınılması istenildiğinde kullanılan en etkin yöntem  startActivityForResult() metodunun kullanılmasıdır. Bu metod sayesinde geçiş yapılan activity ile alakalı bilgiler önceki activitye iletilebilmektedir. Bu işlemde onActivityResult() metodu ile sağlanmaktadır.
    Intent i = new Intent(getApplicationContext(), İkinciEkran.class); 
    startActivityForResult(i, 1453); 
    // 1453 bir sonraki activityden gelen datanın olumlu olup olmadığında kullanılacaktır.
    // Yeni oluşturulan activityden gelen datanın okunmasında onActivityResult() kullanılmaktadır.
    @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == 1453){ 
    // website verisinin yeni activityden çekilmesi şu şekilde olmaktadır.
    String websitem = data.getExtras().get("website"); 
    } 
    }
    
    Yukarıda bulunan kodlama ilk ekranda kullanılmaktadır. İkinciEkran.classında ise kullanılması gereken veri ise şu şekilde hazırlanmaktadır:
    Intent i = new Intent(); 
    // Websitesi bilgisini 'yazilimdersi.info' olarak aşağıdaki şekilde tanımlayarak göndermekteyiz:
    i.putExtra("website", "yazilimdersi.info"); // setResult alanında 1453 olarak setleme yapılması gerekmektedir.
    setResult(1453,in);
    

    5. Activitynin kapatılması: 
    Oluşturulan aktivitilerin kapatılmasında finish() metodu kullanılmaktadır. Kısacası aktivitilerin yaşam döngüsü bu metod kullanılarak sona erdirilmektedir.
    finish();
    

    6. Activitynin Manifest.xml dosyasına yazılması: 
    Oluşturulan aktivitiler direkt uygulama içerisinde kullanılamamaktadır. Kullanılacak tüm activitylerin önceden Android Manifest.xml dosyasında tanımlanması gerekmektedir. Aksi takdirde uyarı mesajı ile karşılaşacaksınızdır. Bu tanımlamalar application etiketi arasında yazılarak gerçekleştirilmektedir. Gerekli tanımlama aşağıdaki gibi yapılmaktadır.
    <activity android:name=".OrnekActivity"></activity>

    7. Activity geçişleri ile alakalı örnek proje oluşturalım: 
    Şimdiye kadar olan yazımızda activity geçişlerinin nasıl gerçekleştirildiği ve sonlandırıldığı ile alakalı kod parçacıkları paylaştık. Şimdi ise 2 farklı ekran ( ekran1.xml, ekran2.xml) ve iki farklı activity( IlkEkranActivity.class, IkinciEkranActivity.class) kullanarak örnek bir uygulama hazırlayalım. Öncelikle uygulama bittiğinde oluşacak dosya yapısı aşağıdaki gibi olacaktır.

    Uygulama oluşturulurken izlenmesi gereken adımlar şu şekildedir:
    • Eclipse uygulamasını açınız ve File->Others->Android Application Project linkine tıklayınız. Oluşturulacak projede mainactivity oluşturulurken IlkEkranActivity olarak isimlendirmesini gerçekleştiriniz.
    • Şimdi sırada hazırlanan activity nin arayüzünü hazırlamaya geldi. /res/layout/activity_main.xml olarak default eklenen dosya ismini ekran1.xml olarak değiştiriniz. Herhangi bir xml dosyası bulunmuyorsa /res/layout altında, layout dizini altında sağa tıklayın ve New->Android XML File dosyasında ekran1.xml olarak dosyayı oluşturunuz.
    • Aşağıda bulunan layoutları ekran1.xml dosyasına ekleyiniz. Böylelikle uygulumaya ait ilk ekran hazırlanmış oldu.
    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout 
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent" 
            android:padding="10dp" android:orientation="vertical" > 
        <TextView android:id="@+id/nameTextView" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:textColor="#FFF" 
            android:textSize="18sp" android:text="İsim : " /> 
        <EditText android:id="@+id/nameEditText" android:layout_width="match_parent" 
            android:layout_height="wrap_content" android:ems="10" > 
        <requestFocus /> 
        </EditText> 
        <TextView android:id="@+id/emailTextView" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:textColor="#FFF" 
            android:textSize="18sp" android:text="Email :" /> 
        <EditText android:id="@+id/emailEditText" android:layout_width="match_parent" 
            android:layout_height="wrap_content" android:ems="10" /> 
        <Button android:id="@+id/sonrakiEkranButton" android:layout_width="fill_parent" 
            android:layout_marginTop="10dp" android:layout_height="wrap_content" 
            android:text="Sonraki Ekrana Geç" /> 
    </LinearLayout>

    • IlkEkranActivity.class dosyasını açıp aşağıda bulunan kodlamayı ekleyiniz. Yazılan kodlamada Sonraki Ekrana Geç butonuna tıklanıldığında İkinciEkranActivity.classının nasıl çalıştığı görüntülenmektedir.
    import android.app.Activity; 
    import android.content.Intent; 
    import android.os.Bundle; 
    import android.util.Log; 
    import android.view.View; 
    import android.widget.Button; 
    import android.widget.EditText; 
    
    public class IlkEkranActivity extends Activity { 
    EditText inputIsim; 
    EditText inputEmail; 
    
    @Override public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.ekran1); 
    inputIsim = (EditText) findViewById(R.id.nameEditText); 
    inputEmail = (EditText) findViewById(R.id.emailEditText); 
    Button sonrakiEkranButton = (Button) findViewById(R.id.sonrakiEkranButton); //Butona tıklanıldıgında alınacak aksiyonun yazılması 
    
    sonrakiEkranButton.setOnClickListener(new View.OnClickListener() { 
           public void onClick(View arg0) { //Starting a new Intent 
               Intent sonrakiEkran = new Intent(getApplicationContext(), IkinciEkranActivity.class); //Bilginin diğer aktivitelere iletilmesi
               sonrakiEkran.putExtra("isim", inputIsim.getText().toString()); 
               sonrakiEkran.putExtra("email", inputEmail.getText().toString()); 
               Log.e("n", inputIsim.getText()+"."+ inputEmail.getText()); startActivity(sonrakiEkran); 
           } 
    }); 
    
    }}

    • İlk activity ile yapılacak işlemler tamamlandı. Şimdi çağrılacak IkinciEkranActivity.class dosyasını oluşturalım. Bunu projede src dizini altında New->Class a tıklayıp IkinciEkranActivity.classını oluşturunuz. Aşağıda bulunan kod parçacığını ikinci ekrana ait aktivity sınıfına ekleyiniz.
    import android.app.Activity; 
    import android.content.Intent; 
    import android.os.Bundle; 
    import android.util.Log; 
    import android.view.View; 
    import android.widget.Button; 
    import android.widget.TextView; 
    
    public class IkinciEkranActivity extends Activity {
    
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.ekran2); 
            TextView txtIsim = (TextView) findViewById(R.id.txtIsim); 
            TextView txtEmail = (TextView) findViewById(R.id.txtEmail); 
            Button kapatButton = (Button) findViewById(R.id.kapatButton); 
            Intent i = getIntent(); // Bilgilerin önceki activityden alınması 
            String isim = i.getStringExtra("isim"); 
            String email = i.getStringExtra("email"); 
            Log.e("Second Screen", isim + "." + email); 
            
            // İlk activityden alınan bilgilerin görüntülenmesinde kullanılmaktadır. 
            txtIsim.setText(isim); txtEmail.setText(email); 
            
            // Kapatma butonun alacağı aksiyonun belirlenmesi 
            kapatButton.setOnClickListener(new View.OnClickListener() { 
                   public void onClick(View arg0) { 
                   //İkinci Activity nin kapatılması 
                        finish(); 
                   } 
            }); 
    } }
    

    • Activity classı oluşturulan ikinci ekrana ait tasarım aşağıdaki kodlamaya göre ayarlanmaktadır.
    <LinearLayout 
            xmlns:android="http://schemas.android.com/apk/res/android" 
            android:layout_width="fill_parent" android:layout_height="fill_parent" 
            android:gravity="center_horizontal" android:padding="10dp" 
            android:orientation="vertical" > 
        <TextView android:id="@+id/textView1" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:textColor="#FFF" 
            android:textSize="18sp" android:text="Önceki Activityde girdiğiniz bilgier :" /> 
        <TextView android:id="@+id/txtIsim" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:textColor="#FFF" 
            android:textSize="18sp"/> 
        <TextView android:id="@+id/txtEmail" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:textColor="#FFF" 
            android:textSize="18sp" /> 
        <Button android:id="@+id/kapatButton" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:text="Kapat" /> 
    </LinearLayout>
    • Şu an her iki ekranla alakalı activity sınıfları ve tasarımları ayarlandı. Makalenin başında belirtigimiz üzere Manifest.xml dosyasına işlem yapacak activitylerin yazılması gerekmektedir aşağıda belirtildiği gibi:
    <?xml version="1.0" encoding="utf-8"?> 
    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android" 
        package="com.yazilimdersi.info.androidactivitygecisi" 
        android:versionCode="1" 
        android:versionName="1.0"> 
    <uses-sdk android:minSdkVersion="8" />
    <application 
        android:icon="@drawable/icon" 
        android:label="@string/app_name"> 
    <activity 
        android:name=".IlkEkranActivity" 
        android:label="@string/app_name"> 
       
        <intent-filter> 
          <action android:name="android.intent.action.MAIN" /> 
          <category android:name="android.intent.category.LAUNCHER" /> 
        </intent-filter> 
    </activity> 
    <activity android:name=".IkinciEkranActivity">
    </activity> 
    </application> 
    </manifest>
     

    • Kodlamanın tamamlanması ile birlikte uygulama üzerinde sağa tıklayıp Run As-> Android Application seçeneği ile uygulama çalıştırılır. Oluşan ekranlar aşağıdaki gibidir:
    ]]>
    MySQL çoklu kayıtların (duplicate records) silinmesi http://yazilimdersi.info/makaleler/detay/16/mysql-coklu-kayitlarin-(duplicate-records)-silinmesi Mon, 28 Jul 2014 00:00:00 +0000 mstfchelik Veritabanı ile çalışan birçok uygulamada tablolarda oluşan çoklu kayıtların belirlenmesi için birçok yöntem uygulanmaktadır. Bazılarımız bu kayıtların silinmesi için tek tek kayıtları incelemekte ve tekrarlı olanları belirleyip tablodan silinmesi ile alakalı işlemler gerçekleştirmektedir. Aslında en iyi çözüm MySQL veritabanında unique olmasını istediğimiz elemanın daha önceden setlenmesi ile olmaktadır. Örnek verecek olursak names isimli bir tablomuz olsun ve içerisinde unique olmayan bazı kayıtlar bulunsun aşağıdaki gibi;

    SELECT * FROM names;
    Yukarıda yazılı olan sorgunun çıktısı şu şekilde olsun: 
    +----+--------+ 
    | id | name | 
    +----+--------+ 
    | 1 | java | 
    | 2 | php | 
    | 3 | linux | 
    | 4 | java | 
    | 5 | java | 
    | 6 | ruby |
    |  6   |  java   | 
    +----+--------+
    Tabloda gördüğünüz üzere 'java' ismi birden çok bulunmaktadır. Bu tablo hazırlanmadan önce eger programcı name isimli sütun için unique key i kullanmış olsaydı bu tip tekrarlı kayıtlar ile karşılaşılmayacaktı. O sorgu ise şu şekilde gerçekleştirilmektedir.  
    ALTER TABLE names ADD CONSTRAINT name_ID UNIQUE (name)
    Tekrarlı kayıt bulunan tabloda tekrarsız kayıtları çekmek için ise yazılması gereken sorgu şu şekilde olmalıdır:
    SELECT DISTINCT name FROM names;
    Yukarıda yazılı olan sorgunun çıktısı şu şekilde olsun: 
    +------+ 
    | name | 
    +------+ 
    | java | 
    | php | 
    | linux | 
    | ruby | 
    +-----+
    Gördüğünüz gibi sadece çoklu kayıtların select sorgusunda çekilmemesi DISTINCT anahtar kelimesi ile gerçekleştirilmiştir.

    Eğer duplicate yani tekrarlı kayıtların tablomuzdan tamamen silinmesini istiyorsak yazılması gereken sorgu ise şu şekildedir. Yazılan sorgulama sonrası yukarıdaki gibi name sütununda bulunan içerikler unique olarak listelenecektir:
    DELETE n1 FROM names n1, names n2 WHERE n1.id < n2.id AND n1.name = n2.name
    Gördüğünüz gibi herşey bu kadar basit. Tek satır sorgu ile çoklu kayıtlardan kurtulmuş oldunuz.

     

    ]]>
    MySQL de kullanıcı oluşturulması ve yetkilendirmeler http://yazilimdersi.info/makaleler/detay/15/mysql-de-kullanici-olusturulmasi-ve-yetkilendirmeler Mon, 28 Jul 2014 00:00:00 +0000 mstfchelik
    1. MySQL'de yeni kullanıcı oluşturma: 

    Yeni kullanıcı oluşturulurken 3 parametrenin setlenmesi gerekmektedir: kullanıcı adışifrehost.
    kullanıcı adı : Bu alanın girilmesi zorunludur. Yeni eklenen kullanıcı adını temsil etmektedir. Herhangi bir yetkilendirme verilmek istenildiğinde veritabanları üzerinde bu parametre kullanılmaktadır. 
    şifre : Bu alan zorunlu değildir. Ancak güvenlik açısından şifre setlenmesi daha iyi olacaktır. Aksi takdirde bu kullanıcı üzerinden bazı kişiler sisteminize erişim yapabilirler. Tabiki sadece bu kullanıcı için setlenmiş veritabanları için bu işlem gerçekleştirilecektir. Ancak tedbir açısından her zaman setlenmesi gerekmektedir.
    host : Bu kullanıcının veritabanına nereden erişim yapabileceği ile alakalı alandır.
    Örnek bir kullanıcı  oluşturma kodu şu şekildedir: 
     CREATE USER 'kullanıcı adı'@'localhost' IDENTIFIED BY 'şifre'
    2. MySQL'de kullanıcı silme: 

    Herhangi bir kullanıcının silinmesinde kullanıcı adı parametresi kullanılmaktadır. Örnek bir kullanıcı silme kodu şu şekildedir: 
    DROP USER 'kullanıcı adı';
    
    3. MySQL'de kullanıcı listeleme: 

    Veritabanınıza bağlı tüm kullanıcıları ve bağlandığı host verilerini görmek için ise aşağıda bulunan kod parçacığını kullanabilirsiniz: 
     SELECT host, user FROM mysql.user;
    4. MySQL'de kullanıcı yetkilendirme: 

    Herhangi bir kullanıcının belirlemiş olduğumuz bir tabloya erişimi ile alakalı sorgulamada kullanılan parametreler şunlardır: veritabanı ismi, tablo ismi, kullanıcı adı ve host.
    veritabanı ismi : Kullanıcının hangi veritabanı ile ilişkilendirildiğinde kullanılmaktadır.Eğer kullanıcı tüm veritabanları ile ilişkilendirilmek isteniyorsa '*' kullanılması yeterlidir. Ancak tüm veritabanları degilde belirlediğimiz veritabanlarının erişimi güvenlik açısından daha iyi olacaktır. 
    tablo ismi : Kullanıcının veritabanında belirli tablolara erişimini sağlamada kullanılabilmektedir. Bu alan veritabanı isminde kullanıldığı gibi '*' ile veritabanına ait tüm tablolara yetki verebilmektedir. Ayrıca sadece belirli tablolara erişimin sağlanmasında da kullanılabilmektedir.
    kullanıcı adı : Bu alanın girilmesi zorunludur. Kullanıcı adı yazılarak hangi kullanıcının hangi tablo ile yetkilendirildiği belirlenmektedir.
    host : Bu kullanıcının veritabanına nereden erişim yapabileceği ile alakalı alandır.
     
    GRANT ALL PRIVILEGES ON 'veritabanı ismi' . 'tablo ismi' TO 'kullanıcı adı'@'localhost';

    Belirlediğimiz kullanıcıya tüm veritabanına ve tablolarına erişimi verebildiği kod parçacığı şu şekildedir:
     
    GRANT ALL PRIVILEGES ON * . * TO 'kullanıcı adı'@'localhost';

    Kullanıcılarla alakalı yapılan yetkilendirmelerden sonra yeni yapılandırmaların etkili olması için yetkilendirmeleri aşağıda bulunan kodlama ile yenilendirmemiz gerekmektedir. Böylelikle yapılan düzenlemeler etkin hale gelmiş olur
     
    FLUSH PRIVILEGES;
    ]]>
    Crontab Cronjob kullanımı ve örnek kodlamalar http://yazilimdersi.info/makaleler/detay/14/crontab-cronjob-kullanimi-ve-ornek-kodlamalar Mon, 28 Jul 2014 00:00:00 +0000 mstfchelik
    Crontab : Belirlediğimiz zaman diliminde belirlediğimiz scriptin çalıştırılmasını sağladığımız yapıdır.
    Cronjob : Çalıştırılmasını istediğimiz scripti verilen isimdir. 

    1. Crontab'ın editlenmesi: 
    Linux tabanlı sisteminizde crontabların editlenmesi kullanılan kod parçacığı şu şekildedir:
    crontab -e
    

    2. Crontab'ın yapılan işlemlerin listelenmesi: 
    Crontaba eklenmiş olan cronjobların listesini aşağıda bulunan kod parçacığı ile alabiliriz:
    crontab -l
    

    3. Crontab'ların silinmesi: 
    Crontaba eklenmiş olan cronjobların tümünü silmek istediğimizde kullanılacak kod parçacığı şu şekildedir:
    crontab -r
    

    Örnek bir crontab dosyası şu şekilde olmaktadır:
    *  *  *  *  *  /calıstirilacak komut
    

    Yukarıda bulunan kod parçacığında * olarak yazılı olan alanlar çalıştırılacak komutun ne zaman çalıştırılması gerektiğini belirlemede kullanılmaktadır. İlk * dakika, ikinci * saat, üçüncü * gün, dördüncü * ay, beşinci * haftanın günlerine karşılık gelmektedir. Daha iyi anlaşılması için aşağıda bulunan yapıyı inceleyebilirsiniz:
    .---------------- dakika (0 - 59) 
    | .------------- saat (0 - 23) 
    | | .---------- Ayın Günleri (1 - 31) 
    | | | .------- Ay (1 - 12) 
    | | | | .---- Haftanın Günleri (0 - 6) (Pazar=0 ya da 7) 
    | | | | | 
    * * * * * Çalıştırılacak komut
    

    4. Örnek cronjoblar: 
    30 dakikada bir çalışacak crontab girdisi şu şekilde olmaktadır :
    */30 * * * * /komut
    

    Sabah 8 Akşam 18 arasında çalışacak crontab girdisi şu şekilde olmaktadır :
    00 08-18 * * * /komut
    

    Her 5 dakikada bir yapılmasını istediğimiz crontab girdisi şu şekilde olmaktadır :
    */5 * * * * /komut
    

    Her saat başında yapılmasını istediğimiz crontab girdisi şu şekilde olmaktadır :
    0 * * * * /komut
    

    ]]>
    VPNC komutu ile Cisco VPN e bağlanmak http://yazilimdersi.info/makaleler/detay/13/vpnc-komutu-ile-cisco-vpn-e-baglanmak Mon, 28 Jul 2014 00:00:00 +0000 mstfchelikVPNC (Virtual Private Network Consortium) olarak adlandırılan yapıda güvenli sistemlere uzaktan erişimi sağlamada kullanılmaktadır. Sektörde en çok kullanılan VPN yapısı ise Cisco VPN Client olarak bilinmektedir. Ubuntu sistemi üzerinde vpnc kurulumu aşağıdaki komut ile sağlanmaktadır.
    sudo apt-get install vpnc
    
    vpnc kurulumunun ardından sistemlere erişimde kullanılacak konfigürasyon dosyasının hazırlanması gerekmektedir. .conf olarak ayarlanan dosya uzak servere erişimde kullanılacak kullanıcı adı,şifre ve erişimde kullanılacak protokol hakkında bilgi vermektedir. vpnc kurulumundan sonra /etc/vpnc/default.conf dosyası oluşmaktadır. Bizde bağlantı kurmak istediğimiz sistemle alakalı bilgileri /etc/vpnc/ dizini altında .conf dosyası içerisine aşağıdaki şekilde ekleriz:
    IPSec gateway  
    IPSec ID  
    IPSec secret  
    IKE Authmode hybrid 
    Xauth username  
    Xauth password <şifre>
    

    VPNC ile uzaktan servere erişimde aşağıda bulunan komut kullanılmaktadır:
    vpnc /etc/vpnc/xxx.conf
    

    VPNC ile bağlanılan servere bağlantının kesilmesinde kullanılan kodlama şu şekildedir:
    vpnc-disconnect
    
     
    ]]>
    Linux ta find komutunun işlevi http://yazilimdersi.info/makaleler/detay/12/linux-ta-find-komutunun-islevi Sun, 27 Jul 2014 00:00:00 +0000 mstfchelik-name ifadesi aratılan kelimenin küçük büyük harfa karşı duyarlı olmasına sebep olmaktadır. Yani aramalarda 'Game' veya 'gaME' isimli dosyalar listelenmeyecektir. Eğer aramalarda duyarlılığı kaldırmak istiyorsanız -name yerine -iname ifadesi yazılması yeterlidir.

    find / -name game

    Aşağıda bulunan komutta ise /home dizini altında bulunan ve yazilimdersi kullanıcısına ait tüm dosyaların listelenmesini sağlamaktadır.

    find /home -user yazilimdersi

    Aşağıda bulunan komutta ise /usr dizini altında bulunan ve dosya ismi stat ile biten tüm dosyaların listelenmesini sağlamaktadır.

    find /usr -name *stat 

    Aşağıda bulunan komutta ise /var/spool dizini altında bulunan ve 60 günden önce güncellenmiş tüm dosyaların listelenmesini sağlamaktadır.

    find /var/spool -mtime +60 

    ]]>
    Android Layout Yapıları (Linear, Relative, Frame Layout) http://yazilimdersi.info/makaleler/detay/11/android-layout-yapilari-(linear-relative-frame-layout) Sun, 27 Jul 2014 00:00:00 +0000 mstfchelik Linear Layout, Relative Layout, Frame Layout kullanılmaktadır. Ayrıca listelemelerde ListView ve GridView yapılarıda kullanılmaktadır.

    Android kodlamada tasarımlar /res/layout dizini altına eklenen activityler icerisinde bulunan XML dosyalarında yapılmaktadır. Ayrıca tasarımlar Java kodlaması ile de yapılabilmektedir. Ancak pratik kullanımda geliştiriciler daha çok XML dosyalar üzerinde bu işlemi gerceklestirmektedir.

    Şimdi her bir layout un ne amaçla ve nasıl çalıştığını anlatalım.

    1. Linear Layout: 
    Bu layout yapısı çoğunlukla aynı sırada ve boyutta olan içeriklerin ardarda eklenmesi amacı ile kullanılabilmektedir. Bu layoutun en önemli özelliği orientation(yön belirleme) değişkeninin bulunmasıdır. Bu değişken horizontal(yatay) veya vertical(dikey) olarak setlenebilmektedir. LinearLayout içerisine eklenen buton ve textlerin ne yönde ardarda ekleneceğinin belirlenmesinde kullanılmaktadır.

     <LinearLayout 
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" 
          android:orientation="vertical">
          ....
     </LinearLayout>


    Linear Layout yapısının nasıl çalıştığını en iyi şekilde betimleyen resim aşağıdaki gibidir:
    Şekildeki gibi oluşturulan layout yapısında en dışta bulunan LinearLayout un vertical olarak belirlenmesi ve alt elemanlarda bulunan LinearLayout un ise horizontal olarak setlenmesi bize birçok platformda kullanılan login sistemine ait tasarımı vermektedir. Şimdi aşağıda bulunan kodlamada örnek bir tasarım hazırlanmakta ve kodsal paylaşım gerceklestirilmektedir.














    • Eclipse programını açınız ve File->New->Android Application Project linkine tıklayarak yeni proje oluşturunuz.
    • Oluşan projede /res/layout dizininde sağa tıklayarak New->Android XML File üzerinden linear_layout.xml dosyasını oluşturunuz. 
    • Oluşturduğunuz linear_layout.xml dosyasını açın ve aşağıda bulunan kod parçacığını ekleyin.
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android" 
        xmlns:tools="http://schemas.android.com/tools" 
        android:layout_width="match_parent" android:layout_height="match_parent" 
        android:background="#359bed" android:orientation="vertical" 
        android:padding="20dp" > 
    
      <TextView android:id="@+id/emailTextView" android:layout_width="fill_parent" 
        android:layout_height="wrap_content" android:padding="5dp" 
        android:text="Email :" android:textColor="#FFFFFF" 
        android:textSize="18sp" /> 
      <EditText android:id="@+id/emailEditText" android:layout_width="match_parent" 
        android:layout_height="wrap_content" android:hint="Email adresinizi girin" 
        android:inputType="textEmailAddress" android:ems="10" > 
      <requestFocus /> 
      </EditText> 
      <EditText android:id="@+id/passwordEditText" android:layout_width="match_parent" 
        android:layout_height="wrap_content" android:hint="Şifrenizi girin" 
        android:inputType="textVisiblePassword" android:ems="10" > 
      <requestFocus /> 
      </EditText> 
      <Button android:id="@+id/saveButton" android:layout_width="fill_parent" 
        android:layout_height="wrap_content" android:text="Login" /> 
      <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" 
        android:orientation="horizontal" > 
      <Button
        android:id="@+id/createAccountButton" android:layout_width="wrap_content" 
        android:layout_height="wrap_content" android:layout_weight="1" 
        android:text="Yeni Hesap" /> 
      <Button android:id="@+id/forgetpasswordButton" android:layout_width="wrap_content" 
        android:layout_height="wrap_content" android:layout_weight="1" 
        android:text="Şifremi unuttum" /> 
      </LinearLayout> 
    </LinearLayout>
    • Activity dosyasına hazırlamış olduğunuz layoutu yani linear_layout.xml setlemeniz gerekmektedir. Bunu ise aşağıda bulunan kodlama ile gerçekleştirebilirsiniz.
    import android.app.Activity; 
    import android.os.Bundle; 
    
    public class AndroidLayoutsActivity extends Activity { 
        @Override
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.linear_layout); 
        } 
    }
    • Proje Explorer alanında projeniz üzerinde sağa tıklayıp Run As-> Android Application seçeneğini seçtiğiniz takdirde uygulamanın emülatörde görüntülenen arayüzü şu şekilde olacaktır. 
    2. Relative Layout: 
    Bu layout yapısı normal hayatta kullandığımız herhangi bir nesneyi baz alarak yaptıgımız yönlendirmelerde kullanılmaktadır. Örneğin; giriş butonunun sağına iptal butonunu eklemenizde, veya layoutun en altına herhangi bir element eklemek istediginizde kullanılır. Bu layoutun sizinde anladığınız üzere birçok yararı bulunmaktadır. Farklı ekran boyutlarında bu yönlendirmeler sorunsuz çalıştığından geliştiricilerin en çok kullandığı layout yapısı oldugunu söyleyebiliriz. Örnek kod parçası aşağıdaki gibi ayarlanmaktadır.

    <Button android:id="@+id/btnLogin">
    </Button>
    <Button android:id="@+id/btnCancel" android:layout_toRightOf="@id/btnLogin" 
    android:layout_alignTop="@id/btnLogin">
    </Button>


    Relative Layout yapısının nasıl çalıştığını en iyi şekilde betimleyen resim aşağıdaki gibidir:
    Şekildeki gibi oluşturulan layout yapısında Cancel butonun Login butonun yanına ilişlendirilmesi ve Register New Account butonun sayfanın en altına konulması RelativeLayout kullanılarak rahatlıkla yapılmıştır. Zaten ingilizcesi az buçuk iyi olan birisi kodlamada geçen yönlendirmelerden butonların nasıl konumladırılabileceğini tahmin edebilirsiniz. Örneğin; cancel butonun login butonun yanına konulması gerektiğini android:layout_toRightOf ifadesi ile tanımlamaktadır. Şimdi aşağıda bulunan kodlamada örnek bir tasarım hazırlanmakta ve kodsal paylaşım gerceklestirilmektedir.














    • Eclipse programını açınız ve File->New->Android Application Project linkine tıklayarak yeni proje oluşturunuz.
    • Oluşan projede /res/layout dizininde sağa tıklayarak New->Android XML File üzerinden relative_layout.xml dosyasını oluşturunuz. 
    • Oluşturduğunuz relative_layout.xml dosyasını açın ve aşağıda bulunan kod parçacığını ekleyin.
    <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"                                
            android:background="#359bed" android:orientation="vertical" 
            android:paddingLeft="20dp" android:paddingRight="20dp" android:paddingTop="20dp" > 
        <TextView android:id="@+id/emailTextView" android:layout_width="fill_parent" 
            android:layout_height="wrap_content" android:padding="5dp" 
            android:text="Email :" android:textColor="#FFFFFF" 
            android:textSize="18sp" /> 
        <EditText android:id="@+id/emailEditText" android:layout_width="match_parent"
            android:layout_height="wrap_content" android:layout_alignLeft="@+id/emailTextView" 
            android:layout_below="@+id/emailTextView" android:ems="10" 
            android:hint="Email adresinizi girin" android:inputType="textEmailAddress" > 
        <requestFocus /> </EditText> 
        <Button android:id="@+id/loginButton" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:layout_alignLeft="@+id/emailEditText" 
            android:layout_below="@+id/emailEditText" android:layout_alignParentLeft="true" 
            android:layout_marginRight="10px" android:text="Login" /> 
        <Button android:id="@+id/cancelButton" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:layout_below="@+id/emailEditText" 
            android:layout_toRightOf="@+id/loginButton" android:text="Cancel" /> 
        <Button android:id="@+id/registerButton" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:layout_alignParentBottom="true" 
            android:layout_centerHorizontal="true" android:text="Register New Account" /> 
    </RelativeLayout>
    
    • Activity dosyasına hazırlamış olduğunuz layoutu yani relative_layout.xml setlemeniz gerekmektedir. Bunu ise aşağıda bulunan kodlama ile gerçekleştirebilirsiniz.
     
    import android.app.Activity; 
    import android.os.Bundle; 
    
    public class AndroidLayoutsActivity extends Activity { 
        @Override
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.relative_layout); 
        } 
    }
    • Proje Explorer alanında projeniz üzerinde sağa tıklayıp Run As-> Android Application seçeneğini seçtiğiniz takdirde uygulamanın emülatörde görüntülenen arayüzü şu şekilde olacaktır. 
    3. Frame Layout: 
    Bu layout yapısında ise resimlerin veya textlerin üst üste bindirilmesi gerektiğinde kullanılmaktadır. Mesela herhangi bir resmin üzerinde text ifadenin eklenmesi isteniyorsa bu yöntem izlenmektedir. Örnek kod parçası aşağıdaki gibi ayarlanmaktadır.
     
    <FrameLayout 
            xmlns:android="http://schemas.android.com/apk/res/android" 
            android:layout_width="fill_parent" android:layout_height="fill_parent"> 
        <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" 
            android:scaleType="center" android:src="@drawable/golden_gate" /> 
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" 
            android:layout_marginBottom="20dip" android:layout_gravity="center_horizontal|bottom" 
            android:padding="12dip" android:background="#AA000000" 
            android:textColor="#ffffffff" android:text="En altta text" /> 
    </FrameLayout>
    Yapılan kodlama sonucu oluşan ekran görüntüsü şu şekilde olacaktır.

    ]]>
    Android Uygulamasının Tam Ekran Yapılması http://yazilimdersi.info/makaleler/detay/10/android-uygulamasinin-tam-ekran-yapilmasi Sun, 27 Jul 2014 00:00:00 +0000 mstfchelik
    1. Activity içerisinde tam ekran bilgisinin setlenmesi:
    Yazılan activitylerin onCreate() metodu içerisinde aşağıda bulunan kod parçacıkları eklendiği takdirde uygulamanız tam ekran olarak çalışacaktır. Burada bulunan metodların amacı ise şu şekildedir:
    requestWindowFeature() : Uygulamamızla alakalı ekranın hangi özelliklerde olacağına dair setlemelerin yapıldığı fonksiyondur.
    setFlags(): Uygulamamızla alakalı farklı özelliklerin setlenmesinde kullanılabilen flag(bayrak) mekanizmasıdır. Sadece tam  ekran modunda değil ayrıca activity ile alakalı diğer özelliklerinde setlenmesinde kullanılabilmektedir.

    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    2. Manifest dosyasında tam ekran bilgisinin setlenmesi:
    Manifest dosyası sizinde bildiğiniz üzere Android uygulamanız ile alakalı detaylı bilgilerin tutulduğu dosyadır. Burada yapılan tanımlamalarla birlikte kullanıcıdan hangi izinleri almak istediginizi, uygulama icerisinde kullanılan activityler ve servislerin tanımlandıgı ve uygulamanın desteklendiği versiyonlarla alakalı bilgilerin tutulduğu dosyadır. Bu dosyada tanımlanan activitylere direkt olarak theme setlenmesi yapılabilmektedir. Bu özellikten yararlanılarak uygulamamızın tam ekran olarak görüntülenmesi sağlanabilmektedir. Eklenmesi gereken kod parçacığı aşağıdaki gibidir:

    <activity android:name=".MainActivity" 
    android:label="@string/app_name" 
    android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">



    ]]>
    Php de hata raporlama mekanizması ( error_reporting) http://yazilimdersi.info/makaleler/detay/9/php-de-hata-raporlama-mekanizmasi-(-error-reporting) Sat, 26 Jul 2014 00:00:00 +0000 mstfchelikPHP programlama dili ile yazdığınız kodlamada oluşan hataların hangilerinin sitede görüntülenip hangilerinin görüntülenmeyeceği ile alakalı hata raporlama (error_reporting) sistemi bulunmaktadır. Bu sistem sayesinde kodlamanızın sebep olduğu uyarı mesajlarının, hata mesajlarının, bilgi mesajlarından istediklerinizin sadece listelenmesi sağlanacaktır. Oluşabilecek muhtemel hata seviyeleri şu şekildedir:


    Sabit Açıklama
    E_ERROR Ölümcül çalışma anı hataları. Bellek ayırma sorunu gibi giderilemeyen hatalar bu sınıfa girer. Böyle hatalar betiğin çalışmasının durmasına sebep olur.
    E_WARNING Çalışma anı uyarıları (ölümcül olmayan hatalar). Betiğin çalışması durmaz.
    E_PARSE Derleme anı çözümleme hataları. Çözümleme hatalarını sadece çözümleyici üretir.
    E_NOTICE Çalışma anı bildirimleri. Betikte bir hataya sebep olabilecek fakat betiğin normal çalışmasını esnasında oluşmayabilecek bir şeylerin saptandığını belirtir.
    E_ALL Desteklenen (PHP 6'da E_STRICT dışında kalan) tüm hatalar ve uyarılar.

    Örneğin tüm hataların sitede görüntülenmesini istiyorsanız, tek yapmanız gereken php kodunuza aşağıdaki kod parçacıgını eklemeniz.
    error_reporing(E_ALL);
    ini_set('display_errors','1');
    Eğer sadece kodunuzun çalışmasına sebep olan hataların görüntülenmesini istiyorsanız, bu durumda sadece aşağıdaki kod parçacığını eklemeniz yeterli olacaktır:
    error_reporing(E_ERROR);
    ini_set('display_errors','1');
    Bu tip kod parçacıklarını direkt php kodunuzda tanımlayabileceğiniz gibi ayrıca serverinizde tanımlayabilirsiniz. Apache kurulu olan serverinizde php.ini dosyasına 
    error_reporting = E_ALL
    display_errors = On 
    satırlarını eklemenizle birlikte tüm projelerinizde bulunan hatalar görüntülenecektir. Burada dikkat edilmesi gereken konu php.ini de yapılan düzenleme sonrası bu serverde çalışan tüm php dosyalarındaki hatalar görüntülenecektir.]]>
    Eclipse ile Android programlamaya başlangıç http://yazilimdersi.info/makaleler/detay/8/eclipse-ile-android-programlamaya-baslangic Thu, 10 Jul 2014 00:00:00 +0000 mstfchelik
    1. Android SDK indirin ve kurun
    • Android SDK yi linke tıklayarak indirin.
    • Android SDK yi indirdikten sonra zip dosyasından çıkarıp C:\ dizini altına bırakın. Şu an dosyanızın dizini şu şekilde olmalı ( C:\android-sdk-windows tabiki windows işletim sistemine sahip cihazlar için)
    • SDK yi indirdiginiz dizine gidin ve SDK Manager.exe dosyasını göreceksiniz. Bu dosyaya tıklayarak farklı Android SDK dosyalarını görüntüleyebilirsiniz. AVD : Android Virtual Device ifadesinin kısaltmasıdır. Bu dosya programlarınızın emulatorler üzerinde çalıştırılmasını sağlamaktadır. Bu dosya üzerinden bilgisayarınızda farklı özellikte bir çok telefon ve tablet emulatoru oluşturabilir ve testlerinizi direkt programlama yaparken gerçekleştirebilirsiniz.
    • SDK Manager sayfasında birçok farklı versiyonda Android SDK leri görebilirsiniz. Bunların tümünü indirmenize gerek yoktur. Sadece sizin için gerekli olan SDK yi indirmeniz gerekmektedir. Aksi takdirde tüm SDK lerin indirilmesi uzun sürmektedir.

    • Listelemede bulunan herhangi bir SDK versiyonuna tıklayıp install butonuna tıklayıp bilgisayarınıza indiriniz.
         Bu işlemlerle birlikte Android SDK kurulumu bilgisayarınızda gerçekleştirilmiş oldu. Şimdi sırada diğer adımları izlemeye geldi.

    2. Eclipse programını indirin
         Android geliştirmesi sırasında kullanabileceğiniz birçok IDE bulunmaktadır. Ancak bunlardan en çok dikkat çekenleri Android Studio ve Eclipse programlarıdır. Android Studio Google tarafından geliştirilen yakın zamanda piyasaya çıkan bir editördür. Bazı eksikleri halen bulunsa da sadece Android geliştiriciler için kurgulandığından Eclipse programına göre daha etkin bir geliştirme imkanı sunacağı dikkat çekmektedir. 
    • Eclipse programını indirmek için linke tıklayınız.

    3. Android Development Toolkit (ADT) pluginin kurulması
    • Eclipse programını açınız ve menüde bulunan Help->Install New Software linkine tıklayınız. 
    • Bu menüye tıklamanız ile birlikte Available Software başlıklı bir dialog açılacaktır. Work with ifadesinin yanında bulunan Add butonuna tıklayınız.Açılan dialogta Name alanında ADT Location alanına ise https://dl-ssl.google.com/android/eclipse/ yazınız. OK butonuna basmanızla birlikte ADT plugini ile alakalı dosyalar Available Software sayfasında listelenecektir. Select all ile tüm paketleri seçiniz ve en altta bulunan Finish butonuna tıklayarak entegrasyonu tamamlamış olun. 

    4. Örnek Android projesi oluşturmak
         Android proje geliştirme ile alakalı gerekli ortam yukarıdaki maddelerle birlikte hazırlanmış oldu. Şu an örnek olacak seviyede bir uygulama geliştirelim. 
    • Öncelikle Menüde bulunan File seceneginden New secenegine tıklayın. Burada Android Application Project başlığı altında herhangi bir seçenek görmüyorsanız. Other... seçenegine tıklayın ve açılan pencerede Android klasörü altında listelenen Android Application Project secenegine tıklayın. 
    • Bu seçeneği seçmenizle birlikte New Android Project baslıklı bir pencere açılacaktır. Bu pencerede uygulamanın ismi, proje ismi,paket ismi,minimum ve maximum desteklenecek versiyon ile geliştirme süresince kullanılacak versiyon bilgilerinin girilmesi gerekmektedir. 
    • Yeni projenin eklenmesi ile birlikte Project Explorer alanında HelloWorld isimli projemiz listelenecektir. 
    5. Android Virtual Device (AVD) oluşturulması
         Oluşturulan projenin emülatörde çalıştırılması için AVD kurulumunu 3.adımda gerçekleştirmiştik.Şimdi projemiz için oluşturacağımız emülatör ile alakalı detaylı bilgileri girmemiz gerekmektedir. 
    • Eclipse programında Menü altında bulunan Android Virtual Device Manager butonuna tıklayın.
    • Açılan dialog daha önceden hiç emülatör eklemediğiniz için şekildeki gibi boş listelenecektir. Projeniz için yeni emülatör oluşturmak için New... butonuna tıklayın ve resimde görülen alanlara AVD ye vereceginiz ismi ve destekleneceği versiyonla alakalı bilgileri giriniz. Burada önemli olan konu projeyi oluştururken kullandıgınız SDK versiyonu ile ekleyeceğiniz AVD ye ait SDK versiyonun aynı olmasıdır. Aksi takdirde uygulamayı çalıştırmak istediginiz uygun AVD bulunamadığı ile alakalı bir uyarı ile karşılaşabilirsiniz. 
    6. Android projenin çalıştırılması
         AVD nin oluşturulması ile birlikte uygulamamızı test etmeye hazırız. 
    • Project Explorerde bulunan projenizin üzerine gidip sağa tıklayın ve Run As -> Android Application seçeneğine tıklayınız.
    • AVD, uygulamayı çalıştırmayı istediğiniz emülatörü seçmeniz ile alakalı pencere açacaktır. Burada isterseniz en altta bulunan Run Configurations alanına tıklayarak Target secenegi altından projenizin USB Debugging ile cihazınızda çalıştırılması konusunda da talimat verebilirsiniz. Bu alanda yapılan konfigürasyonlar her uygulamayı çalıştırmak istediğinizde size emülatör seçimi ile alakalı pencerenin açılmasını engelleyecektir. 
    • Emülatörün açılması ile birlikte HelloWorld başlıklı uygulamamızı ekranda görebilirsiniz.
    ]]>