29/08/2015 14

Android ile bir Web Sitesinden Veri Okuma (Php & JSON)

Merhabalar;

Bu yazıda çoğu profesyonel uygulamalarda kullanılan web servis yardımıyıla internette herhangi bir siteden veri çekerek android yani client tarafında kullanmadan bahsedeceğim. Örneğin; bir haber uygulaması geliştiriyoruz.Fakat geliştirdiğimiz sitenin  RSS i yetersiz yada yok ise mecburen sitenin kaynağına inerek html tag larini parse etmemiz gerekecek. İşte bu noktada aslında kullanabileceğimiz çeşitli yöntemler var. En çok kullanılanlar ise Client yani Android tarafında JSOUP kütüphanesi kullanarak,diğeri de php ile bot yazıp sonuçları web servis ile almak. Ben ikisini de ayrı yazı olarak anlatmayı düşündüm.Ama ben genelde bu tarz projelerde web servisi tercih ediyorum.Tag lari parçalama kısmını tamamen web serviste halledip android tarafında sadece web servisi çağırmak kalıyor. Veriyi çekeceğimiz site muhtemelen bizim elimizde olmadığı için site sahibi bir tane bile tag değiştirse android tarafını oturup baştan düzenlememiz gerekicek.Ama bunun yerine bu işlemi serviste yapmak daha kolay.Özellikle de  php ile.

Şimdi bu yazıda yapacağımız örnek projeden bahsedeyim. Android kısmında sitemizdeki yazıları çekeceğiz.Tabi biraz php bilmek gerekiyor ama mantığı anlarsanız zorlanmazsınız.Çok karışık işler yapmayacağız. Siteden neleri çekeceğiz görsel olarak gösterelim:

Şimdi de çekeceğimz bu verilerin kaynaktaki kodlarını görelim.Hangi class da olduğu yada hangi id ye sahip vb. Sonrasında da web servisi yazmaya başlayacağız.

(Öğeyi denetle yaptığımızda gelen kodlar ile kaynaktaki kodlar farklı olabiliyor.Bot yazarken sonuç alamazsak kaynağı görüntüleyeceğiz.)

Şimdi web servisi yazmaya başlayalım.PHP ile bot yaparken aslında genelde 2 yol kullanılır. Birisi curl diğeri de  file_get_gontents metodu. Curl daha fonksiyonel . O yüzden curl kullanarak hazırlayacağım botu.Ama ilerleyen derslerde file_get_contents ile de bir yazı yazmayı düşünüyorum.

Şimdi artık web servisimizi oluşturalım. thecodeprogram.php olarak oluşturdum ben. Gerekli açıklamaları kodlar üzerinde yaptım :

thecodeprogram.php <?php header('Content-Type: text/html; charset=utf-8'); $curl_handle=curl_init(); curl_setopt($curl_handle, CURLOPT_URL,'http://www.thekodprogram.com/'); //Sitemizin URL adresi curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_USERAGENT, 'deneme'); $query = curl_exec($curl_handle); //Burada Curl çalışıyor ve linkteki bütün içerikler query değişkeninde tutuluyor. curl_close($curl_handle); //query değişkeninden almak istediğimiz kısmı bildiriyoruz. //Burada (.*?) ile belirtilen yer değişecek kısım.Yani anasayfada bir sürü yazı başlığı mevcut. //Bizde bunların değişebileceğini derleyiciye (.*?) ile bildirdik. $parcala_baslik='@<h2 class="post-box-title"><a href="(.*?)">(.*?)</a></h2>@si'; //Burada da query içinden istediğimiz kısmı parçalayıp $basliklar değişkenine atıyoruz. preg_match_all($parcala_baslik, $query, $basliklar); echo "<pre>"; print_r($basliklar); "</pre>"; ?>

Şuan başlıkları aldık fakat daha bitmedi tabiki.Çıktısını göstermek için koydum.Devam edeceğiz fakat yukarıdaki kod bloğu bize şu çıktıyı verdi : Gördüğümüz gibi array şeklinde sonuçlar aldık.İşte biz bu arraylarin indekslerini json dizimize atıp döndüreceğiz. Mantık basit arkadaşlar.Şimdi web servise özet ve resim için eklemeler yapalım:

Özet eklemesi ile web servis devam :

<?php header('Content-Type: text/html; charset=utf-8'); $curl_handle=curl_init(); curl_setopt($curl_handle, CURLOPT_URL,'http://www.thekodprogram.com/'); //Sitemizin URL adresi curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_USERAGENT, 'deneme'); $query = curl_exec($curl_handle); //Burada Curl çalışıyor ve linkteki bütün içerikler query değişkeninde tutuluyor. curl_close($curl_handle); //query değişkeninden almak istediğimiz kısmı bildiriyoruz. //Burada (.*?) ile belirtilen yer değişecek kısım. //Yani anasayfada bir sürü yazı başlığı mevcut.Bizde bunların değişebileceğini derleyiciye (.*?) ile bildirdik. $parcala_baslik='@<h2 class="post-box-title"><a href="(.*?)">(.*?)</a></h2>@si'; //Burada da query içinden istediğimiz kısmı parçalayıp $basliklar değişkenine atıyoruz. preg_match_all($parcala_baslik, $query, $basliklar); $parcala_ozet='@<p>(.*?)</p>@si'; //Özet için de query içinde arayacağımız kısımı bildirdik. preg_match_all($parcala_ozet, $query, $ozetler); print_r($ozetler); ?> Özetler için de çıktımız aşağıdaki gibi oldu. Şimdi son olarak da resimleri alalım. <?php header('Content-Type: text/html; charset=utf-8'); $curl_handle=curl_init(); curl_setopt($curl_handle, CURLOPT_URL,'http://www.thekodprogram.com/'); //Sitemizin URL adresi curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_USERAGENT, 'deneme'); //Burada Curl çalışıyor ve linkteki bütün içerikler query değişkeninde tutuluyor. $query = curl_exec($curl_handle); curl_close($curl_handle); //query değişkeninden almak istediğimiz kısmı bildiriyoruz. //Burada (.*?) ile belirtilen yer değişecek kısım. //Yani anasayfada bir sürü yazı başlığı mevcut. //Bizde bunların değişebileceğini derleyiciye (.*?) ile bildirdik. $parcala_baslik='@<h2 class="post-box-title"><a href="(.*?)">(.*?)</a></h2>@si'; //Burada da query içinden istediğimiz kısmı parçalayıp $basliklar değişkenine atıyoruz. preg_match_all($parcala_baslik, $query, $basliklar); $parcala_ozet='@<p>(.*?)</p>@si'; //Özet için de query içinde arayacağımız kısımı bildirdik. preg_match_all($parcala_ozet, $query, $ozetler); $parcala_resim='@<img width="(.*?)" height="(.*?)" src="http://www.thekodprogram.com/wp-content/uploads/(.*?)" class="(.*?)" alt="(.*?)">@si'; //Resimler için de query içinde arayacağımız kısımı bildirdik. preg_match_all($parcala_resim, $query, $resimler); echo "<pre>"; print_r($resimler); "</pre>"; ?> Bunun çıktısı da : Evet şimdi çekmek istediğimiz verileri array halinde tutmuş olduk.Sıra geldi bu array lari Json diziye atıp yollamak. Web servisin son hali : <?php header('Content-Type: text/html; charset=utf-8'); $curl_handle=curl_init(); curl_setopt($curl_handle, CURLOPT_URL,'http://www.thekodprogram.com/'); //Sitemizin URL adresi curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_USERAGENT, 'deneme'); //Burada Curl çalışıyor ve linkteki bütün içerikler query değişkeninde tutuluyor. $query = curl_exec($curl_handle); curl_close($curl_handle); //query değişkeninden almak istediğimiz kısmı bildiriyoruz. //Burada (.*?) ile belirtilen yer değişecek kısım. //Yani anasayfada bir sürü yazı başlığı mevcut. //Bizde bunların değişebileceğini derleyiciye (.*?) ile bildirdik. $parcala_baslik='@<h2 class="post-box-title"><a href="(.*?)">(.*?)</a></h2>@si'; //Burada da query içinden istediğimiz kısmı parçalayıp $basliklar değişkenine atıyoruz. preg_match_all($parcala_baslik, $query, $basliklar); $parcala_ozet='@<p>(.*?)</p>@si'; //Özet için de query içinde arayacağımız kısımı bildirdik. preg_match_all($parcala_ozet, $query, $ozetler); $parcala_resim='@<img width="(.*?)" height="(.*?)" src="(.*?)" class="(.*?)" alt="(.*?)">@si'; //Resimler için de query içinde arayacağımız kısımı bildirdik. //Bize android tarafında resimlerin linkleri lazım olduğu için src kısmını full değişken olarak belirttim. preg_match_all($parcala_resim, $query, $resimler); //Şimdi bu değişkenlerin bize getirdiği verileri ayrı ayrı array lere atayalım. $gelen_basliklar=array(); for($i=0;$i<count($basliklar[2]);$i++) { //Başlıklar için attığım resimde 2.index te başlıkların stilsiz olarak geldiği görülüyor.O yüzden 2.indexteki verileri alıyorum. array_push($gelen_basliklar, $basliklar[2][$i]); } $gelen_ozetler=array(); for($i=0;$i<count($ozetler[1]);$i++) { array_push($gelen_ozetler, $ozetler[1][$i]); //Ozetler için attığım resimde 1. index işimize yarıyacak. } $gelen_resim_linkleri=array(); for($i=0;$i<count($resimler[3]);$i++) { //Resimler için de linkleri aldık ve dizimize atadık. array_push($gelen_resim_linkleri, $resimler[3][$i] ); } $JSON["icerikler"]=array(); //JSON tipte döndüreceğimiz dizi for($i=0;$i<count($gelen_basliklar);$i++) { $temp["basliklar"]=array(); //JSON dizisinin içindeki alt diziler - basliklar,ozetler,resimlink $temp["ozetler"]=array(); $temp["resimlink"]=array(); array_push($temp["basliklar"], $gelen_basliklar[$i]); array_push($temp["ozetler"], $gelen_ozetler[$i]); array_push($temp["resimlink"],$gelen_resim_linkleri[$i]); array_push($JSON["icerikler"], $temp); //Son olarak da ana json dizimize verileri entegre ettik. } echo json_encode($JSON,JSON_UNESCAPED_UNICODE); ?> Web servisin JSON çıktısı da şu şekilde : Görüldüğü üzere karmançorman görünüyo.Bunun için JSON Parser düzenleyecisi kullanırsak tag lari bulamda zorlanmayız. Ben bu adresi kullanıyorum.Burayı kullandıktan sonra web servisimizin çıktısı şu şekilde oldu : Web kısmı uzun oldu ama tamamlandı şükür :) Şimdi Android kısmına geçelim. Tek activity kullanacağım. Birde bu activty de kullanacağım custom list için ayrı bir xml dosyamız olacak.Gerekli açıklamaları kod üzerinde yapacağım.Önce activity_main.xml kodlarını görelim : activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ListView android:id="@+id/veriler_listview" android:layout_width="fill_parent" android:layout_height="fill_parent"></ListView> </RelativeLayout> Şimdi CustomList için oluşturacağımız layout dosyasını görelim :

customlist.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:src="@drawable/tk" android:id="@+id/logo" android:layout_width="70dp" android:layout_height="70dp" /> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/baslik_txt" android:textSize="15dp" android:textStyle="bold" android:textColor="#f01414" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/ozet_txt" android:textColor="#000000" android:textSize="12dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> Şimdi ise JSON verimize ulaşabilmek için istek yollayacağımız bir class hazırladım.Bu kısıma url adresimizi gönderiyoruz ve response alıyoruz.

getResponse.java


package com.thekodprogram;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

/**
 * Created by mehmet.ozay on 28.08.2015.
 */
public class getResponse {
    public getResponse()
    {
        //constructor
    }
    public String getJSONData(String url)
    {

        String response=null;
        DefaultHttpClient httpClient=new DefaultHttpClient();
        HttpGet httpGet=new HttpGet(url);
        httpGet.setHeader("Content-type", "application/json");
        HttpEntity httpEntity=null;
        HttpResponse httpResponse=null;

        try{
            httpResponse=httpClient.execute(httpGet);
            httpEntity=httpResponse.getEntity();
            response= EntityUtils.toString(httpEntity);
        }catch (Exception e)
        {
            e.printStackTrace();
        }

        return response;
    }
}
Şimdi de artık MainActivity.java kısmını ineleyelim.En önemli işleri bu class da yapıyoruz :

package com.thekodprogram;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

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

import java.io.InputStream;
import java.util.ArrayList;


public class MainActivity extends Activity {

    ListView veriler_listesi;
    public String Url=" web servisinizin url adresi !!! ";
    ProgressDialog p;
    ArrayList basliklar=new ArrayList<>();
    ArrayList ozetler=new ArrayList<>();
    ArrayList resim_linkleri=new ArrayList<>();
    ArrayList resimler=new ArrayList<>();
    MyCustomAdapter adapter;
    public class ParseJSONTask extends AsyncTask
    {

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            p.dismiss();
            for(int i=0;i {

        public MyCustomAdapter(Context context, int textViewResourceId, ArrayList xmlList) {

            super(context, textViewResourceId, xmlList);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View row = convertView;

            if (row == null) {
                LayoutInflater inflater = getLayoutInflater();
                row = inflater.inflate(R.layout.customlist, parent, false);
            }

            //CustomList içerisindeki verilerimizi kendi oluşturduğumuz MyCustomAdapter ile doldurduk.

            TextView baslik_textview=(TextView)row.findViewById(R.id.baslik_txt);
            baslik_textview.setText(basliklar.get(position));

            TextView ozet_textview=(TextView)row.findViewById(R.id.ozet_txt);
            ozet_textview.setText(ozetler.get(position));

            ImageView image=(ImageView)row.findViewById(R.id.logo);
            image.setImageBitmap(resimler.get(position));

            return row;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        veriler_listesi=(ListView)findViewById(R.id.veriler_listview);
        p=new ProgressDialog(this);
        new ParseJSONTask().execute();  //Parse işlemlerini gerçekleştireceğimiz AsycnTask ı başlatıyoruz.

    }
}
Manifest Dosyamızı da aşağıdaki gibi hazırlıyoruz.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.thekodprogram" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> </manifest>

Biraz uzun bir yazı oldu.Bazı kısımları anlatmak benim içinde zor oldu.Umarım faydalı olur.

Bir sonraki yazıda görüşmek dileğiyle ...


Tags

Share this Post



Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment.

Comments

  • Mehmet

    Aradığım buydu çok teşekkürler. Json Parse işlemini çok güzel şekilde anlatmışsınız.

    2015/08/29 15:16:35