3.a Ada Tempat Untuk Menampung Data

Ini adalah seri lanjutan dari proses pembuatan Kamus Digital yang bisa di upload/download, di jual atau di pasang langsung ke HP android. Salah satu kriteria untuk bisa memasang kamus di HP adalah agar di dalam HP ada tempat untuk menampung data, maka denga demikian kita butuh database. Halaman ini adalah untuk class KamusDatabase.java di namakan KamusDatabase karena class ini yang mengatur segala sesuatu yang berhubungan dengan database pada aplikasi kamus digital yang sedang kita bangun. Tapi sebelum membaca di halaman ini ada baiknya baca dulu 2 seri sebelumnya yang memuat dua class java lain-nya yaitu KamusDigital.java dan PenghubungData.java
Berikut adala isi dari class KamusDatabase.java
package com.vik_sintus.projects.kamusDigital;
/**
 * Copyright (C) 2012 Vik Sintus Projects
 *
 * Segala kelebihan dan kekurangan di luar tanggung jawab pembuat.
 * Di larang memakai kode ini untuk kepentingan komersial tanpa ijin.
 * Silahkan di pakai untuk kepentingan belajar.
 * vik.sintus@gmail.com
 * http://belajar-android-indonesia.blogspot.com
 * Unless required by applicable law or agreed to in writing, this software
 * is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * 
 * 
 */
import android.app.SearchManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;

/**
 * logika utk mengambil data dari database, dan
 * memasang table, kolom, baris yang di butuhkan.
 */
public class KamusDatabase {
    private static final String TAG = "KamusDatabase";

    // kolom yang akan di pakai di table-nya database kamus
    // yaitu kolom KATA dan kolom ARTI_NYA
    public static final String KATA = SearchManager.SUGGEST_COLUMN_TEXT_1;
    public static final String ARTI_NYA = SearchManager.SUGGEST_COLUMN_TEXT_2;

    private static final String NAMA_DATABASE = "kamus";
    private static final String TEMPAT_MUNCUL_KATA = "membentangKebawah";
    private static final int VERSI_DATABASE = 2;
    // perantara antara database dan aplikasi
    private final DictionaryOpenHelper pembukaDatabase;
    private static final HashMap<String,String> penghubungKolom = buatPenghubungKolom();

    
     // berikut adalah Constructor-nya
     // @parameter context maksudnya pada konteks apa class ini bekerja, 
     // dalam hal ini adalah utk membuat database
     
    public KamusDatabase(Context context) {
     pembukaDatabase = new DictionaryOpenHelper(context);
    }

    
     // membuat penghubung(map) utk semua kolom yg 
     // akan di butuhkan, yang di dalam-nya akan di pasang 
     // SQLiteQueryBuilder. Ini adalah suatu cara yang 
     // baik untuk mendefinisikan nama alias dari kolom2
     // tapi hal itu berarti harus menyertakan 
     // semua kolom yg ada, termasuk kolom key 
     // dengan demikian peluang ContentProvider terbuka 
     // lebar untuk mencari kolom tanpa
     // mengenal nama asli kolom sehingga 
     // bisa membuat nama kolom samaran(alias) on the go
     // bila di butuhkan
     
    private static HashMap<String,String> buatPenghubungKolom() {
        HashMap<String,String> menghubungkan = new HashMap<String,String>();
        menghubungkan.put(KATA, KATA);
        menghubungkan.put(ARTI_NYA, ARTI_NYA);
        menghubungkan.put(BaseColumns._ID, "rowid AS " +
                BaseColumns._ID);
        menghubungkan.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " +
                SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
        menghubungkan.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "rowid AS " +
                SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
        return menghubungkan;
    }

    
     // letak-kan cursor pada kata yang di 
     // identifikasikan dengan rowId
     // @parameter barisId adalah Id dari kata yang mau di cari
     // @parameter kolom adalah salah satu kolom yg termasuk dalam search, 
     // kalau kolom==null maka semua 
     // kolom berarti di ikut sertakan dalam search
     // @return Cursor tempatkan cursor pada kata yang cocok, atau
     // null kalau tak menemukan kata yang cocok
     
