toast etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
toast etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

22 Haziran 2012 Cuma

Android Programlama XIX - Servis Kullanımı

Herkese merhaba!

Bu yazımda sizlere servis kullanımını anlatmaya çalışacağım. Servis kullanarak uygulamanıza arka planda çalışacak özellikler ekleyebilirsiniz. Bu yazıda yazacağımız uygulama arka planda çalışacak ve düzenli aralıklarla ekrana sistem tarihini ve saatini yazdıracak.

ServisOgreniyorum isimli bir proje oluşturarak işe başlayalım.

Projeyle beraber oluşturduğumuz ana etkinliğin tasarımını yaparak işe başlayalım. Servisi durdurup başlatmak için bir düğme ekleyelim. Layout dosyamız aşağıdaki gibi görünmeli.
Kullanacağımız metinleri belirlediğimiz strings.xml dosyamız da şöyle görünmeli.
Şimdi servis sınıfımızı oluşturalım. Ana etkinlik dosyamızdan bir kopya oluşturup içeriğini aşağıdaki gibi değiştirelim.
Projemizin temelleri hazır. Şimdi ana etkinliğimizi açıp servisi başlatıp durdurmakla ilgili kodları yazarak başlayalım.

İlk iş olarak eklediğimiz düğmenin tıklama olayını oluşturalım.
Bu düğmeye tıklandığında servis durdurulmuş haldeyse servis başlatılacak, başlatılmış haldeyse durdurulacak. Bunun için servisin çalışıp çalışmadığını kontrol etmemiz gerekiyor. Haydi bunun için bir metod yazalım.
Bu metod çağrıldığında eğer servisimiz çalışıyorsa geriye true döndürülecek. Eğer çalışmıyorsa false döndürülecek.

Bunun için bir ActivityManager nesnesi oluşturup sistemin etkinlik servisini alıyoruz. Java'nın gelişmiş for döngüsü yapısını kullanarak getRunningServices() metodu ile sistemde çalışan tüm servisleri alıyoruz. Bu metodun döndürdüğü RunningServiceInfo nesnelerinden oluşan dizi içinde servis isimli değişken ile dönüyoruz. Döngü sırasındaki servis nesnesinin paket adı, bizim uygulamamızın paket adına eşitse bizim servisimiz çalışıyor demektir. Bu mantığı kullanarak tüm çalışan servisleri geziyoruz ve bizim servisimiz çalışıyor mu kontrol ediyoruz.

Şimdi tıklama metodumuzun içini dolduralım ve yazdığımız metodu da kullanalım.
Temel mantık bu şekilde olacak. Servis başlatılacağı zaman ilgili metod çağrılacak ve düğmenin üzerindeki yazı durdur yazısına çevrilecek. Servis durdurulacağı zaman da tam tersi yapılacak.

Oluşturduğumuz tıklama olayının parametresi (daha önceki yazılarda bahsettiğim gibi) üzerine tıklanan nesneyi temsil ettiği için v nesnesini Button türüne dönüştürerek dugme ismiyle saklıyoruz. Daha sonra bu nesne üzerinden yazı değişikliğini yapıyoruz.

Tıklama olayımızın kodları bittiğinde aşağıdaki gibi görünmeli.
Şimdi etkinliğin onCreate() metoduna da bir ekleme yapalım. Servis arka planda çalışacağı için servisin çalışıp çalışmama durumuna göre uygulama başlangıcında düğmenin üzerindeki yazıyı belirlememiz gerekiyor. Bunun için aşağıdaki gibi bir ekleme yapıyoruz.
Şimdi servisimizin kodlarını yazalım.

İlk önce düzenli aralıklarla iş yapmak için bir Timer nesnesi ve servis içinden ekrana Toast ile yazı yazabilmek için bir Handler nesnesi tanımlayalım.
Eksik import bilgilerini Ctrl + Shift + O ile ekleyelim. Burada Eclipse birden fazla Handler sınıfı bulduğu için bize hangisini eklemek istediğimizi soracak. Bizim ihtiyacımız olan android.os.Handler olacak.
Şimdi de zamanlayıcının çalışacağı aralığı bir sabit olarak belirleyelim. Buraya milisaniye cinsinden bir zaman belirtmemiz gerekiyor. (1 sn = 1000 ms) Örneğin ben 10 saniyede bir çalışmasını istedim.
Şimdi servisimiz oluşturulduğunda çalıştırılacak onCreate() metodu içinde bu nesnelerimize ilk değerlerini verelim.

yardimci nesnesine uygulamanın ana Looper nesnesini atıyoruz. Böylece bu Handler nesnesine göndereceğimiz bilgiler, içinde bulunduğumuz sınıf yerine (bu durumda bizim servisimiz) uygulamanın kendisi üzerinde işletilecek. Eğer bunu yapmazsak servis sınıfı içinden Toast nesnesi ile bilgi vermemiz mümkün olmayacak.

Şimdi zamanlayıcımıza bir görev verelim. Bunun için TimerTask türünden bir nesneye ihtiyacımız olacak. Ama biz bunu metod çağrısı içinde bir iç sınıf (inner class) oluşturarak yapacağız. Haydi başlayalım.

zamanlayici nesnemiz üzerinden scheduleAtFixedRate() metodunu çağırıyoruz ve parametre olarak yeni bir TimerTask iç sınıfı oluşturuyoruz. Burada Eclipse'in bize sağladığı imkanlardan faydalanacağız.

zamanlayici yazıp yanına bir nokta koyduktan sonra Eclipse bize kullanabileceğimiz metodları listeliyor. Buradan scheduleAtFixedRate() metodunu seçiyoruz.


Daha sonra ilk parametreye new yazıp bir boşluk bırakıyoruz ve Ctrl + Boşluk tuşlarına basıyoruz. Eclipse bize yazıyor olduğumuz parametreyle ilgili önerilerde bulunuyor. Buradan yeni bir iç sınıf oluşturacağız. Anonymous Inner Type seçeneğini seçiyoruz.

 Gördüğünüz gibi iç sınıfımız oluşturuldu.

Şimdi diğer parametreleri değiştiriyoruz ve metod çağrısını sonlandıran parantezin sonrasına ; işaretimizi koyuyoruz.


Burada yazdığımız ikinci parametre zamanlayıcının ne kadarlık bir gecikmeyle işe başlayacağını, üçüncü parametre ise ne kadar zamanda bir zamanlayıcının tekrar çalışacağını belirtiyor. Ben 0 ms gecikme ile ve daha önce belirlediğim 10 sn zaman aralığıyla çalışması gerektiğini belirttim.

Şimdi bu belirttiğimiz özelliklerle yapılacak işi tanımlayalım. Yazının başında belirttiğim gibi bu uygulama düzenli aralıklarla sistem tarihini ve saatini ekrana yazdıracak.

Şimdi bu iş için bir metod oluşturalım.


Gördüğünüz gibi belirttiğimiz aralıklarla bu metod çağrılacak ve ekranda bilgi gösterilecek.

Şimdi bilgiyi belirli bir biçimde göstereceğiz.

Burada Java'nın sunduğu imkanlardan faydalanacağız. İlk önce sistem zamanını alalım. (Bunu bildirim kullanımını anlattığım yazıda kullanmıştık.)


Şimdi bu zamanı kullanarak istediğimiz biçimde bilgi oluşturacağız. Bunun için SimpleDateFormat sınıfından faydalanacağız. Boş bir SimpleDateFormat nesnesi oluşturduktan sonra istediğimiz biçimi belirliyoruz. (SimpleDateFormat için kullanılabilecek biçimlerle ilgili daha fazla bilgiyi internette bulabilirsiniz, ben detaylara girmeyeceğim.)


