Json Ayrıştırarak Parse (Android Eclipse)
Merhabalar, bu uygulamamızda, hava durumu bilgisini Internet’ten JSON yapısında çekip, uygulamamızda göstermeyi öğreneceğiz.
Json Nedir?
Vikinin yalancısıyım, insanlar tarafından okunabilen bir veri değişimi biçimiymiş.
Aşağıdaki linke tıklarsanız nasıl bir şey olduğunu görebilirsiniz:
Linki analiz edecek olursak:
http://api.openweathermap.org/data/2.5/find => Hava durumu sorgusu yaptığımız link.
?q=Urla&units=metric => Sorguya eklediğimiz parametreler kısmı.
* q değişkeni hava durumunu sorguladığımız ilçe, başka değişkenlerde alıyor ama biz şimdilik ilçe adı kullanarak devam edelim.
* units değişkenini de metrik sistem kullandığımız için metric olarak verdik.
Şimdi gelelim bu linkin döndürdüğü JSON yapısını incelemeye:
{
-
message: “accurate”,
-
cod: “200”,
-
count: 1,
-
list:
[
-
{
-
id: 298316,
-
name: “Urla”,
-
coord:
{
-
lon: 26.76403,
-
lat: 38.322922
},
-
-
main:
{
-
temp: 25.14,
-
pressure: 1016,
-
humidity: 60,
-
temp_min: 23,
-
temp_max: 27
},
-
-
dt: 1412855400,
-
wind:
{
-
speed: 7.7,
-
deg: 40
},
-
-
sys:
{
-
country: “TR”
},
-
-
clouds:
{
-
all: 0
},
-
-
weather:
[
-
{
-
id: 800,
-
main: “Clear”,
-
description: “Sky is Clear”,
-
icon: “01d”
}
-
]
-
}
-
]
-
}
Girdiğimiz parametreler sonucu sorgu linki bize yukarıdaki gibi bir Json döndürdü. Burada görmüş olduğunuz üzere Urla’daki hava durumu bilgileri sunulmaktadır. Biz buradaki bütün bilgilere ihtiyaç duymuyoruz, o yüzden sadece işimize yarayan kısımları ayrıştırarak uygulamamızda kullanacağız.
Json YapısıJson’da küme parantezleri arasında{} olan her şey bir Json objesi olarak kabul edilir.O yüzden aslında linkten dönen şey kocaman bir Json objesi. Ve bu Json objesi içinde başka Json objeleri de tutabilir. Aynı zamanda Json array de tutabilir ve daha bir sürü şey, öyle değil mi viki?Şu veri tiplerini destekler:
- Number
- String
- Boolean
- Array
- Object
- null
İç içe geçmiş bu Json objelerini ve diğer veri tiplerini ayrıştırması çok kolaydır. İlk başta karmaşık gelebilir ama işin mantığını kaptınız mı artık Serkan is my girl diye değil Json is my boy diye ortalıkta rahatça dolanabilirsiniz.
Json’ımızı ayrıştırmadan önce bu yapıyı Android uygulamamızda kullanmak üzere Internet’ten nasıl çekeriz bir onu görelim. Internet’ten çekme işini adım adım anlatmayacağım, arkadaşlar sağolsunlar yazmışlar bir kod, onu kullanalım. Kısaca ne yapıyor anlatayım: parametre olarak verdiğimiz linkle sorgu atıyor cevap dönüyor sonra string formatında json’ımızı döndürüyor ki biz daha sonra ayrıştırıp kullanabilelim. Bu kodu bir sınıf olarak projemize ekleyelim hemen.
package com.example.havalarnasil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public static String getJSONFromUrl(String url) {
Log.e("URL", url);
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
Log.e("JSON Parser", "UnsupportedEncodingException " + e.toString());
e.printStackTrace();
} catch (ClientProtocolException e) {
Log.e("JSON Parser", "ClientProtocolException " + e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.e("JSON Parser", "IOException " + e.toString());
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// JSON'ı string olarak döndürüyoruz.
return json;
}
}
Kısayol: Bu kodu kopyalayıp, Eclipse’de projenizin src dosyasındaki paket’e yapıştır derseniz, siz sınıf yaratmadan direk JSONParser isimli bir sınıf projenize eklenecektir.
Bu arada ben projemizin adını HavalarNasil olarak belirledim, siz istediğiniz ismi verebilirsiniz. Ufaktan projeyi de açarsanız iyi olur, biraz geç söyledim ama. Benimki şu durumda:
HavaDurumu etkinliğimizin tasarım(layout) kısmını taslaktan(outline) da gördüğünüz üzere kabataslak bir şey yaptım:
cityname => EditText => Kullanıcıdan ilçe ismi almak için
weatherButton => Button => Tıklanıldığında , girilen ilçe ismi ile sorgu yapmak için
temperature => TextView => Sıcaklık derecesini göstermek için, şimdilik boş, sorgu sonrası dönen değer ile doldurulacak
description => TextView => Hava durumunu halk dili ile yazdırmak için, şimdilik boş, sorgu sonrası dönen değer ile doldurulacak
Bu tasarımı kendiniz yazsanız daha hoş olur, yukarıdaki temel widget’lar olsun içinde yeter. Ya da yazının sonunda linkten projeyi indirip inceleyebilirsiniz.
Tasarımı aşağı yukarı böyle bir şey:
HavaDurumu etkinliğimizde widgetlarımızı tanıtalım:
Internet’ten Json verisi çekebilmemiz için bir tane AsyncTask sınıfı yaratmamız gerekiyor.
AsyncTask sınıfının 3 tane override etmemiz gereken metodu var.
onPreExecute => Arka planda Internet’ten veri çekilirken, ön planda ne göstereyim abime? kısmı.
Genellikle progres dialog falan gösterilir, ben bunu şimdilik es geçiyorum.
doInBackground => Internet’ten json verimizi çekiyoruz.
onPostExecute => Çektiğimiz verileri ekranda gösteriyoruz.
UYARI: Arayüze dair herhangi bir işlemi sadece onPostExecute kısmında yapabiliriz. Yani TextView’larımıza çektiğimiz verileri sadece onPostExecute kısmında atayabiliriz. Yoksa patlar. Denedim %100 patlıyor. =)
AsyncTask sınıfımızı da butona tıklanıldığında çağırıyoruz. AsyncTask’ı doldurmadan son kez gösteriyorum:
Evet, şimdi gelelim Json verimizi ayrıştırma işlemine. Yukarıdaki Json’da uygulamamızda göstereceğimiz iki tane değer var: temp ve description. Bu değerlere ulaşmamız lazım.
temp, sırasıyla en baştaki Json objemizin// list adlı Json array’inin// ilk objesinin //main adlı Json objesinin//içindeki temp adında bir sayı. Vay vay vay! Neyse kodda, daha anlaşılır olacaktır, umarım.
İlk önce kullanıcının girdiği ilçe ismini linkimize parametre olarak ekleyelim. Ve de sorgu sonrası doInBackground’da çekeceğimiz sıcaklık(temp) değeri için bir tam sayı(tempNo) değişkeni oluşturalım.
Şimdi de ayıralım artık şu Json’ı, çok uzadı ayol. JSONParser sınıfımızın getJsonFromUrl metoduna linkimizi parametre olarak verip çağıralım ve dönen json string’inden baştaki objemizi çekelim.
Sonrasında adım adım yorumlarla nasıl temp değişkenine ulaşıyoruz, bakalım:
Evet, temp değerini ekrana onPostExecute kısmında bastıralım bakalım:
Son olarak AndroidManifest.xml ‘e Internet iznini eklersek, uygulamamız hazır olacak:
<uses-permission android:name=”android.permission.INTERNET”/>
Evet, Json ile Internet’ten veri çekip ayrıştırma işlemlerimiz burada sonra ermiştir.
En son görüntü:







