Tutorial: Membuat Aplikasi Android Jadwal Sholat menggunakan Kotlin

Pada tutorial kali ini kita akan membahas tentang pembuatan aplikasi android sederhana yang akan menampilkan Jadwal Sholat berdasarkan kota yang dipilih. Aplikasi ini belum melakukan deteksi lokasi menggunakan GPS. Jadi aplikasi ini masih sangat sederhana. Fokus utama dari tutorial kali ini adalah pada proses penggunaan API Jadwal Sholat, yaitu proses membaca JSON API dan menampilkannya pada android.

Aplikasi ini akan kita buat menggunakan bahasa pemrograman Kotlin dan API Jadwal Sholat yang diambil dari API Fatimah Bot. Disana disediakan berbagai macam jenis API salah satunya adalah Jadwal Sholat.

Ok, langsung saja kita mulai membuat project baru dengan nama JadwalSholatApp.

Membuat Project

Buka android studio, kemudian klik new project, pilih pilihan layout pilih Layout Empty. Dan jangan lupa untuk mencentrang pilihan Include Kotlin support.

Pertama kita siapkan terlebih dahulu layout tampilan aplikasi kita. Pada aplikasi ini kita membutuhkan satu buah Spinner untuk menampilkan dropdown daftar kota yang bisa dipilih. Kemudian kita siapkan beberapa TextView untuk menampilkan jadwal sholat 5 waktu per tanggal hari yang aktif. Layout yang kita gunakan adalah LinearLayout.

Buka file activity_main.xml, sesuaikan kodenya seperti berikut:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:padding="@dimen/padding"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Spinner
            android:id="@+id/kota"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <LinearLayout
            android:orientation="vertical"
            android:layout_marginTop="@dimen/vertical_margin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/tv_tanggal"
                android:text="Tanggal"
                android:layout_marginBottom="@dimen/vertical_margin"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:text="Subuh"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="@dimen/left_width"
                    android:layout_height="wrap_content"/>

                <TextView
                    android:id="@+id/tv_subuh"
                    android:text="12"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

            </LinearLayout>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:text="Dzuhur"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="@dimen/left_width"
                    android:layout_height="wrap_content"/>

                <TextView
                    android:id="@+id/tv_dzuhur"
                    android:text="12"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

            </LinearLayout>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:text="Ashar"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="@dimen/left_width"
                    android:layout_height="wrap_content"/>

                <TextView
                    android:id="@+id/tv_ashar"
                    android:text="12"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

            </LinearLayout>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:text="Maghrib"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="@dimen/left_width"
                    android:layout_height="wrap_content"/>

                <TextView
                    android:id="@+id/tv_maghrib"
                    android:text="12"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

            </LinearLayout>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:text="Isya"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="@dimen/left_width"
                    android:layout_height="wrap_content"/>

                <TextView
                    android:id="@+id/tv_isya"
                    android:text="12"
                    android:layout_marginBottom="@dimen/vertical_margin"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

            </LinearLayout>

        </LinearLayout>

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

Selanjutnya, kita perlu menyiapkan API Client yang akan membaca data dari server JSON API dari Fatimah Bot. Disini kita akan mengaplikasikan AsyncTask Loader dan HTTPClient untuk memjalankan proses pada background. Selain itu kita juga memerlukan class data (POJO) yang akan digunakan untuk meyimpan data kota.

Untuk membuat class POJO, klik menu New -> Kotlin File/Class, kemudian berinama Kota.kt dan tulis kode berikut:

class Kota {
    var id: Int? = null
    var nama: String? = null

    override fun toString(): String {
        return nama.toString()
    }
}

Selanjutnya buat class baru lagi dengan nama ClientAsyncTask.kt untuk membuat class API Client. Disini kita akan mengaplikasikan penggunaan AsyncTask Loader untuk memanggil data dari server JSON API dengan memanfaatkan HttpURLConnection.

Pada class tersebut kita akan menambahkan sebuah interface event listener untuk memproses hasilnya pada event onPostExecute.

Kemudian sesuaikan kodenya seperti berikut:

class ClientAsyncTask constructor(private val mContext: Context, postExecuteListener: OnPostExecuteListener) :
    AsyncTask<String, String, String>() {
    val CONNECTON_TIMEOUT_MILLISECONDS = 60000
    private val mPostExecuteListener : OnPostExecuteListener = postExecuteListener

    interface OnPostExecuteListener {
        fun onPostExecute(result: String)
    }

    override fun onPostExecute(result: String) {
        super.onPostExecute(result)
        if (mPostExecuteListener != null) {
            mPostExecuteListener.onPostExecute(result)
        }
    }

    override fun doInBackground(vararg urls: String?): String {
        var urlConnection: HttpURLConnection? = null

        try {
            val url = URL(urls[0])

            urlConnection = url.openConnection() as HttpURLConnection
            urlConnection.connectTimeout = CONNECTON_TIMEOUT_MILLISECONDS
            urlConnection.readTimeout = CONNECTON_TIMEOUT_MILLISECONDS

            var inString = streamToString(urlConnection.inputStream)

            return inString
        } catch (ex: Exception) {

        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect()
            }
        }

        return ""
    }

    fun streamToString(inputStream: InputStream): String {

        val bufferReader = BufferedReader(InputStreamReader(inputStream))
        var line: String
        var result = ""

        try {
            do {
                line = bufferReader.readLine()
                if (line != null) {
                    result += line
                }
            } while (line != null)
            inputStream.close()
        } catch (ex: Exception) {

        }

        return result
    }

}