Şimdi belirlenen biçimi kullanarak bir bilgi oluşturalım. Bunun için SimpleDateFormat nesnemiz üzerinden format() metodunu çağırıyoruz ve gerekli parametre için sistem zamanını kullanarak oluşturduğumuz bir Date nesnesi veriyoruz.


Artık sonuc isimli String bizim istediğimiz şekilde biçimlenmiş tarih ve saat bilgisini içeriyor. Şimdi bunu ekranda göstereceğiz. Bunun için önceden oluşturduğumuz Handler nesnemiz üzerinden post() metodunu çağıracağız ve parametre olarak Runnable türünde bir iç sınıf oluşturacağız.


Artık Toast kullanarak bilgiyi ekranda gösterebiliriz.


Burada bir hata aldık, Eclipse bize sonuc isimli Stringin final olarak belirlenmesi gerektiğini söyledi. Bunun nedenini tam bilmiyorum, o yüzden detaylı anlatamayacağım. Hatayı bu şekilde çözebiliriz.


İşimiz bitti gibi görünüyor ama aslında bitmedi. :) Şu an uygulamayı çalıştırmaya kalkarsak servis durdurulduğunda hata alacağız çünkü zamanlayıcıyı durdurmadık. Haydi şimdi servis durdurulduğunda olacakları belirleyelim.

Servis sınıfımız içinde onDestroy() isimli metodu Override ederek yeniden yazacağız. Bunun için on yazıp Ctrl + Boşluk yapmanız yeterli. Eclipse size yardımcı olacaktır.


Metodu oluşturduktan sonra içine zamanlayıcıyı durduracak kodu ekliyoruz.


Artık işimiz bitti gibi. Son bir adım olarak yazdığımz bu servisi uygulamanın manifest dosyasına ekliyoruz.

Manifest dosyasını açtıktan sonra Application sekmesine geliyoruz. Application Nodes kısmındaki Add düğmesine tıklayıp Service seçeneğini seçiyoruz.

 Daha sonra yan taraftan Name alanının yanındaki Browse'a tıklıyoruz ve servisimizi seçiyoruz.

Manifest dosyasısnı kaydediyoruz.

Haydi şimdi uygulamamızı deneyelim! :)

Gördüğünüz gibi uygulamamız açıldı ve servis çalışmıyor durumda olduğu için düğmenin üzerinde Servisi Başlat yazıyor.


Düğmeye basıp servisi başlattığımızda istediğimiz biçimde oluşturulmuş tarihi ve saati göreceğiz.

Servis arka planda çalıştığı için uygulamadan çıksak bile belirlediğimiz 10 sn ardından tekrar ekranda tarihi ve saati göreceğiz.
Uygulama listesinden uygulamamızı tekrar çalıştırdığımızda ise servis çalışır durumda olduğu için düğmenin üzerinde Servisi Durdur yazıyor.
Bir yazının daha sonuna geldik.

Bu yazıda sizlere servis kullanımını elimden geldiğince anlatmaya çalıştım. Aslında birkaç özellik daha olacaktı yazdığımız uygulamada ama tuhaf sorunlarla karşılaştım. O yüzden yazıyı daha fazla uzatıp sizleri de sıkmamak adına bu kadar yazıp bitirdim.

Uygulamanın kodlarını buradan indirebilirsiniz.

İnşallah faydalı olmuştur.

Hepinize kolay gelsin, iyi çalışmalar. :)

7 Şubat 2012 Salı

Android Programlama VI - Birden Fazla Etkinlik (Activity) Kullanma, Aralarında Veri Aktarımı ve Toast Kullanımı

Herkese merhabalar.

Bu yazımda sizlere birden fazla etkinlik (activity) kullanmayı, bunlar arasında geçiş yapmayı, veri aktarmayı ve kullanıcıya bilgi vermek için Toast nesnesini kullanmayı anlatmaya çalışacağım.

Şu ana kadar yazdığımız uygulamalarda tek bir etkinlik vardı. Artık uygulamamıza birbirinden farklı etkinlikler ekleyerek uygulamamızın işlevselliğini artırabileceğiz.