    public Cursor getWord(String barisID, String[] kolom) {
        String pilihKata = "rowId = ?";
        String[] kolomTempatKata = new String[] {barisID};

        return query(pilihKata, kolomTempatKata, kolom);

        
         //  sama dengan:
         //     SELECT <columns> FROM <table> WHERE barisID = <rowId>
         
    }

    
     // Cursor akan menemukan semua kata yang 
     // sesuai dengan search pencari
     
     // @parameter query adalah string utk mendapatkan isi 
     // @parameter kolom agar kolom tetentu termasuk 
     // dalam pencarian, tapi kalau null maka
     // semuanya kolom teramsuk dalam pencarian
     // @return Cursor ambil semua kata yg cocok, 
     // atau null kalau tak satupun ygcocok.
     
    public Cursor getWordMatches(String cariKata, String[] kolom) {
        String pilihKata = KATA + " MATCH ?";
        String[] tempatPenampungKata = new String[] {cariKata+"*"};

        return query(pilihKata, tempatPenampungKata, kolom);

       
         // sama seperti mysql
         //     SELECT <columns> FROM <table> WHERE 
         //     <KEY_WORD> MATCH 'query*'
         // yang adalah bentuk search text utk 
         // FTS3 (tambah sebuah wildcard) didalam kolom kata2
         // fts3(full text search versi 3).
         
         // - "rowid" adalah unik utk semua baris tapi 
         // kita butuh nilai utk kolom "_id"  agar
         // adapter dapat bekerja, jadi kolom alias adalah 
         // "_id" untuk "rowid"
         // - "rowid" juga perlu di gunakan pada 
         // SUGGEST_COLUMN_INTENT_DATA alias sebagai
         //   pertimbangan dalam melakukan 
         //   cek intent data dengan benar.
         //   Semua alias yg di maksud di jelaskan dalam 
         //   class 'PenghubungData' pada pembuatan query.
         // - hal tsb juga dpt di rubah kalau mau search melalui 
         // ARTI_NYA daripada men-search lewat KATA
         // hal tsb dapat di lakukan dengan merubah 
         // pencarian pakai FTS3 dengan mengganti KEY_WORD dgn
         // FTS_VIRTUAL_TABLE (soearch bolak-balik) tapi 
         // hal tsb akan menyulitkan pengaturan abjad karena
         // kadang satu kata akan memiliki arti lebih dari satu kata
         
    }

    
     // melakukan query ke database.
     // @parameter 'pilihan' adalah mengatur memilih kata
     // @param gudangKataKata adalah pilihan arguments 
     // untuk komponen "?" dalam pilihan
     // @param kolom adalah kolom untuk di isi (return)
     // @return A Cursor pada semua baris yang 
     // cocok dengan tujuan pencarian
     
    private Cursor query(String pilihan, String[] gudangKataKata, String[] kolom) {
        
         // SQLiteBuilder menyediakan sebuah 
         // penghubung(map)utk semua kolom yg di request dengan
         // kolom sebenarnya di databse, membuat 
         // mekanisme kolom aliasnya yg sederhana 
         // yang mana PenghubungData tak perlu 
         // tahu nama kolom sebenarnya
         
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(TEMPAT_MUNCUL_KATA);
        builder.setProjectionMap(penghubungKolom);

        Cursor cursor = builder.query(pembukaDatabase.getReadableDatabase(),
                kolom, pilihan, gudangKataKata, null, null, null);

        if (cursor == null) {
            return null;
        } else if (!cursor.moveToFirst()) {
            cursor.close();
            return null;
        }
        return cursor;
    }


    
     // ini utk membuat/membuka databasenya.
     
    private static class DictionaryOpenHelper extends SQLiteOpenHelper {

        private final Context bantuBukaDB;
        private SQLiteDatabase databasenya;

        
         // catatan bahwa FTS3 tidak mendukung 
         // hukum kolom oleh karena itu
         // tak dapat mendeklarasikan sebuah 
         // primary key. Namun demikian, "rowid" akan  
         // di gunakan secara otomais sebagai 
         // unique identifier maka ketika membuat pencarian,
         //  kita akan gunakan "_id" sebagai sebuah
         //  alias untuk "rowid"
         
        private static final String FTS_TABLE_CREATE =
                    "CREATE VIRTUAL TABLE " + TEMPAT_MUNCUL_KATA +
                    " USING fts3 (" +
                    KATA + ", " +
                    ARTI_NYA + ");";

        DictionaryOpenHelper(Context bantuBukaKamus) {
            super(bantuBukaKamus, NAMA_DATABASE, null, VERSI_DATABASE);
            bantuBukaDB = bantuBukaKamus;
        }

        @Override
        public void onCreate(SQLiteDatabase membuatDatabase) {
            databasenya = membuatDatabase;
            databasenya.execSQL(FTS_TABLE_CREATE);
            masukanDiKamus();
        }

        
        
         // mulai sebuah thread utk masukan sebuah 
         // table di database beserta kata-katanya
         
