Kamus Bersuara

Sudah beberapa minggu terakhir ini saya telah bolak-bolak ke google untuk mencari contoh kode untuk mengimplementasikan 'kamus bersuara' yaitu kamus yang bisa membaca isinya sendiri. Sudah cukup banyak beredar kamus bersuara di internet tapi tak satupun developernya yang mau merelease kodenya ke public, mungkin karena alasan bisnis, pelit e aeh....
Yang saya maksudkan di sini adalah kamus yang isinya berada di database dan isinya itu dapat di 'searchable' dalam arti dapat di cari seperti mencari kontent di google. Coba perhatikan saat anda mencari sesuatu di google, ia seakan tahu apa yang kita mau cari atau paling kurang dia seolah mencoba menebak apa yang  kita cari. Demikian lah cara kerja kamus yang sedang kita bicarakan disini.
Saya juga bermaksud untuk membangun kamus ini tanpa koneksi internet dan atau tanpa koneksi network.
Internetnya hanya di butuhkan saat download, ....sekali download selesai, maka bisa memakai kamusnya di manapun dan kapan pun, sehingga bisa di pakai di kampung2 yang tak ada koneksi internet.

Kita ketahui bahwa sejak android 1.6 telah ada TTS(text to speech) engine yaitu engine yang bisa membaca apa yang kita tulis di layar HP seperti yang saya telah jelaskan di HpBisaNgomong
Implementasi penyimpanan data di database dan proses pencarian isi kamus telah saya jelaskan juga di artikel Kamus Digital Disana telah di buat proses dan kapabilitas mencari(searching process) yang cukup ramping dan cepat.

Sebagai proyek lanjutan saya akan menunjukan bagaimana menggabungkan kedua teknologi tersebut di atas untuk membangun sebuah kamus bahasa Inggris atau kamus bahasa2 lainnya di HP yang akan di lengkapi dengan cara membacanya menggunakan suara dan logat asli dari 'native speaker' dari bahasa2 bersangkutan.

Oleh karena lelah dan bosan untuk terus mencari jawaban di google dan juga bosan tanya2 di forum karena tak pernah ada jawaban, akhirnya saya memaksa diri untuk mencari solusi dan ternyata tidak sesulit yang saya bayangkan.
Untuk membuat 'KamusDigitalBersuara' yang bisa membaca sendiri hasil pencarian-nya maka yang menjadi pusat perhatian adalah pada halaman atau class yang berhubungan atau class yang mengatur  cara kerja halaman 'result page'
Pada artikel KamusDigital, class yang berbicara tentang 'result page' adalah bernama 'TampilanKata.java' saya memberi nama demikian hanya karena logika pribadi saya saja, oleh karena kata yang kita cari akan tampil di layar HP maka dengan demikian 'TampilanKata.java' terdengar cukup berlogika dalam kenteksnya sebagai penampil atau penunjuk kata ke layar HP.

Untuk membuat kata yang tampil bisa terbaca oleh HP maka kita perlu bubuhkan sebuah tombol "Baca" sehingga ketika di tekan akan keluar suara untuk menbaca kata yang di pilih dari database dalam logat 'native speaker' bahasa yang bersangkutan. Perhatikan gambar berikut:
Berikut adalah isi dari class 'TampilanKata.java' dengan solusi dan logika baru yang saya develop melalui 'trail and error' agar HP dapat berbicara atau bersuara membaca kata yang telah kita pilih dari database. Seperti terlihat pada gambar di atas bahwa saya telah test kodenya di emulator dan bekerja dengan baik bahkan melebihi apa yang saya harapkan. Saya sedang mencari tukang ketik untuk masukan kata2 ke database (maklum saya sendiri masih ketik pakai dua jari) sehingga nantinya kamusnya akan saya release ke pasar mudah2-an for free.
package com.vik_sintus.projects.kamusDigital;
/*
 * Copyright (C)Vik Sintus Projects
 *
 * di larang pakai kode ini untuk kepentingan komersial tanpa ijin
 * 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 java.util.Locale;

import android.app.Activity;
import android.app.ActionBar;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * class ini utk menampilkan kata-kata dan artinya.
 */
public class TampilanKata extends Activity implements OnInitListener {
 // yang perlu di baca hanya arti_kata
 private TextView arti_kata;
 private TextToSpeech membaca;
 private int KODE_UNTUK_PRIKSA_TTS = 0;
 private Button tombolBaca;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.kata);

        ActionBar tempatTampilKata = getActionBar();
        tempatTampilKata.setDisplayHomeAsUpEnabled(true);
        arti_kata = (TextView) findViewById(R.id.kolomArtinya);
        tombolBaca = (Button) findViewById(R.id.tombol_baca);
        tombolBaca.setOnClickListener(new OnClickListener(){
         
         public void onClick(View v){
          String kata = arti_kata.getText().toString();
          if (kata!=null && kata.length()>0) {
           membaca.speak(kata, TextToSpeech.QUEUE_ADD, null);
          }
         }
        });
        
        Intent priksa_TTS = new Intent();
        priksa_TTS.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(priksa_TTS, KODE_UNTUK_PRIKSA_TTS);

        Uri uri = getIntent().getData();
        Cursor cursor = managedQuery(uri, null, null, null, null);

        if (cursor == null) {
            finish();
        } else {
            cursor.moveToFirst();

            TextView kataKata = (TextView) findViewById(R.id.kolomKata);
            TextView artinya = (TextView) findViewById(R.id.kolomArtinya);

            int indexKata = cursor.getColumnIndexOrThrow(KamusDatabase.KATA);
            int indexArtinya = cursor.getColumnIndexOrThrow(KamusDatabase.ARTI_NYA);

            kataKata.setText(cursor.getString(indexKata));
            artinya.setText(cursor.getString(indexArtinya));
        }
    }
    
    @Override
    protected void onActivityResult(int ambilKataKata, int hasilDariKataKata, Intent data) {
            if (ambilKataKata == KODE_UNTUK_PRIKSA_TTS) {
                if (hasilDariKataKata == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                    // kalau kode priksa berhasil, maka buatlah instance tts 
                    membaca = new TextToSpeech(this, this);
                } 
                else {
                    // kalau belum ada TTS di HP maka minta di pasang
                    Intent pasang_TTS = new Intent();
                    pasang_TTS.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                    startActivity(pasang_TTS);
                }
            }

        }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.untuk_menu, menu);

        SearchManager aturPencarian = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView tampilanPencarian = (SearchView) menu.findItem(R.id.cari).getActionView();
        tampilanPencarian.setSearchableInfo(aturPencarian.getSearchableInfo(getComponentName()));
        tampilanPencarian.setIconifiedByDefault(false);
        
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.cari:
                onSearchRequested();
                return true;
            case android.R.id.home:
                Intent intent = new Intent(this, KamusDigital.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                return true;
            default:
                return false;
        }
    }
    
    //kalau kondisi HPnya belum ada TTS maka  
    //keluarkan prompt untuk install TTS
    public void onInit(int kondisi) { 
     // 1 baris berikut untuk logat inggris
     membaca.setLanguage(Locale.UK);
        if (kondisi == TextToSpeech.SUCCESS) {
            Toast.makeText(TampilanKata.this, 
                    "sukses di baca", Toast.LENGTH_LONG).show();
        }
        else if (kondisi == TextToSpeech.ERROR) {
            Toast.makeText(TampilanKata.this, 
                    "HP anda tak ada TextToSpeech engine", Toast.LENGTH_LONG).show();
        }
    }
}
Sebelumnya kode di atas hanya mempersembahkan hasil search dari database, yaitu hasil akhir yang menampilkan sebuah kata dan artinya, tetapi oleh karena saya ingin agar ada tombol "Baca" dan ada suara yang keluar untuk membaca kata, maka saya memerlukan beberapa object baru. Object2 baru tersebut saya deklarasikan pada awal kode antara lain:

 private TextView arti_kata;
 private TextToSpeech membaca;
 private int KODE_UNTUK_PRIKSA_TTS = 0;
 private Button tombolBaca;
