Android : JSON ve PHP Web Servis İşlemleri
Merhabalar,
Bu yazımda sizlere Android’te en çok kullanılan JSON veri değişimi biçimi ile bir PHP web servisinin haberleşmesini, sunucuda bulunan veri tabanına veri eklemeyi ve bunları uygulamamıza çekme işlemlerini anlatmaya çalışacağım.
Yukarıdaki şekilde işlemin hayat döngüsü görülmektedir.
Web servisimizin barınacağı sunucumuzu daha önceki yazımızda göstermiştik. Şimdi sunucumuzda basit bir veritabanı oluşturup bu veritabanına Android uygulamamız ile veriler göndereceğiz. Veri gönderme işlemleri sonunda da dilersek uygulamayı otomatik güncelleyerek yeni listemizi, istemezsek kendi yenileme talebimizle listemizin yeni halini görüntüleyebileceğiz. Android ile sunucu arasındaki veri alışverişini JSON veri değişim biçimi ile gerçekleştireceğiz.
İlk olarak oluşturduğumuz veritabanına göz atalım ve veritabanına bağlantı sağlayan dbConfig.php dosyamızı yazmaya başlayalım. Aşağıdaki görselde adım adım veritabanı oluşturulması bulunmaktadır.
Artık veritabanımızda adı liste olan bir tablomuz ve bu tablomuzun id ile isim sütunları bulunmaktadır. Android uygulamamızda bu listeye her defasında listede olmayan bir isim ekleyeceğiz. Aynı isimden bir tane daha olmayacak şekilde kontrolümüzü yapacağız. Aşağıdaki kodlar ile oluşturacağımız dbConfig.php dosyasını Filezilla programı ile sunucumuza atarak veritabanına bağlantımızı sağlayabiliriz. Bu dosyayı hangi php dosyası içerisinde çağırırsak artık o dosyadan veritabanı işlemi gerçekleştirebiliriz.
dbConfig.php
//mysql_connect fonksiyonu sırasıyla 3 parametre alır //sunucu adresi, kullanıcı adı ve şifre $dbBaglanti=@mysql_connect("sql308.byethost4.com","b4_16062720","şifreniz") or die("Server baglanti saglanilamadi."); if($dbBaglanti) { //mysql select db fonksiyonu 2 parametre alır //1.si kullanılacak veritabanı adı //2.si üst kısımda gerçekleştirilen bağlantıdır. mysql_select_db("b4_16062720_1",$dbBaglanti) or die("Database baglanti saglanilamadi."); }
Android uygulamamız içerisinde web servis olarak 2 sayfa ile işlem gerçekleştireceğiz. ekle.php ve getir.php, bu sayfalar adından da anlaşıldığı gibi sunucumuzdan uygulamamıza verileri getirecek ya da uygulamadan sunucuya veri göndermemizi sağlayacaktır. Şimdi bu dosyaları da oluşturup tüm php dosyalarımızı sunucuya Filezilla ile yüklüyoruz.
ekle.php
<?php //Veritabanı bağlantı dosyamızı include ettik. include('dbConfig.php'); //Android uygulamamızdan verilerimizi POST metodu ile gönderelim //o yüzden burada da POST ile karşılayacağız. Ancak biz doğrudan //web üzerinden de testlerimizi yapabilmek adına 2 durumuda kontrol edelim. //eğer post edildiyle post ile get edildiyse get ile alsın. if(isset($_POST['eklenecekVeri'])) $sunucuyaGelenVeri = $_POST['eklenecekVeri']; else $sunucuyaGelenVeri = $_GET['eklenecekVeri']; //Şimdi bu verinin daha önce kayıtlı olup olmadığıma bakalım. //Mysql num rows fonksiyonu veritabanında kayıt varsa satır //sayısını getirecektir. Yoksa 0 döndürecektir. Eğer gelen veri //daha önce kayıt edilmediyse 0 dönmelidir. $sorgu1 = "SELECT * FROM liste WHERE isim='".$sunucuyaGelenVeri."'"; $sorgu1Sonuc = mysql_query($sorgu1); $sonuc = mysql_num_rows($sorgu1Sonuc); $sonucDizisi = array(); /* Android uygulamaya göndereceğimiz sonuçlar şu şekilde olsun; 1 - Bu isim zaten kayıtlı. 2 - Kayıt başarılı. 3 - Kayıt işlemi başarısız. */ if($sonuc>0){ $sonucDizisi['basarilimi'] = 1; echo json_encode($sonucDizisi); //JSON tipi olarak sonuç gösterilir. } else{ //Bu isimde kullanıcı yoksa kayıt işlemini gerçekleştirelim. //mysql_query fonksiyonu içerisindeki sorguyu gerçekleştirir ve //işlem başarılıysa true değilse false döndürür. $sorguKayit = "INSERT INTO liste (isim) VALUES('".$sunucuyaGelenVeri."')"; $kayitOlduMu = mysql_query($sorguKayit); //sorgudan sonra işlemi kontrol edelim. if($kayitOlduMu){ $sonucDizisi['basarilimi'] = 2; echo json_encode($sonucDizisi);//JSON tipi olarak sonuç gösterilir. } else{ $sonucDizisi['basarilimi'] = 3; echo json_encode($sonucDizisi);//JSON tipi olarak sonuç gösterilir. } } mysql_close(); ?>
getir.php
<?php //Veritabanı bağlantı dosyamızı include ettik. include('dbConfig.php'); //Burada herhangi bir veri gelmeyecek sadece mevcut verileri döndüreceğiz. $sorgu2 = "SELECT * FROM liste"; $sorgu2Sonuc = mysql_query($sorgu2); $sonucDizisi['donenVeriler'] = array(); /* basrili 1 basarisiz 0 */ if($sorgu2Sonuc){ //while ile veritabanından çekilen tüm satırları sırayla her adımda diziye //atıyoruz ve ardından json ile göndereceğiz. while($geciciDizi = mysql_fetch_array($sorgu2Sonuc)){ $temp['tag'] = $geciciDizi['isim']; array_push($sonucDizisi['donenVeriler'], $temp); //burada, oluşturduğumuz temp dizisiyle veritabanının 'isim' sütunundan gelen //veriler her adımda sonuc dizimize eklendi. Ve bir json array oluşmuş oldu. } $sonucDizisi['basarilimi'] = 1; echo json_encode($sonucDizisi); //işlem başarılı olduysa basarilimi tag'ımıza da değerimizi atadık ve json ile değerleri //döndürdük. Başarılı olmazsa devam eden kod bloğunda başarısız oldugunu uygulamamıza bildirdik. } else{ $sonucDizisi['basarilimi'] = 0; echo json_encode($sonucDizisi); } mysql_close(); ?>
Sayfalarımız oluşturduktan sonra sayfalarımızın çalışıp çalışmadığını deneyelim.
“http://adresimiz.byethost4.com/ekle.php?eklenecekVeri=oguzhan” şeklinde ekleme işlemi gerçekleştiriyoruz. Sonuç olarak ekranda eğer “basarilimi=2” dönüyorsa işlemimiz başarılı olmuştur. Ardından aynı adresimizin “/getir.php” sayfasına gidiyoruz, karşımıza bir json array ve basarilimi=1 şeklinde json objesi gelecektir. Bu ifadeleri Android uygulamamızda parse ederek projemizi tamamlayacağız. Artık Android uygulamamıza geçebiliriz. Android uygulamamızda 1 activity üzerinden hem ekleme hemde listeleme işlemlerini gerçekleştireceğiz.
JSONParser.java
package com.ogzhnozdmr.getdatawithjson; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URLEncodedUtils; 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 = ""; public JSONParser() { } //Bu sınıfın kullanacağımız fonksiyonu makeHttpRequest'tir. Burada paraetre olarak işlem yapılacak servisin adresi, methodu ve varsa gönderilecek veriler alınır. //Kullanımı esnasında daha iyi anlayacağız. public JSONObject makeHttpRequest(String url, String method, List<NameValuePair> params) { try { if(method == "POST"){ DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(params)); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } else if(method == "GET"){ DefaultHttpClient httpClient = new DefaultHttpClient(); String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { 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()); } try { jObj = new JSONObject(json); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } return jObj; } }
activity_main.xml dosyamızda 1 tane edittext, 2 tane buton ve 1 tane listview olacak şekilde bir arayüz oluşturuyoruz.
<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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.ogzhnozdmr.getdatawithjson.MainActivity" > <EditText android:id="@+id/isim" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:ems="10" android:inputType="textPersonName" > <requestFocus /> </EditText> <Button android:id="@+id/ekle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/isim" android:layout_below="@+id/isim" android:text="Veri Ekle" /> <Button android:id="@+id/yenile" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/ekle" android:layout_below="@+id/ekle" android:text="Listeyi Yenile" /> <ListView android:id="@+id/listem" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/yenile" android:layout_below="@+id/yenile" > </ListView> </RelativeLayout>
MainActivity.java
package com.ogzhnozdmr.getdatawithjson; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends Activity { //Sayfamızda bulunan arayüz elemanlarını yazıyoruz. Button btnVeriEkle, btnListeYenile; EditText veriAlani; ListView tumVerilerListesi; //JSON verilerini parse edebilmek için kullanacağımız json parser nesnesi. public JSONParser jsp = new JSONParser(); //yenileme işlemi ve ekleme işlemi sırasında ekranda görüntüleyeceğimiz progress dialog public ProgressDialog pDialog; //Gelen verileri listede tutalım List<String> veriler = new ArrayList<String>(); //Web servis adreslerimiz: String ekleServis = "http://myexamplepage.byethost4.com/ekle.php"; String getirServis = "http://myexamplepage.byethost4.com/getir.php"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Şimdi bu arayüz nesnelerini xml dosyamızdaki nesnelerle birbirine bağlayacağız. btnVeriEkle = (Button)findViewById(R.id.ekle); btnListeYenile = (Button)findViewById(R.id.yenile); tumVerilerListesi = (ListView) findViewById(R.id.listem); veriAlani = (EditText)findViewById(R.id.isim); //öncelikle ekleme ve yenileme işlemlerini arkaplanda yapacağımız 2 sınıf oluşturacağız. //bu sınıfları mevcut namespace içerisinde yapabiliriz. //ekle ve getir sınıfları olsun. btnVeriEkle.setOnClickListener(new OnClickListener() { //veriekle butonunun click olayında Ekle classı çalışacak @Override public void onClick(View v) { new Ekle().execute(ekleServis); } }); btnListeYenile.setOnClickListener(new OnClickListener() {//yenile butonunun click olayında ise Getir classı çalışacak. @Override public void onClick(View v) { new Getir().execute(getirServis); } }); } public class Ekle extends AsyncTask<String, Void, Integer>{ //Bu sınıf AsyncTask sınıfından kalıtım alır, bu sınıf hakkında daha sonra bir yazı yazacağım. //Alınan ilk parametre içerisine verilecek değeri temsil eder biz de string olarak aresi gondereceğiz. //2.parametreyi şimdilik kullanmayacağız son parametre ise post execute fonksiyonuna gönderilecek değer. //Aşağıda bulunan methodlar kalıtım alınan sınıfın kendi fonksiyonlarıdır. @Override protected void onPreExecute() { super.onPreExecute(); //Burada arkaplan işlemi başlarken ne yapılacağı söylenir. Bizde progress //dialogumuzu burada göstereceğiz ve işlem sonuna kadar sürdüreceğiz. pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Ekleniyor.."); //görünecek mesaj pDialog.setCancelable(false); pDialog.show(); } @Override protected Integer doInBackground(String... params) { //params bir string dizidir burada, params[0] bizim execute ederken vereceğimiz servis adresi oalcaktır. // Arkaplan işleminin gerçekleştiği kısımdır. hiç bir şekilde arayüze müdahale edilemez. int sonuc = 0; List<NameValuePair> sendParams = new ArrayList<NameValuePair>(); //Buradaki kodda servisimizde bizi karşılayacak olan tag isminiı ve ne gönderileceğini ifade ediyoruz. //myexamplepage.byethost4.com/ekle.php?""eklenecekVeri""=deneme sendParams.add(new BasicNameValuePair("eklenecekVeri", veriAlani.getText().toString())); //Bu method biz bir json objesi döndürecek ve bu json objesi üzerinden tüm verilere ulsacağız. //ekleme işleminde sadece basarili olup olmadıgını ifade eden bir data döndürüyorduk. //POST GET olması farketmez servisimizde 2 durumda yazmıştık. JSONObject myObject = jsp.makeHttpRequest(params[0], "POST", sendParams); try { sonuc = myObject.getInt("basarilimi"); //web servisinde belirttiğimiz tag return sonuc; } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Integer result) { // Arkaplanda yapılan işlem sonunda arayüze müdahale etmek istenirse şlem burada gerçekleştirilebilir. //Ayrıca doInBackground methodunda gerçekleştirilen işlem sonunda dönen değer buraya gelecektir. super.onPostExecute(result); //1, 2 ve 3 değerlerinin ne ifade ettiğini web servisimizde belitmiştik. Öncelikle progress dialogumuzu kapatıp //ardından dönen veriye göre kullanıcıya bilgi vereceğiz. pDialog.dismiss(); if(result == 1){ //Toast kullanıcıyı bilgilendiren kısa mesaj alanıdır. Toast.makeText(getApplicationContext(), "Bu isim zaten kayıtlı.", Toast.LENGTH_SHORT).show(); }else if(result == 2){ Toast.makeText(getApplicationContext(), "Kayıt işlemi başarılı.", Toast.LENGTH_SHORT).show(); }else if(result == 3){ Toast.makeText(getApplicationContext(), "Kayıt işlemi başarılı değil.", Toast.LENGTH_SHORT).show(); } } } public class Getir extends AsyncTask<String, Void, Integer>{ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(MainActivity.this); pDialog.setMessage("Yenileniyor.."); //görünecek mesaj pDialog.setCancelable(false); pDialog.show(); } @Override protected Integer doInBackground(String... params) { int sonuc = 2; List<NameValuePair> sendParams = new ArrayList<NameValuePair>(); //getirme işleminde herhangi bir veri göndermeyeceğiz o yuzden sendparams boş gönderiyoruz. //işlem sonunda bir json objesi dönecek bu onbje içerisinde isimelrin bulunduğu //bir json array ve basarilimi ifadesini tutacak eğer başarılı ise verileri getireceğiz. //yine params[0] adresi göndereceğiz. JSONObject myObject = jsp.makeHttpRequest(params[0], "POST", sendParams); try { sonuc = myObject.getInt("basarilimi"); //web servisinde belirttiğimiz tag //1 basarili 0 başarısız demiştik web servisimizde if(sonuc==1) { //listeyi temizleyelim; veriler.clear(); JSONArray tempArray = myObject.getJSONArray("donenVeriler"); //sunucudan dönen 'donenVeriler' tag lı diziye ulaşıyor ve onu dizimize atıyoruz. Burada gelen //her 1 nesne json objesidir. ve bu nesneler içerisinde de servisimizde aşağıdaki gibi ifade ettiğimiz /*$temp['tag'] = $geciciDizi['isim']; array_push($sonucDizisi['donenVeriler'], $temp); bu koddaki tag'lara ulasarak verileri alacağız. Daha açık bir ifadeyle önce tüm diziye ardından dizi içerisindeki taglara ulasacagız her tag bir isim tutmaktadır. */ for (int i = 0; i < tempArray.length(); i++) { //ilk başta oluşturduğumuz listeye her adımda gelen isme tag ile ulaşarak gönderiyoruz. veriler.add(tempArray.getJSONObject(i).getString("tag")); } } return sonuc; } catch (Exception e) { e.printStackTrace(); } return sonuc; } @Override protected void onPostExecute(Integer result) { // Burada işlem başarılı ise artık listemizde verileri göstereceğiz.Ve progress diyalogumuzu kapatacagız. super.onPostExecute(result); pDialog.dismiss(); if(result == 1){ //ListView'da verileri gösterebilmek için öncelikle adapter e ihtiyacımız var. Basit bir adapter yazalım. //MainActivity içerisinde göüntülenecek, simple list item turunde yani sadeceyazı seklinde görüntülenecek, //içerisine veriler listesini alacak şekilde bir adapter yazdık. ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this,android.R.layout.simple_list_item_1,veriler); tumVerilerListesi.setAdapter(adapter); }else{ Toast.makeText(getApplicationContext(), "kayıtlar getirilemedi.", Toast.LENGTH_SHORT).show(); } } } }
Bu işlemleri tamamladıktan sonra unutmadan internet iznimiz olmadan bu uygulama çalışmayacaktır, bu yüzden Manifest.xml dosyamıza;
<uses-permission android:name=”android.permission.INTERNET”/> satırını eklemeyi unutmuyoruz. Uygulamamızın son haliyle yazımı sonlandırıyorum. Soru görüş ve kod istekleriniz için mail atmanız yeterlidir. İyi çalışmalar.. 🙂
Hocam acaba php nin hangi sürümünü kullanıyoruz burda web alanı alırken sorun olmasın mysql_connect sanırım php7 de hata veriyor belli bi surumden sonra
Henüz 7 yi kullanmadım. Ancak doğrudan PHP’yi frameworksüz de kullanmıyorum. Bu gibi sıkıntıları yaşamamak adına Codeigniter kullanıyor ve tavsiye ediyorum.
hocam merhaba bu uygulamının exe dosyalarını benimle paylaşabilir misiniz sayenizde yeni yeni öğreniyorum
Merhaba
Eski uygulamaların APK dosyalarını ve Kodlarını maalesef harici diskimin bozulmasından dolayı kaybettim. Kodları yazarak tekrar derlemenizi tavsiye ederim bir problemle karşılaştığınızda yardımcı olmaya çalışırım.
Teşekkürler.
Merhaba güzel anlatım olmuş
Bu şekilde serverda veri tabanına veri eklendiğinde , silindiğinde yada güncelleme yapıldığında web servis ile bu verileri hosting deki bir uygulamaya gönderim yapabilir miyiz
Tabi ki,
Web servis ile sunucu üzerindeki herhangi bir uygulamaya işlem yapacak şekilde bir metot oluşturabilir ya da belirli sürelerde çalışıp kontrol edecek ve işlem yapacak bir cron oluşturulabilir.