Selanjutnya kita buka file MainActivity.kt, sesuaikan kodenya seperti berikut:

class MainActivity : AppCompatActivity() {
    private var listKota: MutableList<Kota>? = null
    private var mKotaAdapter: ArrayAdapter<Kota>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        listKota = ArrayList<Kota>()
        mKotaAdapter = ArrayAdapter<Kota>(this, android.R.layout.simple_spinner_item, listKota)
        mKotaAdapter!!.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        kota.adapter = mKotaAdapter
        kota.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onNothingSelected(p0: AdapterView<*>?) {

            }

            override fun onItemSelected(p0: AdapterView<*>?, view: View?, position: Int, id: Long) {

                val kota = mKotaAdapter!!.getItem(position)
                loadJadwal(kota.id)
            }

        }

        loadKota()
    }

}

Sebelumnya, kita perlu menambahkan method baru pada class tersebut, yaitu method loadKota() dan loadJadwal().

Tambahkan method loadKota() yang digunakan untuk mengambil data daftar kota dan akan ditampilkan pada Spinner daftar kota.

fun loadKota() {
        try {
            var url = "https://api.banghasan.com/sholat/format/json/kota"
            val task = ClientAsyncTask(this, object : ClientAsyncTask.OnPostExecuteListener {
                override fun onPostExecute(result: String) {

                    Log.d("KotaData", result)
                    try {
                        val jsonObj = JSONObject(result)
                        val jsonArray = jsonObj.getJSONArray("kota")
                        var kota: Kota? = null
                        for (i in 0 until jsonArray.length()) {
                            val obj = jsonArray.getJSONObject(i)
                            kota = Kota()
                            kota!!.id = obj.getInt("id")
                            kota!!.nama = obj.getString("nama")
                            listKota!!.add(kota)
                        }
                        mKotaAdapter!!.notifyDataSetChanged()

                    } catch (e: JSONException) {
                        e.printStackTrace()
                    }
                }

            })
            task.execute(url)
        }catch (e: Exception) {
            e.printStackTrace()
        }
    }

Selanjutnya tambahkan method loadJadwal() untuk mengambil data jadwal sholat berdasarkan kota pilihan apabila Spinner kota di pilih, maka fungsi ini akan dijalankan.

private fun loadJadwal(id: Int?) {
        try {
            val id_kota = id.toString()

            val current = SimpleDateFormat("yyyy-MM-dd")
            val tanggal = current.format(Date())

            var url = "https://api.banghasan.com/sholat/format/json/jadwal/kota/$id_kota/tanggal/$tanggal"
            val task = ClientAsyncTask(this, object : ClientAsyncTask.OnPostExecuteListener {
                override fun onPostExecute(result: String) {

                    Log.d("JadwalData", result)
                    try {
                        val jsonObj = JSONObject(result)
                        val objJadwal = jsonObj.getJSONObject("jadwal")
                        val obData = objJadwal.getJSONObject("data")

                        tv_tanggal.text = obData.getString("tanggal")
                        tv_subuh.text = obData.getString("subuh")
                        tv_dzuhur.text = obData.getString("dzuhur")
                        tv_ashar.text = obData.getString("ashar")
                        tv_maghrib.text = obData.getString("maghrib")
                        tv_isya.text = obData.getString("isya")

                        Log.d("dataJadwal", obData.toString())

                    } catch (e: JSONException) {
                        e.printStackTrace()
                    }
                }

            })
            task.execute(url)
        }catch (e: Exception) {
            e.printStackTrace()
        }

    }

Kedua fungsi diatas akan memanggil class ClientAsyncTask yang sudah dibuat sebelumnya.

Selanjutnya jangan lupa aktifkan permisson untuk akses internet. Buka file AndroidManifest.xml, tambahkan kode berikut:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="id.web.koding.jadwalsholat">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

OK, sampai disini kode sudah selesai, tinggal kita coba aplikasinya dengan cara menjalankannya. Siapkan emulator atau android device untuk mencobanya. Kemudian klik tombol Run.

Source code lengkap bisa di ambil disini.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *