Implementasi Check-In pada Location Based Service di Android (II)

Pada bagian kedua tentang implementasi check-in pada Location Based Service ini, kita akan belajar tentang bagaimana mengambil koordinat latitude dan longitude dari database SQLite dan menampilkannya di Android Maps.

Welcome Guys ! Sudah lama ane tidak menuliskan tutorial Android dimari, maklum banyaknya proyek dan tugas kuliah lumayan menyita waktu sehingga membuat website ini sedikit terbengkalai. 😀

Namun jangan khawatir, saya tetap membalas komen-komen maupun email yang masuk. So, don’t hesitate to ask me if you have any problem while following tutorial in this TWOH’s Engineering. 🙂

Okay, langsung saja guys. Kali ini kita akan belajar tentang bagaimana mengambil data koordinat dari SQLite dan menampilkannya di peta.

Pada tutorial sebelumnya kita telah mendesain sebuah database beserta objek lokasi untuk memasukkan data koordinat ke dalam database.

Jika kalian menemui kesulitan dalam mengikuti tutorial ini, silahkan baca-baca dulu pre-requisites yang ada di halaman ini :

Warming Up

Okay, seperti yang kita bahas di tutorial sebelumnya. Kita sudah bisa menyimpan data ke dalam database SQLite, dan menampilkannya dalam bentuk ListView. Namun pada kasus kali ini kita ingin ketika ListView tersebut diklik, aplikasi akan membawa kita ke halaman peta dan menampilkan koordinat dari database sesuai dengan lokasi yang dipilih.

Let’s Begin

Sekarang, buka project yang telah kalian buat pada tutorial sebelumnya. Dari situ kita akan menambahkan beberapa method. Method yang pertama yang harus ditambahkan adalah method, getLokasi() pada kelas DBDataSource.java. Apakah kalian ingat kelas DBDataSource.java berfungsi sebagai apa? Yak, benar sekali anak-anak kelas DBDataSource berfungsi sebagai kontroller. 😀

Inilah method getLokasi() yang akan ditambahkan :

public DBLokasi getLokasi(int id)
{
	  DBLokasi lokasi = new DBLokasi();

	  Cursor cursor = database.query(DBMapsHelper.TABLE_NAME, allColumns, "_id ="+id, null, null, null, null);
	  cursor.moveToFirst();
	  lokasi = cursorToLokasi(cursor);
	  cursor.close();
	  return lokasi;
}

Method getLokasi() akan mengambil sebuah objek lokasi pada database, sesuai dengan id atau primary key yang diinputkan, dan kemudian mengembalikan objek lokasi tersebut sebagai output. Sehingga method ini lebih tepat apabila disebut sebagai sebuah fungsi.

Inilah kelas DBDataSource selengkapnya, setelah ditambahkan method baru :

package id.attwhx.twmaps;

import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class DBDataSource {

  // Inisialisasi database fields
  private SQLiteDatabase database;
  private DBMapsHelper dbHelper;

  // Ambil konstanta
  private String[] allColumns = { DBMapsHelper.COLUMN_ID,
      DBMapsHelper.COLUMN_LAT, DBMapsHelper.COLUMN_LONG };

  // Menggunakan DBMapsHelper yang diiinisialisasi pada konstruktor
  public DBDataSource(Context context) {
    dbHelper = new DBMapsHelper(context);
  }

  // Mengambil sebuah database yang bisa digunakan
  public void open() throws SQLException {
    database = dbHelper.getWritableDatabase();
  }

  public void close() {
    dbHelper.close();
  }

  // Method yang berfungsi untuk membuat lokasi baru dan memasukkannya ke dalam database
  public DBLokasi createLokasi(Double dlat, Double dlng) {
    ContentValues values = new ContentValues();
    String lat = Double.toString(dlat);
    String lng = Double.toString(dlng);
    values.put(DBMapsHelper.COLUMN_LAT, lat);
    values.put(DBMapsHelper.COLUMN_LONG, lng);
    long insertId = database.insert(DBMapsHelper.TABLE_NAME, null,
        values);
    Cursor cursor = database.query(DBMapsHelper.TABLE_NAME,
        allColumns, DBMapsHelper.COLUMN_ID + " = " + insertId, null,
        null, null, null);
    cursor.moveToFirst();
    DBLokasi newLokasi = cursorToLokasi(cursor);
    cursor.close();
    Log.v("info", "The lat "+lat+", "+dlat);
    Log.v("info", "The lng "+lng+", "+dlng);
    return newLokasi;
  }

  // Method yang berfungsi untuk menghapus lokasi berdasarkan ID
  public void deleteLokasi(DBLokasi lokasi, long ids) {
    long id = lokasi.getId();
    System.out.println("Lokasi deleted with id: " + id);
    database.delete(DBMapsHelper.TABLE_NAME, DBMapsHelper.COLUMN_ID
        + " = " + id, null);
  }

  // Method yang berfungsi untuk mengambil semua lokasi
  public ArrayList<DBLokasi> getAllLokasi() {
    ArrayList<DBLokasi> daftarLokasi = new ArrayList<DBLokasi>();

    Cursor cursor = database.query(DBMapsHelper.TABLE_NAME,
        allColumns, null, null, null, null, null);

    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
      DBLokasi lokasi = cursorToLokasi(cursor);
      daftarLokasi.add(lokasi);
      cursor.moveToNext();
    }
    // Make sure to close the cursor
    cursor.close();
    return daftarLokasi;
  }

  //berfungsi untuk mengambil sebuah lokasi dari database berdasarkan id/primary key nya
  public DBLokasi getLokasi(int id)
  {
	  DBLokasi lokasi = new DBLokasi();

	  Cursor cursor = database.query(DBMapsHelper.TABLE_NAME, allColumns, "_id ="+id, null, null, null, null);
	  cursor.moveToFirst();
	  lokasi = cursorToLokasi(cursor);
	  cursor.close();
	  return lokasi;
  }

  // Method yang berfungsi untuk membuat sebuah objek lokasi baru yang nantinya akan dimasukkan ke dalam database
  private DBLokasi cursorToLokasi(Cursor cursor) {

	  DBLokasi lokasi = new DBLokasi();
	  Log.v("info", "The getLONG "+cursor.getLong(0));
      Log.v("info", "The setLatLng "+cursor.getString(1)+","+cursor.getString(2));
	  lokasi.setId(cursor.getLong(0));
	  lokasi.setLat(cursor.getString(1));
	  lokasi.setLng(cursor.getString(2));
	  return lokasi;
  }
}