Kunci untuk memahami proses kerja agar aplikasi ini bisa membaca adalah berada di 4 objects di atas. Silahkan pelajari dan telusuri keberadaan mereka pada konstruksi class 'TampilanKata.java' tersebut di atas dan memahami bagaimana ke 4 objects tersebut di gunakan untuk mensukseskan pembangunan aplikasi ini. Selamat mencoba

Kode di balik Tombol di HP Android

Masih banyak yang menanyakan tentang proses pembuatan tombol di android. Tombol yang saya maksudkan adalah ketika di pencet maka akan membawa kita ke halaman lain, sama seperti link pada web site.
Link pada android itu sendiri adalah gampang2 susah karena orientasi android yang portable.

Berikut adalah logika tombol atau link pada android.
Untuk mempermudah memahami logika tombol maka di sini saya akan membuat contoh sederhana dengan dua halaman, satunya berwarna merah dan satunya lagi berwarna hijau. Ketika sampai di halaman merah akan ada tombol yang kalau di klik akan menuju ke halaman hijau begitupun sebaliknya, seperti di tunjukan pada gambar berikut.
Contoh ini memang terasa sangat sederhana tapi kalau kita memahami benar implikasi cara kerja dan logika tombol maka akan membuka cakrawala baru dalam proses belajar untuk menjadi developer android yang tangguh.

Akan ada 7 buah file yang secara bersama merenda perkawinan antara halaman hijau dan halaman merah tersebut di atas sehingga bisa berhubungan antara satu dengan yang lain-nya melalui sebuah tombol, bahkan proses kerjanya akan meniru aplikasi benaran dalam arti dapat di install ke device.

Pada awal jaman android, aplikasi kecil seperti ini sering di pakai sebagai 'obor'/senter dengan cara mengubah salah satu halaman dengan warna putih bersih, sehingga kalau di kegelapan malam layar HP akan terang-benderang bagai lampu neon.

Ke 7 buah file yang saya singgung di atas antara lain
  • 2 buah class java untuk ke 2 halaman
  • 2 buah halaman xml sebagai tampang untuk ke 2 halaman
  • 1 buah halaman xml untuk menyimpan informasi tentang warna
  • 1 buah halaman xml untuk menyimpan semua text(tulisan)
  • 1 buah halaman xml yang di sebut AndroidManifest.xml 
Ke 2 class java antara lain (saya kasih nama sesuai logika saya sendiri, silahkan menamakan class sesuai logika masing2)
  • HalamanMerah.java
  • HalamanHijau.java
Isi dari HalamanMerah.java adalah sbb:
package com.vik_sintus.projects.pencetTombol;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;


public class HalamanMerah extends Activity {
    /** aktivitas awal yang akan di pakai mirip home page lah. */
    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        setContentView(R.layout.merah);
        Button tombolHijau = (Button) findViewById(R.id.tombol_hijau);
        tombolHijau.setOnClickListener(new View.OnClickListener() {
   
   
   @Override
   public void onClick(View v) {
   Intent intent = new Intent(
     HalamanMerah.this,
     HalamanHijau.class
   );
   startActivity(intent);
    
   }
  });
    }
}
Isi dari HalamanHijau.java adalah:
package com.vik_sintus.projects.pencetTombol;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class HalamanHijau extends Activity {

 @Override
 protected void onCreate(Bundle saveInstantState) {
  super.onCreate(saveInstantState);
  setContentView(R.layout.hijau);
  Button tombolMerah = (Button) findViewById(R.id.tombol_merah);
  tombolMerah.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    finish();

   }
  });
 }

}
Sebagai UI(user interface) dari kedua class di atas adalah dua buah halaman xml yang saya beri nama merah.xml dan hijau.xml.
Tadi di HalamanMerah.java sudah mengisyaratkan HP untuk melihat bentuk dari halaman merah di setContentView(R.layout.merah);
 Berikut adalah isi dari merah.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"
    android:gravity="bottom|center_horizontal"
    android:background="@color/latar_merah"
    >
    <TextView 
    android:id="@+id/tulisan_tombolMerah"
    android:text="@string/tulisanHalamanMerah"
    android:textColor="#cccccc" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
     />
    <Button
    android:id="@+id/tombol_hijau"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/tulisan_keHijau"
    android:textColor="@color/warnaTextHijau"
    />
</LinearLayout>
Demikian juga dengan halaman hijau, telah di isyaratkan oleh HalamanHijau.java untuk melihat bentuk halaman hijau di setContentView(R.layout.hijau);
Berikut adalah isi dari hijau.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"
    android:gravity="bottom|center_horizontal"
    android:background="@color/latar_hijau"
    >
    <TextView 
    android:id="@+id/tulisan_tombolHijau"
    android:text="@string/tulisanHalamanHijau"
    android:layout_width="wrap_content"
    android:textColor="#000000" 
    android:layout_height="wrap_content" 
     />
    <Button
    android:id="@+id/tombol_merah"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/tulisan_keMerah"
    android:textColor="@color/warnaTextMerah"
    />
</LinearLayout>
Berikut adalah untuk semua tulisan yang akan nampak di layar dan memakai default name bawaan android strings.xml
Isi dari strings.xml adalah tersirat pada isi @string di halaman hijau.xml dan halaman merah.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="tulisan_keMerah">Pergi ke Halaman Merah</string>
    <string name="tulisan_keHijau">Pergi ke Halaman Hijau</string>
    <string name="nama_aplikasi">Contoh Pencet Tombol</string>
    <string name="tulisanHalamanHijau">Ini Halaman Hijau</string>
    <string name="tulisanHalamanMerah">Ini Halaman Merah</string>
</resources>
Berikut adalah isi dari color.xml untuk mengatur warna halaman yang isinya di ambil dari @color
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="latar_merah">#FF0000</color>
<color name="latar_hijau">#00FF00</color>
<color name="warnaTextHijau">#006600</color>
<color name="warnaTextMerah">#FF0000</color>
</resources>
Berikut adalah isi dari AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.vik_sintus.projects.pencetTombol"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="3" />

    <application 
        android:icon="@drawable/icon" 
        android:label="@string/nama_aplikasi">
        <activity 
            android:name=".HalamanMerah"
            android:label="@string/nama_aplikasi">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.vik_sintus.projects.pencetTombol.HalamanHijau" />

    </application>
</manifest>
Please klik like kalau suka dengan artikel ini ..........Selamat mencoba

User Interface untuk Kamus Digital

Ini adalah seri lanjutan tentang pembangunan Kamus Digital untuk android.
Sebelum melanjutkan membaca di halaman ini ada baiknya lihat terlebih dahulu 4 buah class java yang merupakan cikal bakal pembuatan Kamus Digital ini.
Ke 4 class tersebut antara lain:
  1. KamusDigital.java
  2. KamusDatabase.java
  3. PenghubungData.java
  4. TampilanKata.java