        private void masukanDiKamus() {
            new Thread(new Runnable() {
                public void run() {
                    try {
                        masukanKataKata();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
        }

        private void masukanKataKata() throws IOException {
            Log.d(TAG, "tunggu yah sedang masukan kata...");
            final Resources sumberKataKata = bantuBukaDB.getResources();
            InputStream masukanKataKata = sumberKataKata.openRawResource(R.raw.daftar_kata_kata);
            BufferedReader membacaKataKata = new BufferedReader(new InputStreamReader(masukanKataKata));

            try {
                String barisanKataKata;
                while ((barisanKataKata = membacaKataKata.readLine()) != null) {
                    String[] daftarKataKata = TextUtils.split(barisanKataKata, "-");
                    if (daftarKataKata.length < 2) continue;
                    long idKataKata = tambahKataKata(daftarKataKata[0].trim(), daftarKataKata[1].trim());
                    if (idKataKata < 0) {
                        Log.e(TAG, "tak bisa menambah Kata: " + daftarKataKata[0].trim());
                    }
                }
            } finally {
             membacaKataKata.close();
            }
            Log.d(TAG, "selesai loading kata-kata.");
        }

       
         // tambah kata untuk membentang ke bawah.
         // @return rowId or -1 jikalau gagal
         
        public long tambahKataKata(String kata, String arti_nya) {
            ContentValues jajaranKataKata = new ContentValues();
            jajaranKataKata.put(KATA, kata);
            jajaranKataKata.put(ARTI_NYA, arti_nya);

            return databasenya.insert(TEMPAT_MUNCUL_KATA, null, jajaranKataKata);
        }

        @Override
        public void onUpgrade(SQLiteDatabase gantiDataBase, int versiLama, int versiBaru) {
            Log.w(TAG, "Database di upgrade dari versi " + versiLama + " ke "
                    + versiBaru + ", dan akan menghapus semua data yg lama");
            gantiDataBase.execSQL("DROP TABLE IF EXISTS " + TEMPAT_MUNCUL_KATA);
            onCreate(gantiDataBase);
        }
    }

}

Selain masih ada 2 class lagi yang akan di butuhkan untuk melengkapi pembuatan aplikasi ini, juga masih ada beberapa file XML sebagai tampang dan UI(user interface dari aplikasi.
Untuk membangun aplikasi Kamus Digital selengkapnya dan melihat isi dari fil-file yang saya maksud silahkan klik disini

20 comments:

  1. Wah keren banget, ini yang saya tunggu-tunggu. Jangan lama-lama ya uploadnya...

    ReplyDelete
  2. Pada baris ke-246, di komputer saya kok ada peringatan bunyinya: "raw cannot be resolved or is not a field", apa maksudnya?

    246 InputStream masukanKataKata = sumberKataKata.openRawResource(R.raw.daftar_kata_kata);

    http://imageshack.us/a/img100/1154/pic1hf.jpg

    ReplyDelete
  3. harus ada file yang bernama 'daftar_kata_kata.txt' di dalam folder bernama 'raw'

    ReplyDelete
  4. boleh sya minta file rar-nya mas, soalnya banyak terjadi error pada R.java.
    ninggalin jejak : ardianasti@gmail.com
    kunjungi juga : ardyne.wordpress.com

    sebelumnya terimakasih banyak mas.

    ReplyDelete
  5. mas kan saya mau tambahin aplikasi pencarian kalimat dikamus ini, force close trus kalau tombol pencariannya di klik, kemungkinan yang salah ada pada open databasenya, kira2 klo di source code ini mau bikin opendatabasenya bagaimana?

    ReplyDelete
    Replies
    1. seharusnya hasil search-nya keluar secara otomatis, misalnya kal kita ketik huruf 'a' maka semua yang di mulai dengan huruf akan mulai muncul di layar

      Delete
  6. numpang tanya, saya nambahin beberapa kata di daftar_kata_kata.txt, tapi kok gak bisa di search di aplikasi yah? solusinya gimana gan? maklum masih newbie

    ReplyDelete
    Replies
    1. delete aplikasi lama di emulator,
      pergi ke settings, Apps, klik pada aplikasi lalu 'Uninstall'
      terus di run lagi aplikasinya

      Delete
    2. syukur alham_d_l_l_h mas, selamat ber-koding ria

      Delete
  7. Mas, untuk masalah R.java sudah saya coba cari dan telusuri satu-satu tapi tidak ketemu penyebabnya, saya minta tolong juga mas agar file RAR di share juga ke saya
    vinche.lase@gmail.com

    terima kasih banyak mas

    ReplyDelete
    Replies
    1. sudah menuju ke TKP mas
      semoga berhasil

      Delete
  8. mas, di R.java knp banyak error ya, saya sudah cari tau tp ttp tidak dapat penyebab errornya. saya minta tlg file rar-nya di share mas
    liyaamalia21@gmail.com

    ReplyDelete
    Replies
    1. hai Liya..
      itu karena variable dari xml file belum teregistrasi ke R.java
      R.java di generate secara otomatis oleh sistim... file .rar nya on the way, silahkan di kembangkan plis-plis-plis

      Delete
    2. mas kasus ku juga sama seperti mbk liya mas R. nya gk kedetek ... klo boleh aku juga mnta file rar nya mas kirim ke emailq mnt tlg mas makasih mas

      azzamabdullah354@gmail.com

      Delete
  9. This comment has been removed by the author.

    ReplyDelete
  10. mas file R.java nya ko erorya
    tolong file rar-nya di share mas
    laodemursalim@gmail.com

    ReplyDelete
  11. mas akhirya sya dapat juga masalah di R.javanya bisa minta tolong file rar-nya ya mas tolong
    60900112078@uin-alauddin.ac.id..... masi newbie.

    ReplyDelete
  12. mas boleh minta file Rarnyakah buat tugas akhir saya dan saya sudah coba yang di sini tapi kebanyakan error di R.blabla..
    kalo boleh ini email saya...
    email : riyostefi@yahoo.co.id
    sebelumnya terima kasih banyak :)

    ReplyDelete
  13. assalamualaiikum kak vik saya berterima kasih dengan ilmu yang kakak share dan sudah saya coba kak.. tetapi koq tdk bisa dijalankan. Apakah saya boleh minta programnya?? karena ini untuk skripsi saya kak.. saya minta tolong yah kak kirim ke email aadistyana@yahoo.com atau ke andiadisty@gmail.com
    Tolong yah kak bantuannya...

    ReplyDelete