Setelah itu, kita berpindah ke kelas Checkin.java. Dimana data lokasi dari database ditampilkan dalam bentuk ListView. Nah kita akan membuat ListView tersebut untuk  bisa diklik individually yang kemudian akan menampilkan koordinat dari database di map.

Karena kelas CheckIn sudah mengimplementasi OnClickListener, maka kita hanya perlu meng-override method onListItemClick() dan menambahkannya pada kelas itu :

@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		String text = " Pindah ke lokasi " + values.get(position).getId();
		DBLokasi lokasi = datasource.getLokasi(position+1);
		Toast.makeText(this, text, Toast.LENGTH_LONG).show();

		Intent i = new Intent(this, TWMaps.class);
    	Bundle b = new Bundle();
    	b.putDouble("longitude", Double.valueOf(lokasi.getLng()));
    	b.putDouble("latitude", Double.valueOf(lokasi.getLat()));
        i.putExtras(b);
    	startActivity(i);
	}

Method onListItemClick() membutuhkan sebuah ListView, View, posisi, dan id sebagai parameter masukan. Id akan digunakan sebagai primary key untuk mengambil data lokasi dari database. Parameter Id akan dipassingkan ke fungsi getLokasi(), kemudian fungsi getLokasi() itu akan mengembalikan objek lokasi sebagai output. Selanjutnya kita mengambil latitude dan longitude dari objek lokasi itu, dan memasukkannya sebagai extra untuk dibawa ke activity selanjutnya.

Di activity berikutnya, latitude dan longitude yang dimasukkan sebagai extras itu akan diambil, dan ditampilkan pada peta. Kira-kira seperti itu cara kerjanya. 🙂
Dan ini kelas Checkin.java selengkapnya, setelah ditambahkan method tadi :

package id.attwhx.twmaps;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.MapActivity;

@SuppressWarnings("unused")
public class Checkin extends ListActivity implements OnClickListener{

	private TextView textView;
	private DBDataSource datasource;
	private View checkinbut;
	private Double lat,lng;
	private Button bt;
	ArrayList<DBLokasi> values;
	@Override
	public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.checkin);
      checkinbut = findViewById(R.id.checkinbt);
      checkinbut.setOnClickListener(this);
      textView =  (TextView) findViewById(R.id.textcheckin);
      Bundle b = this.getIntent().getExtras();
      lat = b.getDouble("latitude");
      lng = b.getDouble("longitude");
      textView.setText("Ingin check-in di koordinat berikut ? "+lat+","+lng);

      // Instanstiasi kelas DataSource yang berfungsi sebagai controller atau DAO

      datasource = new DBDataSource(this);
      datasource.open();

      // Ambil semua lokasi

      values = datasource.getAllLokasi();

      // Tampilkan pada ListView
      ArrayAdapter<DBLokasi> adapter = new ArrayAdapter<DBLokasi>(this,
    	        android.R.layout.simple_list_item_1, values);
      setListAdapter(adapter);

      bt = (Button) findViewById(R.id.showallinmap);
      bt.setOnClickListener(this);
    }

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		String text = " Pindah ke lokasi " + values.get(position).getId();
		DBLokasi lokasi = datasource.getLokasi(position+1);
		Toast.makeText(this, text, Toast.LENGTH_LONG).show();

		Intent i = new Intent(this, TWMaps.class);
    	Bundle b = new Bundle();
    	b.putDouble("longitude", Double.valueOf(lokasi.getLng()));
    	b.putDouble("latitude", Double.valueOf(lokasi.getLat()));
        i.putExtras(b);
    	startActivity(i);
	}

	// Masukkan lokasi baru ketika tombol check in di-klik

	public void onClick(View v) {
		@SuppressWarnings("unchecked")
		ArrayAdapter<DBLokasi> adapter = (ArrayAdapter<DBLokasi>) getListAdapter();
		DBLokasi lokasi = null;
		switch (v.getId())
		{
			case R.id.checkinbt:
				lokasi = datasource.createLokasi(lat,lng);
				if(lokasi !=null&&adapter!=null)
				{
					adapter.add(lokasi);
				}else
				{
					Toast.makeText(this, "NULL", Toast.LENGTH_LONG).show();
				}
				break;
			case R.id.showallinmap:
		}
		adapter.notifyDataSetChanged();

	}

	@Override
	  protected void onResume() {
	    datasource.open();
	    super.onResume();
	  }

	  @Override
	  protected void onPause() {
	    datasource.close();
	    super.onPause();
	  }

}

Whatcha to say guys… Kira-kira cuma itu yang perlu ditambahkan. Oh iya kita perlu memodifikasi kelas TWMaps.java, sehingga kelas itu dapat membongkar bundle ekstra yang berisi koordinat tadi, dan menampilkannya pada peta. Kelas lengkapnya adalah sebagai berikut :


package id.attwhx.twmaps;

import java.util.ArrayList;
import java.util.List;

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

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.Overlay;
import com.google.android.maps.OverlayItem;

public class TWMaps extends MapActivity {
   private MapView map;
   private MapController controller;

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.mapdisplay);
      initMapView();
      initMyLocation();
   }

   /** Find and initialize the map view. */
   private void initMapView() {
      map = (MapView) findViewById(R.id.map);
      controller = map.getController();
      map.setSatellite(true);
      map.setBuiltInZoomControls(true);

   }

   /** Menginisialisasi lokasi awal di peta */
   private void initMyLocation() {
	  int lat, lng;
          //mengambil bundle ekstra dari activity sebelumnya
	  Bundle b = this.getIntent().getExtras();
          //mengecek apakah bundle tersebut mempunyai kata kunci "longitude"
	  if(b.containsKey("longitude"))
	  {

	      lat = (int)(b.getDouble("latitude")*1E6);
	      lng = (int)(b.getDouble("longitude")*1E6);
	      Log.v("info", "The lat "+lat);
	      Log.v("infoMAPS", "MASUK KE SATU");
	      Log.v("info", "The lng "+lng);
	      GeoPoint point = new GeoPoint(lat,lng);
	      List<Overlay> mapOverlays = map.getOverlays();
		  Drawable marker = this.getResources().getDrawable(R.drawable.marker);
		  MapOverlay itemizedOverlay = new MapOverlay(marker, this);

		  OverlayItem overlayitem = new OverlayItem(point, "Info Lokasi", "Koordinat ("+b.getDouble("latitude")+","+b.getDouble("longitude")+")");
	      itemizedOverlay.addOverlay(overlayitem);
	      controller.setZoom(16);
	      controller.animateTo(point);
	      mapOverlays.add(itemizedOverlay);

	  }
   }

   @Override
   protected boolean isRouteDisplayed() {
      // Required by MapActivity
      return false;
   }
}

Pada saat kita mempassing/melewatkan data koordinat dari kelas Checkin.java ke kelas TWMaps.java. Kita  menggunakan kata kunci untuk tiap-tiap data yang dilewatkan itu. Kemudian activity TWMaps akan mengecek apakah bundle yang dikirimkan mengandung kata kunci itu. Apabila terdapat kata kunci yang dimaksudkan, maka koordinat akan ditampilkan di peta.

Sederhananya seperti itu 😀

Jika sudah,coba jalankan proyek tersebut, pastikan GPS aktif kemudian klik tombol CheckIn. Akan muncul tampilan seperti di bawah :

Fitur Checkin pada TW-Maps

Kemudian kita coba klik “Lokasi ke 4” pada ListView. Maka aplikasi akan membawa kita ke peta dengan menampilkan lokasi yang tadi kita pilih(lokasi 4) :

TWMaps view

Enjoy !

Oh iya, kalian juga bisa men-download project lengkapnya pada GitHub saya.



Download aplikasi kami di Google Play Store


6 Comments

  1. marina October 14, 2012
  2. marina October 14, 2012
  3. fatah October 20, 2012
    • Herdi Naufal October 21, 2012
  4. Riko June 19, 2014

Leave a Reply