Untuk membangun Kamus Digital maka di butuhkan 4 buah class java seperti tersebut di atas dan beberapa file XML di bawah ini , sehingga kamus akan namapak di HP sbb:
Berikut adalah beberapa halaman XML sebagai UI(user interface) dan strings untuk tampilan aplikasi Kamus Digital ini seperti terlihat pada gambar di atas.
Di  dalam systim android, segala sesuatu yang berhubungan dengan UI(user interface) seperti bentuk dan warna huruf, bentuk dan posisi tombol, warna latar belakang layar, posisi gambar dll, semuanya bernaung di bawah default folder yang bernama res konon res adalah singkatan dari 'resource' kalau benar demikian maka hal itu adalah masuk akal.

Didalam folder res, masing2 resource di bagi lagi menurut fungsi dan kegunaan-nya masing2:

drawable adalah tempat tinggal images termasuk foto dan grafik lain-nya
layout adalah tempat tinggal untuk segala sesuatu yang berhubungan dengan design halaman
menu adalah untuk segala sesuatu yang berhubungan dengan pembuatan menu
raw adalah tempat tinggal data mentah yang siap untuk di proses
values adalah tempat menyimpan tulisan utama yang tampil di layar HP
xml adalah tempat untuk menyimpan semua hal yang berhubungan dengan meta data

Selain file tersebut di atas ada satu file lagi yang amat penting bernama AndroidManifest.xml ia tidak tinggal bersama yang lain di dalam folder res karena ia adalah menyangkut application wide.
Perhatikan struktur file Kamus Digital pada gambar berikut ini

Silahkan copy kode dari blog ini dan letak-kan masing2 file seperti yang di tunjukan pada gambar di atas.

drawable ...letakan logo dalam drawable.... pada gambar di atas saya curi logo dari google yang bernama ic_menu_search.png (harus mencuri karena penyakit bawaan yang bernama malas kambuh lagi) silahkan pakai image dan logo sendiri yang penting ukuran-nya 48x48 pixels
layout ...letakan antara lain hasil.xml, kata.xml, tampilan.xml di dalam folder layout
menu ...letakan file untuk_menu.xml di dalam folder menu
raw ...letakan file daftar_kata_kata.txt di dalam folder raw
values ...letakan file strings.xml di dalam folder values
xml ...letakan file data_untuk_pencarian.xml di dalam folder xml

 Berikut adalah isi dari file-file tersebut di atas

isi dari hasil.xml adalah sbb
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C)Sintus Projects-->
 
  
<!-- ini utk layar hasil pencarian kata dan arti-nya.
 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
    <TextView
            android:id="@+id/kolomKata"
            style="@android:style/TextAppearance.Large"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    <TextView
            android:id="@+id/kolomArtinya"
            style="@android:style/TextAppearance.Small"
            android:singleLine="true"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
</LinearLayout>
Berikut adalah isi dari kata.xml
<?xml version="1.0" encoding="utf-8"?>
<!--Copyright (C)Vik Sintus Projects -->
<!-- utk tampilan layar kata2 yang --> 
<!-- keluar saat ketik pada kotak cari -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
    <TextView
            android:id="@+id/kolomKata"
            android:textSize="35dp"
            android:textColor="?android:textColorPrimary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    <TextView
            android:id="@+id/kolomArtinya"
            android:textSize="18dp"
            android:textColor="?android:textColorSecondary"
            android:paddingTop="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
</LinearLayout>
Di bawah ini adalah isi dari file tampilan.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
/**
 * Copyright (C) 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.
 */
-->
<!-- ini utk tampilan layar utama-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    <TextView
            android:id="@+id/tulisanMuncul"
            android:textColor="?android:textColorPrimary"
            android:textSize="17dp"
            android:text="@string/instruksi_utama"
            android:background="@android:drawable/title_bar"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    <ListView
            android:id="@+id/barisDemiBaris"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
</LinearLayout>

berikut adalah isi dari file untuk_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<!--Copyright (C)Vik Sintus Projects-->

<!-- menu utk cari dan TampilanKata.-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/cari"
          android:title="@string/menu_cari"
          android:icon="@drawable/ic_menu_search"
          android:showAsAction="ifRoom"
          android:actionViewClass="android.widget.SearchView" />
</menu>
Berikut adalah isi dari file strings.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright Vik Sintus Projects
**
*/
-->
<resources>

    <!-- nama aplikasi. -->
    <string name="nama_aplikasi">Kamus Digital</string>

    <!-- label yg muncul(merek) -->
    <string name="namaLabelNya">KamusDigital</string>

    <!-- tulisan yg muncul pada kotak cari. -->
    <string name="tulisanDiKotakCari">cari kata disini---</string>

    <!-- untuk menu. -->
    <string name="menu_cari">Cari---</string>

    <!-- akan terlihat di search settings utk kode ini.  -->
    <string name="artinya">Arti Kata</string>

    <!-- instruksi pada halaman utama. -->
    <string name="instruksi_utama">Silahkan ketik kata yang mau di cari</string>

    <!-- akan di tunjukan di atas hasil pencarian -->
    <plurals name="hasil_pencarian">
      <item quantity="one">%1$d result for \"%2$s\": </item>
      <item quantity="other">%1$d results for \"%2$s\": </item>
    </plurals>

    <!-- ketika pencarian gagal -->
    <string name="tak_ada_hasil">Tak ada \"%s\" dalam database</string>

</resources>

di bawah ini adalah isi dari file data_untuk_pencarian.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright Vik Sintus Projects
*/
-->

<!-- berikut adalah setingan tampang kotak search
     utk info lebih lanjut silahkan lihat
     Developer Guide di
     http://developer.android.com/guide/topics/search/
 -->
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/namaLabelNya"
        android:hint="@string/tulisanDiKotakCari"
        android:searchSettingsDescription="@string/artinya"
        android:searchSuggestAuthority="com.vik_sintus.projects.kamusDigital.PenghubungData"
        android:searchSuggestIntentAction="android.intent.action.VIEW"
        android:searchSuggestIntentData="content://com.vik_sintus.projects.kamusDigital.PenghubungData/kamus"
        android:searchSuggestSelection=" ?"
        android:searchSuggestThreshold="1"
        android:includeInGlobalSearch="true"
        >
 </searchable>
Berikut adalah isi dari file AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
 * Copyright (C)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.
 * 
 * 
 */
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.vik_sintus.projects.kamusDigital"
        android:versionCode="2"
        android:versionName="2.0">

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

    <application android:label="@string/nama_aplikasi"
                 android:icon="@drawable/ic_dictionary">

        <!-- class utama untuk masuk ke aplikasi. -->
        <activity android:name=".KamusDigital"
                  android:launchMode="singleTop">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <!-- yang menerima pencarian. -->
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
                <!-- kategori tak di perlukan,  karena Intent akan menjelaskan-nya pada
                     komponen pada class ini
                     -->
            </intent-filter>

            <!-- mengarahkan ke  meta data pencarian. -->
            <meta-data android:name="android.app.searchable"
                       android:resource="@xml/data_untuk_pencarian" />

        </activity>

        <!-- menampilkan arti kata. -->
        <activity android:name=".TampilanKata" />

        <!-- menyediakan perkiraan kata2 apa yang kira2 di cari -->
        <provider android:name=".PenghubungData"
                  android:authorities="com.vik_sintus.projects.kamusDigital.PenghubungData" />

        <!-- mengarahkan ke aktivitas cari agar aplikasi menghidupkan kegiatan pencarian. -->
        <meta-data android:name="android.app.default_searchable"
                   android:value=".KamusDigital" />

    </application>
</manifest>

