Pada bagian pertama tentang implementasi check-in pada Location Based Service ini, kita akan belajar tentang bagaimana memasukkan koordinat latitude dan longitude ke dalam database SQLite.

Check in ini berfungsi layaknya pada aplikasi Foursquare, yang nantinya koordinat yang telah kalian masukkan akan bisa ditampilkan pada Google Maps. Postingan mengenai implementasi check in ini akan dibahas dalam tiga tahap.

Tutorial ini berhubungan dengan tutorial-tutorial sebelumnya, karena itu saya sarankan kalian membaca tutorial-tutorial di bawah ini, atau langsung menuju ke halaman tutorial menggunakan Android Maps.

Pre Requisites

Tools

Kalian tidak membutuhkan tools tambahan, kecuali tools standar pemrograman Android dan sebuah AVD Emulator yang dilengkapi dengan Google APIs, cara penginstallan semuanya ada pada panduan di bagian pre-requisites di atas.

Warming Up

Oke, di tutorial sebelumnya kita sudah bisa melacak koordinat GPS pada smartphone Android, dan mendapatkan latitude dan longitude-nya. Sekarang kita akan membuat tombol check-in yang nantinya berguna untuk menyimpan data koordinat tersebut.

Pada tutorial kali ini, kita akan dealing dengan database di Android menggunakan SQLite. Dan kita akan menggunakan metode Model View Controller untuk proses transaksi data ke dalam database.

Lets Begin

Sekarang, buka kembali project yang telah kalian buat pada tutorial Location Based Services sebelumnya. Dan di situ kita akan menambahkan beberapa kelas baru yang berfungsi untuk memasukkan koordinat ke dalam database, masing-masing kelas tersebut adalah :

  • DBDataSource.java : Berfungsi sebagai controller, di kelas ini terdapat method-method yang berfungsi untuk mengambil data, memasukkan data dan method lain yang berkaitan dengan fungsi manipulasi. 
  • Checkin.java : berfungsi sebagai view dalam model MVC kita. Interface dan Activity untuk proses memasukkan koordinat ada di kelas ini.
  • DBLokasi.java : inilah kelas yang berfungsi sebagai model, kelas ini berisi method getter dan setter, sekaligus atribut-atribut untuk objek lokasi.
  • DBMapsHelper.java : berfungsi untuk SQLite helper, berisi fungsi-fungsi pembuatan database dan sebagainya. Hanya sebagai pembantu, tapi mempunyai peran penting. 🙂

Karena kita akan menambahkasn sebuah tombol check-in, maka kita perlu merubah tampilannya. Buka main.xml. Kemudian ganti dengan kode berikut:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:background="@drawable/background" 
    >
    <TextView
        android:id="@+id/NamaProgram"
        android:text="Layanan Berbasis Lokasi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:textStyle="bold" 
        />
    <Button
		 android:id="@+id/getLocationButton" 
		 android:text="Get Location"
		 android:layout_width="wrap_content" 
		 android:layout_height="wrap_content" 
	/>
    <Button
		 android:id="@+id/viewOnMapButton" 
		 android:text="View On Map"
		 android:layout_width="wrap_content" 
		 android:layout_height="wrap_content" 
	/>
    <Button
		 android:id="@+id/checkInButton" 
		 android:text="Check In"
		 android:layout_width="wrap_content" 
		 android:layout_height="wrap_content" 
	/>
    <Button
		 android:id="@+id/aboutButton" 
		 android:text="About"
		 android:layout_width="wrap_content" 
		 android:layout_height="wrap_content" 
	/>

</LinearLayout>

Kemudian, kita juga akan menambahkan layout xml baru yang nantinya akan digunakan sebagai layout kelas Checkin.java, buat file checkin.xml pada folder /res/layout. Pada tampilan layout tersebut kita akan menggunakan listAdapter untuk menampilkan posisi-posisi koordinat yang sudah dimasukkan. Di layout ini juga ada tombol check-in yang langsung berfungsi untuk memasukkan koordinat ke dalam database. Kodenya seperti ini:

<?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:orientation="vertical"
       
    > 
    <TextView
        android:id="@+id/textcheckin"
        android:layout_width="wrap_content"
       	android:layout_height="wrap_content"
       	android:text="check in di sini?"
       	android:layout_gravity="center_horizontal"
       	android:background="#0000ff"
       	/>
<LinearLayout
    android:id="@+id/group"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" > 
    >
   <Button
       android:id="@+id/checkinbt"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Check-in" 
       />
   <Button
       android:id="@+id/showallinmap"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Petakan semua lokasi"
       />
    
</LinearLayout>
<ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        
        />

</LinearLayout>

Setelah layout selesai kita set, kita akan membuat SQLite helper class yang bernama DBMapsHelper.java. Kelas ini merupakan inheritance (extends) dari kelas SQLiteOpenHelper, berisi informasi tentang tabel database yang ingin kita buat, seperti

  • TABLE_NAME / nama tabel
  • COLUMN_ID /kolom primary key
  • COLUMN_LAT / kolom untuk menyimpan data latitude
  • COLUMN_LONG / kolom untuk menyimpan data longitude
  • db_version / versi dari database
  • db_nama / nama dari database, berakhiran .db
Kemudian di kelas ini juga terdapat SQL command dalam bentuk string(db_create), yang berfungsi untuk membuat database baru, dan mengupgrade apabila ada database baru. Copy pastekan kode berikut ini ke dalam kelas tersebut :p :
package id.attwhx.twmaps;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

@SuppressWarnings("unused")
public class DBMapsHelper extends SQLiteOpenHelper{

	public static final String TABLE_NAME = "data_lokasi";
	public static final String COLUMN_ID = "_id";
	public static final String COLUMN_LAT = "lat";
	public static final String COLUMN_LONG = "long";
	private static final String db_name ="lokasi.db";
	private static final int db_version=1;

	// Database creation sql statement
	  private static final String db_create = "create table "
	      + TABLE_NAME + "("
	      + COLUMN_ID +" integer primary key autoincrement, "
	      + COLUMN_LAT+ " varchar(50) not null, "
	      + COLUMN_LONG+ " varchar(50) not null);";

	public DBMapsHelper(Context context) {
		super(context, db_name, null, db_version);

	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL(db_create);

	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		Log.w(DBMapsHelper.class.getName(),"Upgrading database from version " + oldVersion + " to "
	            + newVersion + ", which will destroy all old data");
		db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
	    onCreate(db);

	}

}

Setelah itu kita akan membuat model-nya . Kelas ini bernama DBLokasi.java dan merupakan representasi dari objek lokasi di dunia nyata. DBLokasi mempunyai atribut berupa, lat (latitude), lng (longitude), dan id (primary key). Dan juga beberapa methods yang berfungsi sebagai getter dan setter. Ada satu method toString() yang nantinya akan digunakan untuk ArrayAdapter pada tampilan ListView. Berikut adalah kodenya :

package id.attwhx.twmaps;
public class DBLokasi {

private long id;
private String lat;
private String lng;

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

// Will be used by the ArrayAdapter in the ListView
@Override
public String toString() {
return "Lokasi ke "+id+" ("+lat+" , "+lng+")";
}

public String getLat() {
return lat;
}

public void setLat(String lat) {
this.lat = lat;
}

public String getLng() {
return lng;
}

public void setLng(String lng) {
this.lng = lng;
}
}

Setelah itu, sekarang kita akan membuat controller-nya, kelas ini yang paling banyak tantangannya. 😀 Namanya DBDataSource.java, di kelas ini, methods yang berfungsi untuk membuat lokasi baru, memasukkan lokasi ke dalam database, mendelete lokasi dan lain sebagainya diimplementasikan. Cara kerjanya, awalnya kelas ini akan membuat sebuah database baru dengan cara menginstanstiasi kelas DBMapsHelper, dan mengambil database dari sana. Kemudian database itulah yang nantinya akan dimanipulasi pada saat transaksi data. Penjelasan lebih lanjut ada pada komen di source code :

package id.attwhx.twmaps;

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

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 List getAllLokasi() {
    List daftarLokasi = new ArrayList();

    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;
  }

  // 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;
  }
}

Yups, sekarang kelas terakhir yang kurang adalah kelas Checkin.java, kelas ini berfungsi sebagai view, dimana data yang ada di database akan ditampilkan dalam bentuk ListView. 

Oh iya, sebelum membuat kelas ini, kita pertama-tama harus memodifikasi main class yang bernama MapDriverActivity.java (lihat di GitHub)kita akan tambahkan intent sehingga tombol checkin yang baru akan dapat berfungsi. Dan tambahkan juga kelas ChekckIn ke dalam daftar Activity pada AndroidManifest.xml (lihat di GitHub).

Kembali ke kelas CheckIn.java, inilah kodenya

package id.attwhx.twmaps;

import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
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;
	@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

      List values = datasource.getAllLokasi();

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

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

	public void onClick(View v) {
		@SuppressWarnings("unchecked")
		ArrayAdapter adapter = (ArrayAdapter) 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;
		}
		adapter.notifyDataSetChanged();
	}

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

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

}

Pada aplikasi TWOH-Maps yang terbaru ini sudah ditambahkan metode pengecekan GPS apakah aktif atau tidak. Karena pada versi sebelumnya yang tidak melakukan pengecekan, akan terjadi error apabila kita klik View On Map/Get Location, padahal GPS mati. Koordinat pada peta murni didapat dari GPS.

Jalankan

Pertama-tama, aktifkan terlebih dahulu GPS melalui emulator control, masukkan koordinat > klik Send :

Aktivasi GPS

Apabila GPS mati, maka aplikasi tidak dapat berfungsi sebagaimana mestinya dan menampilkan gambar ini. Kalau koordinat sudah terdeteksi, coba klik Check-in

Notifikasi GPS tidak aktif

Inilah halaman check-in. Wow, sudah ada tiga lokasi ! Sekarang coba klik tombol check-in lagi.

Check-In pertama

Lokasinya jadi ada empat. 

Check-In kedua

Tampilan peta-nya di Xoom Ice Cream Sandwich

TWOH-Maps di Xoom ICS

Conclusion

Kira-kira seperti itu hal-hal yang perlu ditambahkan. Tutorial selanjutnya adalah untuk menampilkan lokasi yang sudah tersimpan ke dalam peta.

Atau kalau kalian ingin mencoba meng-oprek-nya sendiri, bisa download project TWOH-Maps pada repositori GitHub saya.

Jangan sungkan untuk bertanya lewat komentar apabila ada yang kurang jelas ! Semoga membantu 😀



Download aplikasi kami di Google Play Store