Tutorial Android : Memanfaatkan Data RSS BMKG Untuk Membuat Aplikasi Pemantau Gempa

Akhirnya bulan agustus datang lagi, bulan yang lumayan saya tunggu-tunggu. Bulan yang banyak waktu kosongnya untuk diisi dengan kegiatan bermanfaat, salah satunya ialah kegiatan mengumpulkan recehan untuk membeli barang-barang impian ;). Selain itu bulan ini juga adalah bulan yang penuh dengan pengeluaran, salah satunya untuk bayar KRS’an. Tepatnya 2 hari yang lalu, saya ke kampus untuk melakukan proses perwalian (yang mudah-mudahan ini adalah yang terakhir kalinya). Datang ke kampus agak siang, karena bangunnya juga siang :p. Masuk ke kantor untuk mencari dosen wali dan semua mata dosen tertuju pada saya, tampak pandangan mereka ke arah saya agak sinis. Dan saya pun langsung tau apa penyebabnya, mungkin gara-gara postingan saya sebelumnya. Dimana saya curhat tentang kasus saya yang diusir dari litbang (#haha), kebetulan juga postingan itu (isinya tentang curhat + tutorial lho yaw) saya bagikan ke group FB kampus. Mungkin si admin mengadu dan jadilah para pak dosen yang terhormat memandang saya dengan sinisnya. Ck..ck..ck..kampus saya memang keren deh pokoknya dan saya malas untuk berkomentar lebih banyak, biarlah waktu yang membuktikan kebenaran postingan saya yang kemarin.

Pada postingan kali ini, saya akan membahas tentang cara untuk memanfaatkan data RSS BMKG untuk membuat sebuah aplikasi pemantau gempa. Kebetulan juga kemarin ada yang menanyakan via FB, tentang tutorial android sebelumnya yang melakukan parsing terhadap data XML ke android. Si doi ingin melakukan parsing data XML yang disediakan BMKG, untuk membuat aplikasi pemantau gempa. Ketika dicoba ternyata erorr a.k.a force close. Penyebabnya adalah karena pada XMLParser saya menggunakan method HttpPost, sedangkan untuk mengambil data RSS itu kebanyakan harus menggunakan method HttpGet. Nah, disini sekalian saya buatkan aplikasinya yang sederhana. Lumayan juga bisa saya gunakan untuk membuat jurnal yang akan disetorkan ke kampus tercinta :D. Berikut cara pembuatannya, cekidot gan….

1. Seperti biasa, buat sebuah project android baru. Karena kita akan sekaligus menampilkan peta sesuai koordinat longitude dan latitude dari BMKG, maka kita harus menggunakan SDK android yang ada Google APIS nya.

2. Disini kita membutuhkan 3 buah file layout, salah satunya pada file peta.xml kita harus memasukkan apiKey untuk memanfaatkan GoogleMap. Silahkan baca postingan saya sebelumnya untuk cara mendapatkan unique apiKey.

main.xml

<?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:padding="10dp"
    android:orientation="vertical">
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

daftar_item.xml

<?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="wrap_content"
    android:orientation="horizontal">
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tanggal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#dc6800"
            android:textSize="18sp"
            android:textStyle="bold"
            android:paddingTop="6dip"
            android:paddingBottom="2dip" />

        <TextView
            android:id="@+id/jam"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:paddingBottom="2dip">
        </TextView>

        <TextView
            android:id="@+id/lintang"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#5d5d5d"
            android:gravity="left"
            android:textStyle="bold"
            android:text="Cost: " >
        </TextView>

        <TextView
            android:id="@+id/bujur"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#5d5d5d"
            android:gravity="left"
            android:textStyle="bold"
            android:text="Cost: " >
        </TextView>

        <TextView
            android:id="@+id/kekuatan"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:textStyle="bold"
            android:gravity="left">
        </TextView>

        <TextView
            android:id="@+id/kedalaman"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:textStyle="bold"
            android:gravity="left">
        </TextView>

        <TextView
            android:id="@+id/wilayah"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:textStyle="bold"
            android:gravity="left">
        </TextView>

    </LinearLayout>

</LinearLayout>

peta.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.google.android.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:enabled="true"
        android:clickable="true"
        android:apiKey="0F8HAxC9X2UOQydLVdGz_YDHRVoazIgWlWXFPbA"
        />

</RelativeLayout>
</LinearLayout>

3. Siapkan 2 buah class activity, yaitu InfoBmkgActivity.java (yang ini sudah ada secara default ketika project dibuat) dan PetaGempaActivity.java. Ketikkan kode di bawah ini :

InfoBmkgActivity.java

package dlmbg.pckg.info.bmkg;

import java.util.ArrayList;
import java.util.HashMap;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class InfoBmkgActivity extends ListActivity {

	static final String URL = "http://data.bmkg.go.id/gempaterkini.xml";
	static final String KEY_ITEM = "gempa";
	static final String KEY_ID = "Tanggal";
	static final String KEY_TANGGAL = "Tanggal";
	static final String KEY_JAM = "Jam";
	static final String KEY_POINT = "point";
	static final String KEY_KOORDINAT = "coordinates";
	static final String KEY_LINTANG = "lintang";
	static final String KEY_BUJUR = "bujur";
	static final String KEY_KEKUATAN_GEMPA = "Magnitude";
	static final String KEY_KEDALAMAN = "Kedalaman";
	static final String KEY_WILAYAH = "Wilayah";
	private ProgressDialog pDialog;
	ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		new AmbilData().execute();
	}

    class AmbilData extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(InfoBmkgActivity.this);
            pDialog.setMessage("Sabar gan, masih ngambil data neh...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        protected String doInBackground(String... args) {

    		XMLParser parser = new XMLParser();
    		String xml = parser.getXmlFromUrl(URL);
    		Document doc = parser.getDomElement(xml);

    		NodeList nl = doc.getElementsByTagName(KEY_ITEM);
    		for (int i = 0; i < nl.getLength(); i++) {

            	HashMap<String, String> map = new HashMap<String, String>();

    			Element e = (Element) nl.item(i);

    			String koordinat = parser.getValue(e, KEY_KOORDINAT);
    			String[] koor = koordinat.split(",");

    			map.put(KEY_ID, parser.getValue(e, KEY_ID));
    			map.put(KEY_TANGGAL, parser.getValue(e, KEY_TANGGAL));
    			map.put(KEY_JAM, parser.getValue(e, KEY_JAM));
    			map.put(KEY_LINTANG, "Garis Lintang : "+koor[1]);
    			map.put(KEY_BUJUR, "Garis Bujur : "+ koor[0]);
    			map.put(KEY_KEKUATAN_GEMPA, "Kekuatan Gempa : "+parser.getValue(e, KEY_KEKUATAN_GEMPA));
    			map.put(KEY_KEDALAMAN, "Kedalaman : "+ parser.getValue(e, KEY_KEDALAMAN));
    			map.put(KEY_WILAYAH, "Wilayah : "+parser.getValue(e, KEY_WILAYAH));

    			menuItems.add(map);
    		}
			return null;
        }

        protected void onPostExecute(String file_url) {
            pDialog.dismiss();
            runOnUiThread(new Runnable() {
                public void run() {

            		ListAdapter adapter = new SimpleAdapter(InfoBmkgActivity.this, menuItems,
            				R.layout.daftar_item,
            				new String[] { KEY_TANGGAL, KEY_JAM, KEY_LINTANG, KEY_BUJUR, KEY_KEKUATAN_GEMPA, KEY_KEDALAMAN, KEY_WILAYAH },
            				new int[] {R.id.tanggal, R.id.jam, R.id.lintang, R.id.bujur,R.id.kekuatan,R.id.kedalaman,R.id.wilayah });

            		setListAdapter(adapter);

            		ListView lv = getListView();

            		lv.setOnItemClickListener(new OnItemClickListener() {

                        @Override
                        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
                            String lintang = ((TextView) view.findViewById(R.id.lintang)).getText().toString();
                            String bujur = ((TextView) view.findViewById(R.id.bujur)).getText().toString();
                            String tanggal = ((TextView) view.findViewById(R.id.tanggal)).getText().toString();
                            String jam = ((TextView) view.findViewById(R.id.jam)).getText().toString();
                            String kekuatan = ((TextView) view.findViewById(R.id.kekuatan)).getText().toString();
                            String kedalaman = ((TextView) view.findViewById(R.id.kedalaman)).getText().toString();
                            String wilayah = ((TextView) view.findViewById(R.id.wilayah)).getText().toString();

                            Intent i = null;
            				i = new Intent(InfoBmkgActivity.this, PetaGempaActivity.class);

                            Bundle b = new Bundle();
            				b.putString("lintang", lintang);
            				b.putString("bujur", bujur);
            				b.putString("tanggal", tanggal);
            				b.putString("jam", jam);
            				b.putString("kekuatan", kekuatan);
            				b.putString("kedalaman", kedalaman);
            				b.putString("wilayah", wilayah);
            				i.putExtras(b);

                            startActivity(i);
                        }
                    });
                }
            });

        }
    }
}