Sedangkan data model yang sekaligus sebagai isi dari kamus akan di muat di file daftar_kata_kata.txt yang struktur isinya harus seperti berikut, (dimana kata berada di sebelah kiri '-' dan arti kata berada di sebelah kanan). Silahkan membuat kamus sendiri sesuai bahasa yang di kuasai
. Data seperti berikut ini sering di sebut sebagai 'raw data'(data mentah) karena terlihat amburadul dalam tampilan-nya di .txt file. Tapi kalau kode java dan kode xml-nya semua benar maka akan di olah oleh sistim agar tampil anggun di layar HP. Data berikut adalah hanya contoh, silahkan di ganti dengan kata-kata dalam bahasa yang di ikuasai
abbey - n. a monastery ruled by an abbot
abide - v. dwell; inhabit or live in
apology - n. an expression of regret at having caused trouble for someone
autonomous - j. existing as an independent entity
autonomy - n. immunity from arbitrary exercise of authority: political independence
avid - j. marked by active interest and enthusiasm
banal - j. repeated too often; over familiar through overuse
barring - n. the act of excluding someone by a negative vote or veto
bass - n. the lowest adult male singing voice
batter - n. a liquid or semiliquid mixture, as of flour, eggs, and milk, used in cooking
belle - n. a young woman who is the most charming and beautiful of several rivals
beneficial - j. promoting or enhancing well-being
bureaucracy - n. non elected government officials
butt - v. to strike, thrust or shove against
cabinet - n. persons appointed by a head of state to head executive departments of government and act as official advisers
caliber - n. a degree or grade of excellence or worth
coherent - j. marked by an orderly, logical, and aesthetically consistent relation of parts
coincidence - n. the temporal property of two things happening at the same time
collapse - v. break down, literally or metaphorically
colleague - n. an associate that one works with
collective - j. set up on the principle of collectivism or ownership and production by the workers involved usually under 

the supervision of a government
cynical - j. believing the worst of human nature and motives; having a sneering disbelief in e.g. selflessness of others
cynicism - n. a cynical feeling of distrust
daring - n. the trait of being willing to undertake things that involve risk or danger
dominant - j. exercising influence or control
dominate - v. be in control
domination - n. social control by dominating
donate - v. give to a charity or good cause
donor - n. person who makes a gift of property
drastic - j. forceful and extreme and rigorous
drought - n. a shortage of rainfall
dubious - j. open to doubt or suspicion
dynamics - n. the branch of mechanics concerned with the forces that cause motions of bodies
earnest - j. characterized by a firm and humorless belief in the validity of your opinions
esquire - n. a title of respect for a member of the English gentry ranking just below a knight; placed after the name
external - j. happening or arising or located outside or beyond some limits or especially surface
extradition - n. the surrender of an accused or convicted person by one state or country to another (usually under the provisions of a statute or treaty)
extraordinary - j. beyond what is ordinary or usual; highly unusual or exceptional or remarkable
extravagant - j. unrestrained, especially with regard to feelings
exuberant - j. joyously unrestrained
fabulous - j. extremely pleasing
the mature animal
frantic - j. excessively agitated; distraught with fear or other violent emotion
fray - v. wear away by rubbing
frequency - n. the number of occurrences within a given time period
fringe - n. a social group holding marginal or extreme views
frivolous - j. not serious in content or attitude or behavior
frontier - n. a wilderness at the edge of a settled area of a country
fundamental - j. being or involving basic facts or principles
further - v. promote the growth of
futile - j. producing no result or effect
grotesque - j. distorted and unnatural in shape or size; abnormal and hideous
grove - n. a small growth of trees without underbrush
guise - n. an artful or simulated semblance
hack - n. a mediocre and disdained writer
hale - j. exhibiting or restored to vigorous good health
handwriting - n. something written by hand
harbor - v. hold back a thought or feeling about
hazard - n. a source of danger; a possibility of incurring loss or misfortune
heir - n. a person who is entitled by law or by the terms of a will to inherit the estate of another
heritage - n. practices that are handed down from the past by tradition
hilarious - j. marked by or causing boisterous merriment or convulsive laughter
hollow - j. not solid; having a space or gap or cavity
homage - n. respectful deference
hostility - n. violent action that is hostile and usually unprovoked
humane - j. marked or motivated by concern with the alleviation of suffering
hysteria - n. excessive or uncontrollable fear
icon - n. a conventional religious painting in oil on a small wooden panel; venerated in the Eastern Church
ideology - n. an orientation that characterizes the thinking of a group or nation
illusion - n. an erroneous mental representation
invoke - v. cite as an authority; resort to
involuntary - j. not subject to the control of the will
involve - v. engage as a participant
irony - n. incongruity between what might be expected and what actually occurs
irrational - j. not consistent with or using reason
irrelevant - j. having no bearing on or connection with the subject at issue
irresistible - j. impossible to resist; overpowering
irresponsible - j. showing lack of care for consequences
judgment - n. the capacity to assess situations or circumstances shrewdly and to draw sound conclusions
judicial - j. belonging or appropriate to the office of a judge
juicy - j. lucrative
junction - n. something that joins or connects
jurisdiction - n. (law) the right and power to interpret and apply the law
juror - n. someone who serves (or waits to be called to serve) on a jury
justification - n. something (such as a fact or circumstance) that shows an action to be reasonable or necessary
juvenile - j. of or relating to or characteristic of or appropriate for children or young people
ken - n. range of what one can know or understand
knit - n. needlework created by interlacing yarn in a series of connected loops using straight eyeless needles or by machine
lament - v. regret strongly
landmark - n. the position of a prominent or well-known object in a particular landscape
landscape - n. an expanse of scenery that can be seen in a single view
lapse - n. a break or intermission in the occurrence of something
laureate - n. someone honored for great achievements; figuratively someone crowned with a laurel wreath
lavish - j. very generous
lax - j. lacking in rigor or strictness
legacy - n. (law) a gift of personal property by will
lifelong - j. continuing through life
lovable - j. having characteristics that attract love or affection
lucrative - j. producing a sizeable profit
ludicrous - j. broadly or extravagantly humorous; resembling farce
lying - n. the deliberate act of deviating from the truth
machinery - n. machines or machine systems collectively
magnet - n. (physics) a device that attracts iron and produces a magnetic field
mentor - v. serve as a teacher or trusted counselor
metal - n. any of several chemical elements that are usually shiny solids
narrator - n. someone who tells a story
naturally - a. according to nature; by natural means; without artificial help
naval - j. connected with or belonging to or used in a navy
necessary - j. absolutely essential
necessity - n. anything indispensable
network - n. an interconnected system of things or people
neutral - j. having no personal preference
nevertheless - a. despite anything to the contrary (usually following a concession)
noisy - j. full of or characterized by loud and nonmusical sounds
nomination - n. the condition of having been proposed as a suitable candidate for appointment or election
nominee - n. a politician who is running for public office
norm - n. a standard or model or pattern regarded as typical
notorious - j. known widely and usually unfavorably
observatory - n. a building designed and equipped to observe astronomical phenomena
obsolete - j. no longer in use
obstruction - n. something that stands in the way and must be circumvented or surmounted
obtain - v. come into possession of
occasion - n. a vaguely specified social event
outrage - n. a feeling of righteous anger
outrageous - j. grossly offensive to decency or morality; causing horror
outright - a. without reservation or concealment
overhaul - v. make repairs, renovations, revisions or adjustments to
oversee - v. watch and direct
overthrow - n. the termination of a ruler or institution (especially by force)
overweight - n. the property of excessive fatness
pact - n. a written agreement between two states or sovereigns
pageant - n. a rich and spectacular ceremony
panic - n. an overwhelming feeling of fear and anxiety
pantheon - n. all the gods of a religion
paradox - n. (logic) a statement that contradicts itself
parallel - j. being everywhere equidistant and not intersecting
released by the court without imprisonment subject to conditions imposed by the court
qualify - v. make fit or prepared
quarterly - a. in three month intervals
radical - j. markedly new or introducing extreme change
resistant - j. impervious to being affected
resort - v. have recourse to
rural - j. living in or characteristic of farming or country life
rustic - j. characteristic of the fields or country
sacrifice - v. kill or destroy
superb - j. of surpassing excellence
systematic - j. characterized by order and planning
tactics - n. the branch of military science dealing with detailed maneuvers to achieve objectives set by strategy
tangible - j. perceptible by the senses especially the sense of touch
taxation - n. the imposition of taxes; the practice of the government in levying 
trivial - j. of little substance or significance
truthful - j. expressing or given to expressing the truth
turmoil - n. a violent disturbance
ubiquitous - j. being present everywhere at once
urban - j. located in or characteristic of a city or city life
urgency - n. an urgent situation calling for prompt action
usage - n. the act of using
utility - n. the quality of being of practical use
vacuum - n. a region that is devoid of matter
valid - j. well grounded in logic or truth or having legal force
variation - n. an artifact that deviates from a norm or standard
volatile - j. liable to lead to sudden change or violence
vulnerable - j. capable of being wounded or hurt
warrant - v. stand behind and guarantee the quality, accuracy, or condition of
wherever - a. where in the world
wholly - a. to a complete degree or to the full or entire extent ('whole' is often used informally for 'wholly')
woo - v. seek someone's favor
zeal - n. excessive fervor to do something or accomplish some end

NB. Agar kodenya terlihat agak bersih, silahkan lihat pakai 'view plain' pada kiri atas kotak kode.
---------selamat mencoba---------

4.a Menampilkan kata_kata

Sebagai lanjutan dari tulisan tentang membuat Kamus Digital untuk di pasang di HP android, berikut adalah class untuk menampilkan kata-kata ke layar HP, dengan demikian maka saya menamakan-nya TampilanKata.java.
class lain yang di butuhkan untuk membangun aplikasi ini adalah KamusDigital.java, KamusDatabase.java, PenghubungData.java

Berikut adalah isi dari class TampilanKata.java
/*
 * Copyright (C)Vik Sintus Projects
 *
 * di larang pakai kode ini untuk kepentingan komersial tanpa ijin
 * 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.
 * 
 */

package com.vik_sintus.projects.kamusDigital;

import android.app.Activity;
import android.app.ActionBar;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.SearchView;
import android.widget.TextView;

/**
 * class ini utk menampilkan kata-kata dan artinya.
 */
public class TampilanKata extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.kata);

        ActionBar tempatTampilKata = getActionBar();
        tempatTampilKata.setDisplayHomeAsUpEnabled(true);

        Uri uri = getIntent().getData();
        Cursor cursor = managedQuery(uri, null, null, null, null);

        if (cursor == null) {
            finish();
        } else {
            cursor.moveToFirst();

            TextView kataKata = (TextView) findViewById(R.id.kolomKata);
            TextView artinya = (TextView) findViewById(R.id.kolomArtinya);

            int indexKata = cursor.getColumnIndexOrThrow(KamusDatabase.KATA);
            int indexArtinya = cursor.getColumnIndexOrThrow(KamusDatabase.ARTI_NYA);

            kataKata.setText(cursor.getString(indexKata));
            artinya.setText(cursor.getString(indexArtinya));
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.untuk_menu, menu);

        SearchManager aturPencarian = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView tampilanPencarian = (SearchView) menu.findItem(R.id.cari).getActionView();
        tampilanPencarian.setSearchableInfo(aturPencarian.getSearchableInfo(getComponentName()));
        tampilanPencarian.setIconifiedByDefault(false);
        
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.cari:
                onSearchRequested();
                return true;
            case android.R.id.home:
                Intent intent = new Intent(this, KamusDigital.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                return true;
            default:
                return false;
        }
    }
}
Selain ke 4 class di atas masih ada beberapa file untuk UI(user interface) dan file xml lain-nya klik disini

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

Penghubung antara aplikasi dan data

2.a Penghubung antara aplikasi dan data

.....ini adalah seri lanjutan dari 'Membuat Kamus Digital'
Sebelum melanjutkan baca tentang class penghubung antara aplikasi dan data di halaman ini silahkan baca dahulu tentang class 'KamusDigital'

 Berikut adalah class java yang menghubungkan data dengan aplikasi yang saya beri nama PenghubungData.java
/*
 * 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
 *
 * 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.
 * 
 * 
 */

package com.vik_sintus.projects.kamusDigital;

import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;

/**
 * utk akses ke kamus database.
 * class 'PenghubungData' ini bertindak sebagai 
 * perantara antara database dan aplikasi
 */
public class PenghubungData extends ContentProvider {
    String TAG = "PenyediaData";
   // tunjukan alamat database
    public static String AUTHORITY = "com.vik_sintus.projects.kamusDigital.PenghubungData";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/kamus");

    // MIME types (multi-media/multi-purpose internet mail extension) utk 
    // mencari KATA dan Arti_NYA 
    public static final String MIME_TYPE_KATA = ContentResolver.CURSOR_DIR_BASE_TYPE +
                                                  "/vnd.vik_sintus.projects.kamusDigital";
    public static final String MIME_TYPE_ARTI_NYA = ContentResolver.CURSOR_ITEM_BASE_TYPE +
                                                       "/vnd.vik_sintus.projects.kamusDigital";

    private KamusDatabase KamusKu;

    // untuk mencocokan lokasi resource-nya
    // melalui URI(universal resource identifier)
    private static final int KLIK_PD_KATA = 0;
    private static final int DAPAT_ARTI_KATA = 1;
    private static final int KATA_YG_KELUAR = 2;
    private static final int REFRESH_SHORTCUT = 3;
    private static final UriMatcher cocokan_URI_nya = buatkan_UriMatcher_nya();

    
    private static UriMatcher buatkan_UriMatcher_nya() {
        UriMatcher mencocokanURI =  new UriMatcher(UriMatcher.NO_MATCH);
        //  klik pd kata agar artinya muncul
        mencocokanURI.addURI(AUTHORITY, "kamus", KLIK_PD_KATA);
        mencocokanURI.addURI(AUTHORITY, "kamus/#", DAPAT_ARTI_KATA);
        // kata-kata yang keluar saat ketik di kotak search
        mencocokanURI.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, KATA_YG_KELUAR);
        mencocokanURI.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", KATA_YG_KELUAR);