Uygulamalar büyüdükçe burada her şeyi anlatmak zorlaştığı için artık üzerinde çalıştığımız projenin son halini gönderilerin sonuna ekleyeceğim. Böylece dosyayı indirip daha detaylı inceleyebilirsiniz.

Artık işe başlayalım. EtkinlikOgreniyorum isimli bir proje oluşturarak başlayabiliriz.

Bu seferki uygulamamız bir kayıt formu örneği. Girdiğimiz bilgileri bize farklı bir etkinlikte gösterecek.

Ayrıca bu seferki uygulamamızda 2 tane etkinlik olacağı için 2 ayrı tasarım yapacağız. O yüzden de main.xml dosyasının adını değiştirmenin uygun olacağını düşündüm. Bunu aşağıda görüldüğü gibi yapabilir ya da dosya seçiliyken F2 tuşuna basabilirsiniz.
İlk etkinliğimizin tasarımını içerecek dosyaya etkinlik_bir.xml ismini verdim. Yalnız dikkat edilmesi gereken bir nokta var. EtkinlikBir.java dosyası içinde hala main.xml dosyasına ulaşılmaya çalışılıyor. Bunu aşağıda görüldüğü gibi düzeltiyoruz yoksa hata almaya devam edeceğiz.
Şimdi ilk etkinliğimiz için tasarımımızı yapalım.

Biraz karışık bir tasarım olduğu için (beni baya uğraştırdı) her şeyi burada adım adım anlatamadım. O yüzden son halinden bir görüntü ekliyorum. İlk seferde aynısını yapamayabilirsiniz, gayet doğal. Gönlünüzden geldiği gibi bir tasarım da yapabilirsiniz. ;) Hiç anlamazsanız, projenin son halini gönderinin sonundan indirip, benim hazırladığım dosyaları da kullanabilirsiniz kendi projenizde. Seçim sizin.
Bu tasarımda nerede hangi nesnenin olduğunu merak edenler için Outline penceresinden bir ekran görüntüsü ekledim aşağıya.
Şimdi ilk etkinliğin tasarımını bitirdiğimize göre gelin 2. etkinliğimizi oluşturalım.

Yeni bir etkinlik oluştururken yapmanız gerekenler temelde şöyle; etkinlik için bir java sınıfı oluşturmak, o etkinliğin tasarımı için bir xml dosyası oluşturmak ve en önemlisi bu etkinlikle ilgili bilgiyi uygulamamızın manifest dosyasına eklemek.

Bu dosyaları elle de oluşturabiliriz ama elimizdekilerden yeni birer kopya çıkarsak işimiz kolaylaşabilir.

Bunu basitçe dosyamıza sağ tıklayıp Copy diyerek, daha sonra da o dosyanın bulunduğu dizine sağ tıklayıp Paste diyerek yapabiliriz. Daha sonra yeni dosyanın ismini de değiştirmeliyiz.

Dosyalara gerekli isimleri verdikten sonra içlerini açıp önceki etkinlikle ilgili yerleri silebiliriz.

Sıra ikinci etkinliğin de tasarımını yapmakta.
İkinci etkinliğe ait java dosyasında aşağıdaki değişikliği de yapmalıyız yoksa bu etkinliği çalıştırsak bile ilk etkinliğe ait tasarım dosyası kullanılacaktır.
Şimdi AndroidManifest.xml dosyasını açıyoruz. Application görünümünde aşağıda görüldüğü gibi Add tuşuna tıklıyoruz.
Etkinlik ekleyeceğimiz için Activity'yi seçiyoruz.
Aşağıda görüldüğü gibi eklenen etkinliğin adını ve başlığını seçmemiz gerekiyor. Browse tuşuna tıklıyoruz.
Yeni etkinliğimizi seçiyoruz.
Aynı şeyi başlık için de yapıp, strings.xml dosyası içindeki app_name'i seçiyoruz. Bu etkinliğin başlığının farklı olmasını isterseniz strings.xml içine bir girdi daha ekleyip burada onu da gösterebilirsiniz. Ben aynı başlığı kullandım.
Xml görünümüne geçersek AndroidManifest.xml dosyamızın şu an ne halde olduğunu görebiliriz.
Gördüğünüz gibi etkinliğimiz buraya eklenmiş.

Burada dikkatinizi çekmek istediğim bir yer var. Gördüğünüz gibi EtkinlikBir dediğimiz etkinliğimiz de burada. Ve tanımı içinde intent-filter diye etiketlenmiş bazı tanımlamalar var. Bu tanımlamalar uygulamanın bu etkinliği kullanarak başlayacağını belirtiyor. Yani uygulama EtkinlikBir isimli etkinlikten başlayacak.
Şimdi etkinlik_bir.xml dosyasını açıp eklediğimiz düğmelerin tıklanma olaylarını belirleyelim.
Aynı şeyi etkinlik_iki.xml dosyasında da yapalım.

Etkinlikler arasında veri aktarırken verilere bazı etiketler vereceğiz. Daha sonra biz bu etiketleri değiştirmek istersek sıkıntı yaşamayalım diye bu etiketleri sabit değerler olarak ayrı bir sınıf içinde tutmak mantıklı bir çözüm. Bunun için yeni bir sınıf oluşturuyoruz.
İçine etkinlikler arasında göndereceğimiz her veri için sabit değerler tanımlayalım.
Şimdi artık kodlama zamanı.

EtkinlikBir.java ile işe başlayalım.
Kullanacağımız nesnelere ait değişkenler oluşturduk ve bunları findViewById metodu ile belirledik.
Düğmelerin tıklanma metodlarını da yazalım.

Burada gönder düğmesi bilgileri ikinci etkinliğe gönderecek. Peki bunu nasıl yapıyoruz? Şöyle.

Etkinlikler arasında geçiş yapmak için Intent türünde bir nesneye ihtiyacımız var. Yukarıdaki görüntünün 40. satırında EtkinlikIki'ye geçmemizi sağlayacak bir Intent nesnesi oluşturuyoruz.

Daha sonra 41 ve 42. satırlarda bu Intent nesnesi içine ek bilgiler ekliyoruz. Uygulamamızdaki EditText nesnelerinin içindeki yazıları okuyup, bunları daha önceden oluşturduğumuz anahtar kelimelerle birlikte Intent nesnesine ekliyoruz.

Peki neden bir anahtar kelimeye ihtiyaç duyuyoruz? Cevap aslında basit. Daha sonra bu eklediğimiz bilgilere bu kelimeler yardımıyla erişeceğiz.

EditText nesnesinden String döndüğü için 43. satırda okunan değeri int türüne dönüştürerek Intent nesnesine ekliyoruz.

Daha sonra cinsiyet kısmında hangi düğmenin seçili olduğunu kontrol edip, seçili olan cinsiyete göre Intent nesnesine String türünde veri ekliyoruz. Bir RadioButton nesnesinin seçili olup olmadığını isChecked metoduyla kolayca öğrenebiliriz. Burada getString metodu ile daha önce strings.xml dosyasında tanımladığımız bir metini çekiyoruz. Yani eğer erkek seçiliyse "Erkek" şeklinde bir String gönderilecek Intent nesnesi aracılığıyla.

Aynı şekilde yazılan ileti de eklendikten sonra startActivity metodu çağrılıyor. Parametre olarak EtkinlikIki isimli etkinliği çağırmak üzere oluşturduğumuz Intent nesnesini verdiğimiz için bu satır bize ikinci etkinliği çalıştıracak. Bu arada ilk etkinlik arka planda bekliyor olacak.

Tüm bu kodları try ve catch bloğu içine yazdık, böylece bir hata olduğunda uygulamamız sonlanmadan bize bilgi verecek. Bu bilgiyi de başta değindiğim gibi Toast nesnesi kullanarak verecek.

Toast nesnesi ile kullanıcıya ekran üzerine açılan küçük bir pencerede bilgiler verebilirsiniz.

Burada Toast sınıfına ait makeText statik metodu, bize içinde bizim strings.xml dosyasında belirlediğimiz hata iletisi yazan bir Toast nesnesi oluşturuyor. Biz de direk bu nesnenin üzerinden show metodunu çağırarak bu bilgiyi gösteriyoruz.

Şimdi EtkinlikIki.java dosyasını açıp gerekli kodları yazalım.
Burada da gerekli nesneleri oluşturup değerlerini belirliyoruz. Değerleri belirledikten sonra yapılacak iş, bu etkinlik çalıştırılırken kullanılan Intent nesnesiyle beraber gönderilmiş bilgileri çekmek.
Intent nesnesine eklenen veriler bir paket halinde geldiği için önce getIntent metodu ile bu etkinlik açılırken kullanılan Intent nesnesini, daha sonra getExtras metodu ile bütün ek verileri, daha sonra da getString metodu ile String türündeki istediğimiz veriyi elde ediyoruz.

Bu etkinlikte bize verilecek bilgi cinsiyete göre değişeceğinden ilk önce cinsiyet kontrolü yaptık. Dikkat ederseniz ilk etkinlikteki cinsiyet bilgisini Sabitler.CINSIYET etiketiyle gönderdik, burada da aynı etiketle alıyoruz.

Diğer bilgiler de çok benzer şekilde alınabiliyor. Yaş bilgisine dikkatinizi çekmek isterim. String değil de int türünde gönderdiğimiz için getString yerine getInt metodu ile bilgiye erişiyoruz.

Tüm bilgileri alıp istediğimiz bilgi metnini oluşturduktan sonra bu etkinlikteki TextView nesnesine bu bilgiyi yazdırıyoruz.

Geri düğmesinin tıklama metodu içinde o anda açık olan etkinliği bitiren finish(); ifadesi yer almakta. Bu şekilde geri düğmesine tıklanıldığında açık olan EtkinlikIki sonlanacak ve arka planda bekleyen EtkinlikBir'e geri dönülecektir.
Yukarıda strings.xml dosyasının son halini görüyorsunuz.

Haydi artık uygulamamızı çalıştıralım. :)

Uygulamamız ilk çalıştığında böyle görünüyor.
Gördüğünüz gibi, boş ya da hatalı giriş yapıldığında bize Toast ile bilgi veriliyor ve uygulamamız hata verip sonlanmıyor.
Tasarım kısmını adım adım anlatamadığım için değinemediğim bir nokta oldu. Bu formu ekrana sığmadığı zaman kaydırabilmemiz için bir ScrollView nesnesi içine yerleştirmiştim. Bunu gösterebilmek için emulatördeki cihazı yan çevirdim. Bunu yapmak için Ctrl + F12 tuşlarını kullanabilirsiniz. Gördüğünüz gibi formu kaydırabiliyorsunuz.
Şimdi ekranı eski haline getirip bilgilerimizi girelim.
Gördüğünüz gibi bilgilerimiz girdikten sonra Gönder düğmesine tıklayınca ikinci etkinliğimiz açıldı ve girdiğimiz veriler bu etkinliğe gönderilip buradaki alana yazıldı.
Burada Geri düğmesine tıkladığımızda uygulamamız bir önceki ekrana geri dönecektir.

Evet arkadaşlar, bu yazımızdaki uygulamamız bu kadar. Bu yazıda uygulamamıza nasıl yeni bir etkinlik ekleyeceğimiz, bu etkinlikler arasında nasıl geçiş yapabileceğimizi, nasıl veri aktarabileceğimiz ve Toast aracı ile kullanıcıya nasıl bilgi verebileceğimiz öğrendik. En azından öyle umuyorum. :)

Bu yazıda yaptığımız uygulamanın projesini buradan indirebilirsiniz.

İnşallah faydalı olmuştur.

Kolay gelsin, iyi çalışmalar. :)