PetaGempaActivity.java

package dlmbg.pckg.info.bmkg;

import android.graphics.drawable.Drawable;
import android.os.Bundle;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class PetaGempaActivity extends MapActivity {

	Double lat = -6.29436;
	Double lng = 106.8859;
	String tanggal,jam,kekuatan,kedalaman,wilayah;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.peta);
        MapView mapView = (MapView) findViewById(R.id.mapView);

        try {

            Bundle b = getIntent().getExtras();

            String koordinatLintang = b.getString("lintang");
            String[] koorlin = koordinatLintang.split(" : ");
            String koordinatBujur = b.getString("bujur");
            String[] koorbuj = koordinatBujur.split(" : ");

            lat = Double.parseDouble(koorlin[1]);
            lng = Double.parseDouble(koorbuj[1]);

            tanggal = b.getString("tanggal");
            jam = b.getString("jam");
            kekuatan = b.getString("kekuatan");
            kedalaman = b.getString("kedalaman");
            wilayah = b.getString("wilayah");

		} catch (Exception e) {}

        GeoPoint posisi = new GeoPoint((int) (lat * 1E6),(int) (lng * 1E6));
		MapController mapController = mapView.getController();
		mapController.setCenter(posisi);
		mapController.setZoom(8);

        Drawable icon = getResources().getDrawable(R.drawable.marker);
		icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon
				.getIntrinsicHeight());

		MyItemizedOverlay overlay = new MyItemizedOverlay(icon, this);
		OverlayItem item = new OverlayItem(posisi, "Posisi Gempa", "Tanggal : "+tanggal+" \nJam : "+jam+" \n"+kekuatan+"" +
				"\n"+kedalaman+" \n"+wilayah);
		overlay.addItem(item);
		mapView.getOverlays().add(overlay);
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