        /* berikut tak di pakai, tapi kalau kita pakai
         * {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} sebagai 
         * kolom di table, maka kita akan menerima
         * refresh queries ketika a shortcutted suggestion di 
         * tayangkan di Quick Search Box, yg dalam hal ini,
         * URI berikut di sediakan dan kita akan
         * mengembalikan kursor dengan single item yg 
         * merepresentasikan sugesti dat yang telah di refresh.
         */
        mencocokanURI.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT, REFRESH_SHORTCUT);
        mencocokanURI.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", REFRESH_SHORTCUT);
        return mencocokanURI;
    }

    @Override
    public boolean onCreate() {
        KamusKu = new KamusDatabase(getContext());
        return true;
    }

    /**
     * utk menghandle semua pencarian dan kata2 apa yang di perkirakan akan 
     * muncul dari Search Manager.
     * ketika mencari kata yang telah kita ketahui, hanya URI akan di perlukan.
     * ketika mencari semua kata2 atau tak jelas kata apa
     * yang mau di cari, maka 'pilihDariSemuaKataYgAda' harus sebagai
     * elemen pertama untuk search query.
     * semua argumen lain-nya akan di kesampingkan/tak dipedulikan.
     */
    @Override
    public Cursor query(Uri uri, String[] perkiraanKata, String pilihan, String[] pilihDariSemuaKataYgAda,
                        String menurutAbjad) {

        // gunakan UriMatcher utk melihat query macam 
     // apa saja yang kita butuhkan sehingga
     // DB query dapat di format sesuai kebutuhan
        switch (cocokan_URI_nya.match(uri)) {
            case KATA_YG_KELUAR:
                if (pilihDariSemuaKataYgAda == null) {
                  throw new IllegalArgumentException(
                      "oik, tak ada data yg mau di pilih di: " + uri);
                }
                return getSuggestions(pilihDariSemuaKataYgAda[0]);
            case KLIK_PD_KATA:
                if (pilihDariSemuaKataYgAda == null) {
                  throw new IllegalArgumentException(
                      "oik, tak ada data yg mau di pilih di: " + uri);
                }
                return search(pilihDariSemuaKataYgAda[0]);
            case DAPAT_ARTI_KATA:
                return getWord(uri);
            case REFRESH_SHORTCUT:
                return refreshShortcut(uri);
            default:
                throw new IllegalArgumentException("tak mengenal alamat Uri: " + uri);
        }
    }

    private Cursor getSuggestions(String deretanKataYgMuncul) {
      deretanKataYgMuncul = deretanKataYgMuncul.toLowerCase();
      String[] kolom_nya = new String[] {
          BaseColumns._ID,
          KamusDatabase.KATA,
          KamusDatabase.ARTI_NYA,
       /* SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
                        (hanya jikalau short cut-nya butuh di refresh) */
          SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};

      return KamusKu.getWordMatches(deretanKataYgMuncul, kolom_nya);
    }

    private Cursor search(String kataYgDiCari) {
      kataYgDiCari = kataYgDiCari.toLowerCase();
      String[] kolom_nya = new String[] {
          BaseColumns._ID,
          KamusDatabase.KATA,
          KamusDatabase.ARTI_NYA};

      return KamusKu.getWordMatches(kataYgDiCari, kolom_nya);
    }

    private Cursor getWord(Uri uri) {
      String rowId = uri.getLastPathSegment();
      String[] columns = new String[] {
          KamusDatabase.KATA,
          KamusDatabase.ARTI_NYA};

      return KamusKu.getWord(rowId, columns);
    }

    private Cursor refreshShortcut(Uri uri) {
      /* berikut takan di gunakan pada 
       * implementasi ini, tapi kalau kitan mengikut sertakan
       * {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} sebagai sebuah 
       * kolom suggestions table, kita akan menerima refresh queries
       * ketika sebuah shortcutted suggestion di tunjukan di kotak Quick Search
       * dalam arti, methode ini  akan melihat kedalam table utk kata tertentu
       * menggunakan item dalam URI dan menyediakan 
       * semua kolom yang tadinya di sediakan untuk 
       * suggestion query.
       */
      String barisId = uri.getLastPathSegment();
      String[] semuaKolom = new String[] {
          BaseColumns._ID,
          KamusDatabase.KATA,
          KamusDatabase.ARTI_NYA,
          SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
          SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};

      return KamusKu.getWord(barisId, semuaKolom);
    }

    /**
     * metode berikut di perlukan agar 
     * dapat men-query tipe query yang di dukung.
     * dan juga berguna dalam metode query() kita sendiri agar 
     * mengetahui type URI yang di terima.
     */
    @Override
    public String getType(Uri uri) {
        switch (cocokan_URI_nya.match(uri)) {
            case KLIK_PD_KATA:
                return MIME_TYPE_KATA;
            case DAPAT_ARTI_KATA:
                return MIME_TYPE_ARTI_NYA;
            case KATA_YG_KELUAR:
                return SearchManager.SUGGEST_MIME_TYPE;
            case REFRESH_SHORTCUT:
                return SearchManager.SHORTCUT_MIME_TYPE;
            default:
                throw new IllegalArgumentException("Unknown URL " + uri);
        }
    }

    // implementasi lain yang di butuhkan

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException();
    }

}

Berikut adalah class KamusDatabase.java

Membuat Kamus Digital

Kamus digital adalah kamus yang bisa di muat dalam HP, agar mudah di akses, dan mudah di baca kapanpun dan dimanapun. Tentunya HP-nya android dong.
Kamus digital yang akan saya bangun ini adalah spesial, karena untuk menjalankan-nya ia tidak membutuhkan koneksi network atau koneksi internet.
Kamus Digital ini juga akan meniru pencarian di google, dimana ia akan dengan cepat menebak kira2 kata apa yang kita mau cari, ia akan  menyuguhkan ke layar HP  berbagai pilihan kata dari yang hampir benar sampai yang paling benar. Dan ketika di klik pada kata yang di butuhkan maka aplikasi akan membukanya dan memperlihatkan isinya(arti kata). Perhatikan gambar2 berikut


Gambar berikut menunjukan kecerdasan mencari dari aplikasi ini, ketika ketik huruf  'a' maka aplikasinya dengan cepat mencari database untuk semua yang di awali huruf  'a'. Ia mencoba menebak apa yang mau di cari oleh pengguna sehingga mudah untuk mendapatkan kata apa yang mau di cari.


Setelah pengguna menemukan kata yang ingin di cari maka aplikasi ini mempersembahkan soft keyboard yang siap di pergunakan untuk pencarian kata(data) selanjutnya.

Langkah membangun aplikasi Kamus Digital ini akan mengikuti nalar dan logika cara berpikir dari kebanyakan orang (orang biasa) seperti saya dan anda. Oleh karena itu, logikanya bahwa kalau mau menyimpan kamus di dalam HP tentunya kita harus membuat HP-nya agar bisa melakukan hal2 dengan kriteria sbb:

1. Bisa mebuka kamus
2. Ada penghubung antara aplikasi dan data.
3. Ada tempat untuk bisa menampung data
4. Ada tempat untuk menampilkan kata2

Kalau kita terjemahkan ke 4 logika di atas masing2 kedalam class program java maka pembuka kamus adalah identik dengan class 'main' yang sebagian besar aktivitasnya adalah hanya untuk memulai dan membuka aplikasi 'Kamus Digital' ini. Secara sederhana class main dalam bahasa program java(android) adalah mirip dengan home page pada halaman web, yaitu kerja utamanya adalah sebagai pintu masuk kedalam web atau aplikasi. Tentunya halaman depan atau home page dapat bekerja lebih banyak daripada sekedar pintu masuk, demikian juga halnya dengan class main pada aplikasi yang di bangun pakai bahasa program java, seperti aplikasi android yang sedang kita bicarakan di sini.

1.a Bisa membuka kamus

Sebagai class main atau sebagai pintu masuk dan atau sebagai halaman awal dari aplikasi' Kamus Digital' ini, maka saya akan membuatkan class yang saya beri nama KamusDigital.java silahkan membuat nama class sesuai logika masing2
Berikiut adalah isi dari class KamusDigital.java
/*
 * Copyright (C)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
 *
 * 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.
 * 
 * 
 */

package com.vik_sintus.projects.kamusDigital;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

/**
 * beraksi sebagai halaman depan (main).
 * yang menayangkan hasil pencarian dari 'search dialog' dan
 * menghandle aksi apa yg di lakukan dengan hasil.
 */
