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….!!!!
Ajip gile.. mantep bener tutorial nya de.. terus berinovasi!! mau belajar buat aplikasi android mulai dari mana dulu ya de?
mantap kamu nak. saya stuck dengan laptop saya, kepanasan jalanin android
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..
nice posting bro 😀
facebook nya dirimu sudah ku add, di confirm ya 😀
keren bang 🙂
tutor sebelumnya juga lumayan ni buat skripsi saya.sukses terus yah !!
Nice share gan.. keep posting.. 🙂
Kak…. projectnya saya sudah import ke Eclipse Juno tapi kok error di SRC nya???? tolong dibantu kk….
bang,, dah pake chrome masih blm bisa muncul link downloadnya
gan…tolong tampilkan tampilan gambarnya setelah di run….
nanti saya migrasi gambar2nya ke google pictures
di tunggu gan
permisi gan, mohon bantuannya…bisa berikan tutorial cara mengambil data RSS dari http://www.bmkg.go.id
maksudnya gmn brow??
kan ada file gempaterkini.xml…..nah, di mana ambilnya itu gan ?????
kurang tau brow, ane gak nemu file xml nya
maaf gan, bisa kasih tutorial gak buat ngambil rss dari
http://data.bmkg.go.id/propinsi_15_2.xml
aq nyoba tutorial yg dr agan tp gak bisa kalo bwt yg link di atas, soalnya kyk’a struktur xml yg beda
samakan aja tag xml nya brow..
ganti dengan tag yg ada di data xml nya
gan…saya mau nanya…kalo buat aplikasi untuk menampilkan ini
http://www.bmkg.go.id/BMKG_Pusat/Geofisika/Gempa_Dirasakan.bmkg
apakah sourcenya sama dengan yang diatas????
cari yg format data output dari BMKG nya berupa file xml brow
ini gan file xmlnya….
http://data.bmkg.go.id/gempadirasakan.xml
maksud saya, apakah source javanya sama dengan yang diatas, tinggal di ganti aja file xmlx n judul2nya?????
sama aja, yg penting samakan tagl xml nya
ok gan makasih banyak..
Wah berarti kalau RSS, bisa juga di koneksi dan diimplementasikan menggunakan PhoneGap ya ??? Thanx buat informasinya. Mencerahkan
agan udah tes ini aplikasi, udah jalan atau masih ada yang error?? coz saya runinng errorx di parsingxml…..
bang ko di gw eror ya
unable resolve target android sdk 10
itu knp ya
gan kok kagak ada ya di 4 shared filenya?
bang ko di gw eror ya
unable resolve target android sdk 10
itu knp ya
[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..,
eh,, gempa yang dirasakan maksutnya gan..,