Selain class di atas, kita juga membutuhkan 2 class lagi. Yaitu XMLParser.java untuk melakukan parsing data XML yang didapatkan dari web BMKG dan MyItemizedOverlay.java untuk menampilkan marker pada titik terjadinya gempa sesuai longitude dan latitude.

XMLParser.java

package dlmbg.pckg.info.bmkg;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class XMLParser {

	// constructor
	public XMLParser() {

	}

	/**
	 * Getting XML from URL making HTTP request
	 * @param url string
	 * */
	public String getXmlFromUrl(String url) {
		String xml = null;

		try {
			// defaultHttpClient
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpGet httpPost = new HttpGet(url);

			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			xml = EntityUtils.toString(httpEntity);

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// return XML
		return xml;
	}

	/**
	 * Getting XML DOM element
	 * @param XML string
	 * */
	public Document getDomElement(String xml){
		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
		        is.setCharacterStream(new StringReader(xml));
		        doc = db.parse(is);

			} catch (ParserConfigurationException e) {
				Log.e("Error: ", e.getMessage());
				return null;
			} catch (SAXException e) {
				Log.e("Error: ", e.getMessage());
	            return null;
			} catch (IOException e) {
				Log.e("Error: ", e.getMessage());
				return null;
			}

	        return doc;
	}

	/** Getting node value
	  * @param elem element
	  */
	 public final String getElementValue( Node elem ) {
	     Node child;
	     if( elem != null){
	         if (elem.hasChildNodes()){
	             for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
	                 if( child.getNodeType() == Node.TEXT_NODE  ){
	                     return child.getNodeValue();
	                 }
	             }
	         }
	     }
	     return "";
	 }

	 /**
	  * Getting node value
	  * @param Element node
	  * @param key string
	  * */
	 public String getValue(Element item, String str) {
			NodeList n = item.getElementsByTagName(str);
			return this.getElementValue(n.item(0));
		}
}

MyItemizedOverlay.java

