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)2013 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

11 comments:

  1. Replies
    1. thanks gan mudah2an suatu hari saya bisa hebat, silahkan di kopas dan di kembangkan mas

      Delete
  2. mas, mau tanya kalau buat galeri gambar dengan imageview, pngen ada suaranya waktu diklik gmna mas..?
    mohon bantuannya mas..

    ReplyDelete
    Replies
    1. banyak macam carnya tergantung cara masing2

      saya lebih suka pasang suaranya di contructor misalnya

      public class untukActivity extends Activity {

      public untukActivity(Bundle onSavedStateInstance) {
      // mungkin ada boject yg perlu di deklarasi disini

      MediaPlayer mp_Nya = MediaPlayer.create(this, R.raw.fileSuaraNya);

      Button tombol = (Button)this.findViewById(R.id.tombolSuara);
      tombol.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
      mp_Nya.start();
      }
      });
      }
      }

      file suaranya harus berada di dalam folder "raw"

      Delete
    2. nah ntu kan untuk menampilkan satu suara di satu button,,,
      gmn lw mau menampilkan banyak suara dalam satu button mas..? :)
      kita sharing" ya mas.. :)
      terimakasih

      Delete
    3. simpanlah suara sebanyak yang di kehendaki didalam fileSuaraNya di folder 'raw'

      Delete
    4. udah mas,,
      cara deklarasiin na gmn lw d koding na? :)

      Delete
  3. Mas, ada error di TampilanKata.java di action bar nya, mohon bantuannya makasih mas sebelumnya. (ActionBar tempatTampilKata=getActionBar())

    ReplyDelete
    Replies
    1. ActionBar ada pada android 3 ke atas... sedangka Mr Candy mungkin di bangun pakai android 3 ke bawah

      Delete
    2. mohon di develop pakai android baru atau paling kurang android versi 3 atau ke atasnya mas

      Delete
  4. wah bisa buat bahan referensi mas bro.. . mantap broo

    ReplyDelete