public class KamusDigital extends Activity {

    private TextView munculTulisan;
    private ListView barisanKata;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tampilan);

        munculTulisan = (TextView) findViewById(R.id.tulisanMuncul);
        barisanKata = (ListView) findViewById(R.id.barisDemiBaris);

        handleIntent(getIntent());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        // oleh karena aktivitas-nya di set dengan launchMode="singleTop", itu berarti 
        // halaman(aktivitas) dapat di daur ulang dalam arti kalau halaman telah 
     // di buka sebelumnya maka tak perlu di buka lagi tapi hanya menghidupkan 
     // intent pada halaman tsb sehingga mengangkatnya ke depan (terlihat lagi)
        
     
        
        handleIntent(intent);
    }

    private void handleIntent(Intent intent) {
        if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            // mengatur klik utk search suggestion dan menghidupkan
         // activity yg membuat kata2 bisa di klik
            Intent agarKataDptDiKlik = new Intent(this, TampilanKata.class);
            agarKataDptDiKlik.setData(intent.getData());
            startActivity(agarKataDptDiKlik);
            finish();
        } else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            // mengatur query pencarian
            String query = intent.getStringExtra(SearchManager.QUERY);
            showResults(query);
        }
    }

    /**
     * cari di kamus dan tunjukan hasil dari query tertentu
     * @parameter query-nya adalah search query
     */
    private void showResults(String query) {

        Cursor cursor = managedQuery(PenghubungData.CONTENT_URI, null, null,
                                new String[] {query}, null);

        if (cursor == null) {
            // kalau tak ada hasil di ketemukan
            munculTulisan.setText(getString(R.string.tak_ada_hasil, new Object[] {query}));
        } else {
            // tunjukan beberapa hasil
            int count = cursor.getCount();
            String countString = getResources().getQuantityString(R.plurals.hasil_pencarian,
                                    count, new Object[] {count, query});
            munculTulisan.setText(countString);

            // KATA di taruh di kolom 'kolomKata' 
            // ARTI_NYA di taruh di 'kolomArtinya'
            String[] dari = new String[] { KamusDatabase.KATA,
                                           KamusDatabase.ARTI_NYA };

            // buatkan hubungan antara design element, dimana kolom akan muncul 
            int[] ke = new int[] { R.id.kolomKata,
                                   R.id.kolomArtinya };

            // buatkan cursor adapter sederhana utk semua kata dan 
            // artinya dan tayangkan baris demi baris(ListView) pada layar
            SimpleCursorAdapter letakanKataPadaTempatnya = new SimpleCursorAdapter(this,
                                          R.layout.hasil, cursor, dari, ke);
            barisanKata.setAdapter(letakanKataPadaTempatnya);

            // apa yg terjadi saat klik pada kata2 yang telah berjajar baris demi baris di layar 
            barisanKata.setOnItemClickListener(new OnItemClickListener() {
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    // ketika sebauh kata dapat di klik
                    Intent kataDiKlik = new Intent(getApplicationContext(), TampilanKata.class);
                    Uri data = Uri.withAppendedPath(PenghubungData.CONTENT_URI,
                                                    String.valueOf(id));
                    kataDiKlik.setData(data);
                    startActivity(kataDiKlik);
                }
            });
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater perpanjangTampilan = getMenuInflater();
        perpanjangTampilan.inflate(R.menu.untuk_menu, menu);

        SearchManager mengaturSearch = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView tampilanSearch = (SearchView) menu.findItem(R.id.cari).getActionView();
        tampilanSearch.setSearchableInfo(mengaturSearch.getSearchableInfo(getComponentName()));
        tampilanSearch.setIconifiedByDefault(false);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.cari:
                onSearchRequested();
                return true;
            default:
                return false;
        }
    }
}
Untuk sekarang saya kehabisan waktu, nanti akan saya buatkan ke 3 class lain-nya, sehingga kalau semuanya sudah termuat disini maka siapapun bisa copy dan paste untuk di pakai di aplikasi masing2. Apalagi bagi mereka yang bisa bahasa asing, aplikasi macam ini bisa di adaptasikan, dapat di jual di pasar bebas seperti 'google play' dll. Calon developer Kamus Digital ini hanya akan mengisi data terjemahan dari bahasa asing yang dia tahu, misalnya Indonesia-Jerman, Prancis-Indonesia, Manggarai-Bajawa dll.

2.a Ada Penghubung Antara Aplikasi dan Data

Silah melihat class penghubung antara aplikasi dan data di sini

Aplikasi agar HP bisa mendengar dan bisa menulis

Saya telah mengirimi kode ini ke beberapa teman2 yang membutuhkan-nya. Tapi karena penyakit bawaan saya yang bernama m a l a s kambuh lagi maka untuk selanjutnya saya tidak akan kirim lagi lewat email dan atau PM. Bagi yang berminat menelusuri kode ini silahkan datang kesini dan ambil sendiri... sorry yah

Ini adalah struktur kode paling sederhana untuk aplikasi Speech Recognition yaitu aplikasi yang bisa membuat HP menulis apa yang kita ucap(ucapnya yang jelas yah biar HPnya bisa paham). Bagi teman2 yang pintar java tentunya sangat mudah untuk mengembangkan aplikasi ini lebih lanjut sesuai kebutuhan masing2.
Aplikasi ini telah saya jalankan testing di beberapa device yang menggunakan sistim android baik yang layar kecil seperti HP maupun di layar lebar seperti tablet khususnya tablet samsung dan motorola ukuran 7 inch maupun yang 10 inch, dan alhamdulillah tampang user interfacenya(UI) semuanya terlihat sama, begitu pula cara kerja dan logika aplikasinya semuanya sama, hal itu menunjukan bahwa aplikasinya telah bekerja sesuai rencana.

Walau aplikasi ini sudah bekerja dengan baik namun saya enggan untuk di pasang ke android market karena masih membutuhkan koneksi internet untuk bisa bekerja.
Alasan-nya bahwa terlalu banyak kata yang di pakai oleh aplikasi untuk mencoba menebak kira2 kata apa saja yang di ucapkan manusia saat berbicara dengan HP. Oleh karena terlalu banyak, maka tempat simpan(storage) HP terlalu kecil sehingga lebih baik di biarkan saja di simpan milliaran kata2 tsb di server-nya google. Dengan demikian maka pada halaman AndroidManifest.xml hanya membutuhkan permission khusus yang berbunyi ' <uses-permission android:name="android.permission.RECORD_AUDIO" /> ' sehingga setiap kali kitan ngomong dengan HP maka dengan cepat HP-nya mencari ke server kira2 kata2 apa yang telah kita ucap, dan suguhkan-nya ke layar dari yang kira2 benar sampai yang ke paling benar.
Hal itu berbeda dengan aplikasi 'TTS(text to speech) yang bekerja tanpa koneksi internet yang saya tulis sebelumnya silahkan baca TTS disini

Tapi... oleh karena banyak teman yang PM saya untuk minta kodenya, maka berikut adalah class utama untuk menjalankan aplikasi 'Speech Recognition' yang saya beri nama SuaraJadiTeks.java



package com.vik_sintus.projects.suaraJadiTeks;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.speech.RecognizerIntent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
 
/**
 *aplikasi agar HP bisa mendengar dan menulis
 *silahkan di pakai untuk kepentingan belajar
 *Tak boleh di pakai utk kepentingan komersial
 *hubungi vik.sintus@gmail.com
 *segala kelebihan dan kekurangan di luar tanggungjawab pembuat
 */
public class SuaraJadiTeks extends Activity {
 
    private static final int PRIKSA_KEBENARAN_NYA = 1234;
    private ListView daftarKataYangKeluar;
 
    //suruh android utk buka aplikasi yang
    //tampang depannya berada di R.layout.suara_jadi_teks

@Override
public void onCreate(Bundle savedInstanceState){
   super.onCreate(savedInstanceState);
   setContentView(R.layout.suara_jadi_teks);
   Button tombol = (Button) findViewById(R.id.tombolUntukBicara);
   daftarKataYangKeluar = (ListView) findViewById(R.id.daftarKataKata);
 
        // Kalau tak ada service maka matikan tombolnya
        // dan tinggalkan pesan agar pengguna tak bingung
 PackageManager paketAplikasi = getPackageManager();
 List<resolveinfo> aktivitas = paketAplikasi.queryIntentActivities(
   new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
      if (aktivitas.size() == 0){
   tombol.setEnabled(false);
   tombol.setText("salah..tak bisa di buka...coba konek ke internet");
        }
    }
 
   //ketika tombol di tekan apa yang harus di lakukan
    
    public void ketikaTombolDiTekan(View v)
    {
        mulaiAktivitasSuaraJadiTeks();
    }
 
    // mulai aktivitas voice recognition dengan 
    // menghidupkan Intent-nya.
     
 private void mulaiAktivitasSuaraJadiTeks(){
   Intent ubahSuaraJadiTeks = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
   ubahSuaraJadiTeks.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
   ubahSuaraJadiTeks.putExtra(RecognizerIntent.EXTRA_PROMPT, "Demo suara jadi teks...");
        startActivityForResult(ubahSuaraJadiTeks, PRIKSA_KEBENARAN_NYA);
    }
 
    //Olah hasil dari Intent.
    
  @Override
  protected void onActivityResult(int kodePriksa, int ambilHasil, Intent hasil){
     if (kodePriksa == PRIKSA_KEBENARAN_NYA && ambilHasil == RESULT_OK){
// isi dengan kata2 yang cocok menurut apa yang di 
// dengar oleh device
// dan kalau device mendengar/merekam lebih 
// banyak kata-kata(EXTRA_RESULT)maka daftarKataKataYangKeluar di 
// adaptasikan dengan ArrayAdapter menggunakan
// tampilan/interface yang bernama simple_list_item_1
      ArrayList<string> kataYangCocok = hasil.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);daftarKataYangKeluar.setAdapter(new ArrayAdapter<string>(this, android.R.layout.simple_list_item_1,kataYangCocok));
        }
        super.onActivityResult(kodePriksa, ambilHasil, hasil);
    }
}


Berikut adalah sedikit penjelasan dari kode di atas
public class SuaraJadiTeks extends Activity {
private static final int PRIKSA_KEBENARAN_NYA = 1234;
    private ListView daftarKataYangKeluar;
 
}
Untuk melakukan kegiatan-nya class 'SuaraJadiTeks' harus bergandengan dengan class 'Activity'.
class 'Activity itu sendiri sudah ada dalam android sistim, kita hanya merangkulnya saja dengan kata kunci extends.
 Kita juga butuh tempat untuk menampung kata-kata yang di dengarkan oleh hp, dan kita ingin kata-kata yang keluar di layar HP harus berjajar baris demi baris mulai dari bagian atas layar. Untuk menghasilkan itu kita  membutuhkan bantuan class ListView . Selain itu kita juga membutuhkan sebuah data bertipe integer(int) yang di pergunakan untuk mengecek kebenaran bahwa suara yang keluar dari HP adalah benar2 menuliskan kata-kata yang kita ucap alias bukan membaca dari tempat lain.
@Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.suara_jadi_teks);
 
        Button tombol = (Button) findViewById(R.id.tombolUntukBicara);
 
        daftarKataYangKeluar = (ListView) findViewById(R.id.daftarKataKata);
Kode di atas menjelaskan apa yang akan di lakukan ketika aplikasinya di buka? lihat isi aplikasinya di setContentView(R.layout.suara_jadi_teks);
Di dalam aplikasi akan ada tombol Button tombol = (Button) findViewById(R.id.tombolUntukBicara); dan juga akan ada daftar deretan kata yang di tuliskan oleh HP daftarKataYangKeluar = (ListView) findViewById(R.id.daftarKataKata);

Kemudian, kita membutuhkan jasa class PackageManager untuk membungkus semua objects dan classses yang menjalankan aktivitas aplikasi agar tidak tercecer. Sedangkan class List dan class ResolveInfo adalah untuk mengatur aktivitas aplikasi agar dapat di proses oleh class RecognizerIntent yang notabene adalah engine utama aplikasi ini yang beraksi sebagai ACTION_RECOGNIZE_SPEECH atau aksi yang memahami kata-kata yang kita ucap.
Kalau aktivitasnya tak ada if (aktivitas.size() == 0) maka matikan tombolnya tombol.setEnabled(false); dan berikan penjelasan kepada pengguna mengapa aplikasinya tak bekerja dengan tombol.setText("tak bisa di buka...mungkin kodenya salah... coba konek ke internet")
PackageManager paketAplikasi = getPackageManager();
  List<resolveinfo> aktivitas = paketAplikasi.queryIntentActivities(
   new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
   if (aktivitas.size() == 0)
     {
       tombol.setEnabled(false);
       tombol.setText("tak bisa di buka, mungkin kodenya salah... coba konek ke internet");
        }

Beberapa dokumen lain yang di butuhkan

Ada ciri khas khusus dalam android struktur, seperti adanya AndroidManifest.xml ia bekerja sebagai pintu gerbang bagi semua aplikasi android, silahkan baca tentang AndroidManifest selengkapnya di http://developer.android.com/guide/topics/manifest/manifest-intro.html

Berikut adalah isi dari AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.vik_sintus.projects.suaraJadiTeks"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
  
    <application android:label="VoiceRecognition" android:icon="@drawable/icon"
            >
        <activity android:name=".SuaraJadiTeks"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
Selain AndroidManfest.xml, aplikasi ini juga membutuhkan tampang/interface agar dapat di lihat, di colek dan di sentuh oleh manusia. Berikut adalah interface dari aplikasi ini yang saya beri nama suara_jadi_teks.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:orientation="vertical">
 
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="4dip"
        android:text="@string/suruhBicara" />
 
    <Button android:id="@+id/tombolUntukBicara"
        android:layout_width="fill_parent"
        android:onClick="tombolSudahDiTekan"
        android:layout_height="wrap_content"
        android:text="@string/tombol" />
 
    <ListView android:id="@+id/daftarKataKata"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" />
 
 </LinearLayout>
Berikut adalah strings.xml seperti yang di isyaratkan oleh @string pada kode di atas
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">SuaraJadiTeks</string>
    <string name="voice_recognition_prompt">Demo Suara Jadi Teks</string>
    <string name="tombol">Tekan disini</string>
    <string name="suruhBicara">Tekan tombol dan mulai bicara</string>
</resources>

mmmhhh.... apa lagi yah
Saya rasa itu saja yang di butuhkan agar aplikasi 'speech recognition' ini bisa bekerja.

Untuk refresh ingatan... yang kita butuhkan adalah
1 SuaraJadiTeks.java
2 AndroidManifest.xml
3 suara_jadi_teks.xml
4 strings.xml

Note: nama file adalah case sensitive, maksudnya harus mengindahkan huruf kecil atau huruf besar serta tanda baca yang ada di nama file tsb

Baca disini langkah untuk bangun aplikasi android pakai eclipse