package dlmbg.pckg.info.bmkg;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class MyItemizedOverlay extends ItemizedOverlay {

	private ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
	private Drawable marker;
	private Context mContext;

	public MyItemizedOverlay(Drawable defaultMarker) {
		super(defaultMarker);
		marker = defaultMarker;
	}

	public MyItemizedOverlay(Drawable defaultMarker, Context context) {
		super(boundCenterBottom(defaultMarker));
		mContext = context;
	}

	@Override
	protected OverlayItem createItem(int index) {
		return (OverlayItem) items.get(index);
	}

	@Override
	public int size() {
		return items.size();

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * com.google.android.maps.ItemizedOverlay#draw(android.graphics.Canvas,
	 * com.google.android.maps.MapView, boolean)
	 */
	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, shadow);

	}

	public void addItem(OverlayItem item) {
		items.add(item);
		populate();
	}

	@Override
	protected boolean onTap(int index) {
		OverlayItem item = items.get(0);
		AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
		dialog.setTitle(item.getTitle());
		dialog.setMessage(item.getSnippet());
		dialog.setPositiveButton("OK", new OnClickListener() {
			@Override
			public void onClick(DialogInterface arg0, int arg1) {
				arg0.dismiss();
			}
		});
		dialog.show();
		return true;
	}

}

4. Selanjutnya buka file AndroidManifest.xml, tambahkan permission untuk menggunakan library GoogleMap dan permission untuk mengakses internet.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="dlmbg.pckg.info.bmkg"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
		<uses-library android:name="com.google.android.maps" />
        <activity
            android:name=".InfoBmkgActivity"
            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="PetaGempaActivity"
			android:label="Daftar Lokasi Tersimpan"
			android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
		</activity>
    </application>
	<uses-permission android:name="android.permission.INTERNET"></uses-permission>

</manifest>

5. Yang terakhir, jalankan project pada emulator atau bisa juga langsung di jalankan di hape android. Kira-kira hasilnya seperti di bawah ini :

Gampang kan cara membuatnya…??? Sebenarnya masih ada banyak data dari BMKG yang bisa dimanfaatkan untuk dibuatkan aplikasinya, semuanya disediakan secara terbuka dan bebas untuk digunakan. Lumayan tuh untuk dijadikan ladang untuk mengeruk recehan :ngakaks:. Semoga saja lebih banyak ada badan-badan pemerintahan dan negara yang menyediakan datanya seperti BMKG, sehingga bisa diolah oleh masyarakat untuk kepentingan bersama. OK deh, sekian dulu postingan saya di malam yang dingin ini. Semoga bisa bermanfaat untuk kita semua.

Happy Blogging and Keep Coding

Cheerrrss….!!!!

[to_like]Download Aplikasi[/to_like]

29 comments

  1. Duwi Arsana Reply

    Ajip gile.. mantep bener tutorial nya de.. terus berinovasi!! mau belajar buat aplikasi android mulai dari mana dulu ya de?

  2. ebuh Reply

    mantap kamu nak. saya stuck dengan laptop saya, kepanasan jalanin android

  3. Choirul Fadholanii Reply

    Mas, sy newbie yg lagi belajar android programming, sudah saya coba berhasil tampil datanya, tapi waktu di click detail salah satu tempat langsung force close, kira2 knp ya mas?
    thx..

  4. Rowlandtz Reply

    nice posting bro 😀
    facebook nya dirimu sudah ku add, di confirm ya 😀

  5. venny Reply

    keren bang 🙂
    tutor sebelumnya juga lumayan ni buat skripsi saya.sukses terus yah !!

  6. Andy Reply

    Kak…. projectnya saya sudah import ke Eclipse Juno tapi kok error di SRC nya???? tolong dibantu kk….

  7. Suwondo Reply

    Wah berarti kalau RSS, bisa juga di koneksi dan diimplementasikan menggunakan PhoneGap ya ??? Thanx buat informasinya. Mencerahkan

  8. jarot Reply

    agan udah tes ini aplikasi, udah jalan atau masih ada yang error?? coz saya runinng errorx di parsingxml…..

  9. dan Reply

    [gan mau tanya]
    gan tag nya itu bisa diganti dengan gempa terkini gak…??
    dan aplikasi ini kan gak butuhi tabel lagi kan gan..???
    makasih sebelumnya..,