Membuat Kolom dan Baris berwarna di Android

Ada yang tanya saya bagaimana agar kolom data tampak cantik dan berwarna-warni di android.
Sorry saya tak sempat jawab bukan karena pelit ...tetapi jawaban-nya rada panjang dan perlu waktu yang cukup panjang untuk menganalisi dan menganalisa.

Jawaban singkatnya adalah ...buatlah sebuah adapter yang merangkul class SimpleAdapter().
Silahkan buka kode java yang ingin isinya atau hasil output-nya akan muncul berwarna-warni. Coba lihat kode pada baris yang mirip berikut ini
ListAdapter adapter = new SimpleAdapter();
Output data anda tak berwarna-warni atau hanya berwarna polos karena class SimpleAdapter() bawaan android tersebut memang sengaja di buat polos karena warna kesukaan setiap manusia pasti berbeda-beda, sehingga bagi yang ingin membuat output-nya berwarna-warni maka buatlah class dengan implementasi sendiri. Implementasi yang saya maksudkan adalah dalam arti untuk membangun sebuah class baru dengan merangkul class SimpleAdapter bawaan android tersebut dengan menggunakan kata kunci 'extends'

Proses membuat sebuah class adalah membutuhkan analisis yang amat rumit ( ini menurut saya), sehingga dengan demikian membuat class baru yang saya maksudkan di atas adalah bukan benar-benar baru, sehingga tak perlu harus super pintar, namun kita  hanya meminjam struktur yang telah ada di class bawaan android dengan membatalkan cara kerja metode yang telah ada disana dengan memasang cara kerja dan metode dari kita sendiri. Metode yang kita butuhkan untuk melihat warna dll adalah bernama getView(), dan kita harus membatalkan cara kerja aslinya dengan memasang @override sebelumnya(diatasnya) .Berikut adalah contoh class yang bekerja untuk adaptasi warna yang saya beri nama AdapterUtkWarna.java

package com.vik_sintus.projects.warna_baris;
/**
 * Copyright ©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 java.util.HashMap;
import java.util.List;
 
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SimpleAdapter;
 
public class AdapterUtkWarna extends SimpleAdapter {
    private int[] warnaYgDipakai = new int[] { 0x30ffffff, 0x30ff2020, 0x30000000 };
     //berikut adalah constructor_nya
    public AdapterUtkWarna(Context contextNya, List<HashMap<String, String>> bagianYgDiWarnai, int sumberNya, String[] darimana, int[] kemana) {
        super(contextNya, bagianYgDiWarnai, sumberNya, darimana, kemana);
    }
 
    @Override
    public View getView(int wilayahYgdiWarnai, View perubahanWarna, ViewGroup semuaWarna) {
      View tampilanAkhir = super.getView(wilayahYgdiWarnai, perubahanWarna, semuaWarna);
      int posisiWarna = wilayahYgdiWarnai % warnaYgDipakai.length;
      tampilanAkhir.setBackgroundColor(warnaYgDipakai[posisiWarna]);
      return tampilanAkhir;
    }
}

Saya pasang tiga warna pada metode warnaYgDiPakai, tapi anda boleh pasang warna sesuka hati. Perhatikan bagian constructor pada kode di atas dan lihat List<HashMap<String, String>> kode tersebut maksudnya adalah aturlah data horisontal(dalam satu baris) dengan benar baru kemudian di susun baris demi baris berjajar kebawah. List adalah untuk membuat data berjajar, dan HashMap untuk mencocokan data yang berada di sebalah kiri dengan data yang berada di kanan sehingga datanya tidak amburadul ( di android hal itu sering di sebut 'mapping'). Data yang di maksudkan disini adalah warna yang mau di cat di table data. Kalau bukan demikian maka warna table datanya akan terlihat bagaikan bibirnya cewek mabuk yang memoleskan lipstick di bibirnya sambil nyetir di jalan yang bebatuan.
Selebihnya kode di atas adalah self explanatory-lah

Bagaimana Cara Menggunakan class AdapterUtkWarna.java ?

Penggunaan -nya tergantung kebutuhan_lah, dan tergantung skenario aplikasi.
Tetapi oleh karena saya tak punya aplikasi yang membutuhkan table data yang warna-warni, maka saya hanya akan membuat sbuah skenario tentang sebuah table data yang isinya memiliki 4 buah kolom dan jumlah barisnya tak terhingga.
Mungkin anda tanya mengapa hanya 4 kolom tapi jumlah barisnya tak terhingga?... man, kita sedang berada di dalam dunia perHPan... lihatlah layar HP-mu ... buatkanlah aplikasi yang cocok untuknya. Melihat penggunaan layar HP secara tradisional, scrolling ke bawah adalah termasuk lumrah tapi setelah scrolling kebawah awak mau scrolling ke kanan pula? wadoh cape dah...kasihan pengguna...  tetapi itu semua tergantung selera developer-lah kawan

Ok keempat kolom-nya yaitu untuk 'nomor urut',  'kolom_1', 'kolom_2', dan 'kolom_3'. Berikut adalah design interface atau tampangnya(saya termasuk bego dalam hal design) anda boleh mendesign yang lebih meriah. Disini saya hanya kasih contoh saja:
Setelah berdiskusi antara saya, aku dan diriku maka kami bersepakat untuk menamakan halaman design ini dengan nama warna_halaman.xml
Berikut adalah isi dari warna_halaman.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent">
    <!-- Bagian atas yg ungu yah-->
    <LinearLayout android:id="@+id/bagian_atas"
        android:background="#9966cc"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        >
        <TextView android:id="@+id/kotak1"
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:text="No:  "
            android:width="20dip"
            android:height="30dip"
        />
        <TextView android:id="@+id/kotak2"
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:layout_marginLeft="10dip"
            android:text="Kolom_1"
            android:width="100dip"
            android:height="30dip"
        />
        <TextView android:id="@+id/kotak3"
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:text="Kolom_2"
            android:width="100dip"
            android:height="30dip"
        />
        <TextView android:id="@+id/kotak4"
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:text="Kolom_3"
            android:width="100dip"
            android:height="30dip"
        />
    </LinearLayout>
 
    <!-- untuk garis perantara -->
    <View android:layout_width="fill_parent"
        android:layout_height="1dip"
        android:background="?android:attr/listDivider" />
 
    <!-- untuk tiap cell(kotak) -->
    <LinearLayout android:id="@+id/tampilan_nya"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent">
        <ListView android:id="@+id/warna_tampilan_nya"
            android:layout_height="fill_parent"
            android:layout_width="fill_parent">
        </ListView>
    </LinearLayout>
</LinearLayout>

Lihat di bagian TextView ada 4 buah kolom dengan android:text="No", android:text="Kolom_1", android:text="Kolom_2", android:text="Kolom_3"  ke 4 nya masing2 di berikan identitas agar dapat di program.
Kode di atas akan mengahasilkan table kosong, karena belum ada data, dan ia akan tampak sbb:


 Ok mari kita program activity-nya atau kegiatan apa yang akan memakai class AdapterUtkWarna.java di atas, sehingga data yang kosong akan ada isinya. Disini saya hanya membuat skenario bahwa setiap cell (kotak) akan menyebut namanya sendiri(sebagai data_nya(content_nya)). Misalnya: kol1_baris1, kol2_baris1, kol3_baris1 dst...
Activity di android sama dengan 'main' di java atau miriplah... berikut adalah class main yang saya beri nama WarnaBaris.java yang akan memperagakan kebolehan class AdapterUtkWarna.java.

Berikut adalah isi dari WarnaBaris.java

package com.vik_sintus.projects.warna_baris;
/**
 * Copyright ©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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
 
public class WarnaBaris extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.warna_halaman);
        ListView tampilanNya= (ListView)findViewById(R.id.warna_tampilan_nya);
 
        // buat peta hubungan antara kolom dan baris (mapping)
        // baris_id untuk klm_no_urt, kol1 untuk utk_kolom1 dst
        String[] darimana = new String[] {"baris_id", "kol1", "kol2", "kol3"};
        int[] kemana = new int[] { R.id.klm_no_urut, R.id.utk_kolom1, R.id.utk_kolom2, R.id.utk_kolom3 };
 
        // siapkan perlengkapan data yang mau di pasang
        List<HashMap<String, String>> melengkapiData = new ArrayList<HashMap<String, String>>();
        for(int namaBaris = 1; namaBaris < 13; namaBaris++){
            HashMap<String, String> menghubungData = new HashMap<String, String>();
            menghubungData.put("baris_id", "" + namaBaris);
            menghubungData.put("kol1", "kol1_baris" + namaBaris);
            menghubungData.put("kol2", "kol2_baris" + namaBaris);
            menghubungData.put("kol3", "kol3_baris" + namaBaris);
            melengkapiData.add(menghubungData);
        }
        // kotak di warnai dengan warna dari class AdapterUtkWarna
        AdapterUtkWarna adaptasiWarna = new AdapterUtkWarna(this, melengkapiData, R.layout.per_baris_nya, darimana, kemana);
        tampilanNya.setAdapter(adaptasiWarna);
    }
}


Lihat cara pemakaian class AdapterUtkWarna, dia butuh tampilan UI(user interface) dengan nama per_baris_nya.xml
Berikut adalah isi dari per_baris_nya.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
        <TextView android:id="@+id/klm_no_urut"
            android:text=""
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:width="20dip"
        />
        <TextView android:id="@+id/utk_kolom1"
            android:text=""
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:width="100dip"
        />
        <TextView android:id="@+id/utk_kolom2"
            android:text=""
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:width="100dip"
        />
        <TextView android:id="@+id/utk_kolom3"
            android:text=""
            android:layout_height="fill_parent"
            android:layout_width="wrap_content"
            android:width="100dip"
        />
</LinearLayout>

Setelah pasang di HP atau coba di emulator maka hasilnya akan tampak sbb:
Pengunaan class adapter seperti class AdapterUtkWarna.java seperti tersebut di atas tidak saja terbatas pada contoh yang saya tunjukan, tapi ia juga bisa mewarnai data yang di ambil dari database baik dari lokal data maupun remote data(remote data maksudnya data yang tersimpan di belahan bumi lain atau di kota lain) . Warna tampilan-nya tinggal di adaptasi-lah.
Perhatikan ClassBacaKomentar.java pada tutorial 2 disana saya implementasikan ListAdapter bawaan android yang menggandeng class SimpleAdapter, sehingga menghasilkan warna default atau warna asli turunan OS android. Datanya berada di remote.
Kode yang saya tulis disana adalah nampak sbb
ListAdapter adapterNya = new SimpleAdapter(this, susunanKomentar,
    R.layout.komentar_tunggal, new String[] { TAG_USERNAME, TAG_JUDUL_KOMENTAR, TAG_ISI_KOMENTAR
       }, new int[] { R.id.usernameNya, R.id.judul, R.id.komentar
       });

Di situ saya menggunakan class default sehingga hasilnya default pula(hanya putih) seperti nampak pada gambar berikut
Setelah implementasinya di ubah dengan class buatan saya sendiri yaitu class AdapterUtkWarna.java maka kodenya menjadi sbb:
AdapterUtkWarna adapterNya = new AdapterUtkWarna(this, tampilanKomentarNya,
    R.layout.komentar_tunggal, new String[] { TAG_USERNAME, TAG_JUDUL_KOMENTAR, TAG_ISI_KOMENTAR
       }, new int[] { R.id.usernameNya, R.id.judul, R.id.komentar
       });

Class AdapterUtkWarna.java menghasilkan warna output sbb:
Silahkan di coba, let me know kalau ada yang macet

Membangun Class JSON(javaScript Object Notation) untuk definisi pertukaran data antara server dan klien

Ini adalah lanjutan dari tutorial tentang komunikasi antara Android, PHP dan MYSQL database. Tapi sebelum melanjutkan baca halaman ini, bacalah lebih dahulu tutorial bagian1, bagian 2 dan bagian 3.

Di halaman ini kita akan membuat sebuah class JSON yang akan di pakai oleh class-class lain-nya agar sebuah aplikasi bisa dinamik dan responsive. Kalau perhatikan isi  dari class-class di tutorial bagian1, 2 dan 3 ...disana  JSON_nya telah di deklarasi dan telah terpakai dengan nama ClassJSONParser.java. Saya sengaja menamakan-nya demikian karena ia memang bekerja untuk 'parsing' data antar klien dan server.

Berikut adalah isi dari ClassJSONParser.java
package com.vik_sintus.projects.koneksiandroidmysql;
/** ©Vik Sintus Projects */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;
 
public class ClassJSONParser {
 
    static InputStream inputStreamNya = null;
    static JSONObject JSONObjectNya = null;
    static String jsonStringNya = "";
 
    // berikut adalah constructor-nya
    public ClassJSONParser() {
 
    }
    
    //ambil json object melalui url script_nya maksudnya
    //object yang dari php yang ada di server
    public JSONObject ambilJsonDariUrl(final String urlNya) {

        // object dari Json di ambil melalui http request
        try {
            // kirim data bolak-balik pakai 'post' yah biar agak aman.
            DefaultHttpClient httpClientNya = new DefaultHttpClient();
            HttpPost httpPostNya = new HttpPost(urlNya);

            // begitu juga dengan jawaban dari server pakai metode POST
            HttpResponse httpResponseNya = httpClientNya.execute(httpPostNya);
            // mengambil data yang dapat di response oleh server.
            HttpEntity httpEntityNya = httpResponseNya.getEntity();
            // buka sebuah inputStream ke data yang ada.
            inputStreamNya = httpEntityNya.getContent();

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            // buat sebuah  BufferedReader untuk di parse melalui inputStream.
            BufferedReader bufferedReaderNya = new BufferedReader(new InputStreamReader(
                    inputStreamNya, "iso-8859-1"), 8);
            // deklarasikan sebuah string utk membantu proses parsing-nya.
            StringBuilder stringBuilderNya = new StringBuilder();
            // deklarasi sebuah string utk menyimpan 
            // data JSON object dalam bentuk string.
            String barisanStringNya = null;
            
            // susun string-nya sampai null(habis). baris demi baris
            while ((barisanStringNya = bufferedReaderNya.readLine()) != null) {
                stringBuilderNya.append(barisanStringNya + "\n");
            }
            
            // tutup input stream-nya.
            inputStreamNya.close();
            // ubalah 'string builder data' menjadi string aslinya.
            jsonStringNya = stringBuilderNya.toString();
        } catch (Exception e) {
            Log.e("BufferNya Salah", "Salah mengolah menjadi string aslinya " + e.toString());
        }

        // coba mengolah stringNya menjadi sebuah JSON object
        try {
            JSONObjectNya = new JSONObject(jsonStringNya);
        } catch (JSONException e) {
            Log.e("JSON ParserNya", "Salah Mengolah data " + e.toString());
        }

        return JSONObjectNya;

    }
    
 
    // fungsi ambilJsonDariUrl dengan
    // cara HTTP POST atau GET 
    public JSONObject membuatHttpRequest(String urlNya, String caraNya,
            List<NameValuePair> parameterNya) {
 
        // buat jalur HTTP-nya
        try {
 
            // priksa metode yang di pakai POST atau GET
            if(caraNya == "POST"){
                DefaultHttpClient httpClientNya = new DefaultHttpClient();
                HttpPost httpPostNya = new HttpPost(urlNya);
                httpPostNya.setEntity(new UrlEncodedFormEntity(parameterNya));
 
                HttpResponse httpResponseNya = httpClientNya.execute(httpPostNya);
                HttpEntity httpEntityNya = httpResponseNya.getEntity();
                inputStreamNya = httpEntityNya.getContent();
            //kalau pakai cara 'GET' maka search string_nya akan
            //tampak di URL
            }else if(caraNya == "GET"){
                DefaultHttpClient defaultHttpClientNya = new DefaultHttpClient();
                String stringYgTampakDiUrl = URLEncodedUtils.format(parameterNya, "utf-8");
                urlNya += "?" + stringYgTampakDiUrl;
                HttpGet httpGetNya = new HttpGet(urlNya);
 
                HttpResponse httpResponseNya = defaultHttpClientNya.execute(httpGetNya);
                HttpEntity httpEntityNya = httpResponseNya.getEntity();
                inputStreamNya = httpEntityNya.getContent();
            }           
 
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        try {
            BufferedReader bufferedReaderNya = new BufferedReader(new InputStreamReader(
                    inputStreamNya, "iso-8859-1"), 8);
            StringBuilder stringBuilderNya = new StringBuilder();
            String barisanDataNya = null;
            while ((barisanDataNya = bufferedReaderNya.readLine()) != null) {
             stringBuilderNya.append(barisanDataNya + "\n");
            }
            inputStreamNya.close();
            jsonStringNya = stringBuilderNya.toString();
        } catch (Exception e) {
            Log.e("Buffer_nya Error", "Salah mengkonvert hasil" + e.toString());
        }
 
        // coba parsing string-nya menjadi JSON object
        try {
            JSONObjectNya = new JSONObject(jsonStringNya);
        } catch (JSONException e) {
            Log.e("JSON ParserNya", "Salah proses datanya " + e.toString());
        }
 
        return JSONObjectNya;
 
    }
}


Saya telah menyisipkan banyak komentar di dalam kode di atas.... silahkan di coba di bangun di android dan di kembangkan menjadi aplikasi besar

Kalau ingin coba menjalankan aplikasi ini di HP atau di emulator ...Berikut adalah beberapa file pelengkap aplikasi ini. Ada satu file xml yang tidak ada class pasangan-nya seperti ClassBacaKomentar.java berpasangan dengan baca_komentar.xml.
File yang yang tak punya pasangan itu bernama komentar_tunggal.xml yang harus di tempatkan bersama file xml yang lain-nya di dalam folder 'layout' di android. Dia bekerja untuk mengatur tampilan dari setiap satu komentar. Berikut adalah isi dari file komentar_tunggal.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="wrap_content"
    android:background="#f0f0f0"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/garis_pinggir_komentar"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/kotakKomentar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="2dp"
            android:background="@drawable/latar_belakang_komentar"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/imageView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/lodokn_one" />

            <LinearLayout
                android:id="@+id/kotakKomentar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="2dp"
                android:orientation="vertical"
                android:padding="5dp" >

                <TextView
                    android:id="@+id/judul"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
                    android:paddingBottom="2dip"
                    android:paddingLeft="5dp"
                    android:paddingTop="6dip"
                    android:textColor="#333"
                    android:textSize="16sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/komentar"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingBottom="2dip"
                    android:paddingLeft="8dp"
                    android:textColor="#888" >
                </TextView>

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

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:gravity="left"
                        android:paddingLeft="5dp"
                        android:text="Nama: "
                        android:textColor="#5d5d5d"
                        android:textStyle="bold" >
                    </TextView>

                    <TextView
                        android:id="@+id/usernameNya"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:gravity="left"
                        android:textColor="#acacac"
                        android:textStyle="bold" >
                    </TextView>
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

Perhatikan file komentar_tunggal.xml diatas ia minta dua buah file untuk di masuk-kan ke dalam folder 'drawable' . Kedua file tsb antara lain:
garis_pinggir_komentar.xml yang isinya nampak sebagai berikut:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true"><shape>
            <solid android:color="#cccccc" />
        </shape></item>
    <item><shape>
            <gradient android:angle="270" 
                      android:endColor="#ccc" 
                      android:startColor="#fff" />

            <corners android:radius="2dp" />
        </shape></item>

</selector>

Dan latar_belakang_komentar.xml sebagai berikut
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true">
        <shape>
            <solid android:color="#cccccc" />
        </shape></item>
    <item><shape>
            <gradient android:angle="90" 
                      android:endColor="#f5f5f5" 
                      android:startColor="#fff" />
        </shape></item>

</selector>

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.koneksiandroidmysql"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/nama_aplikasi"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.vik_sintus.projects.koneksiandroidmysql.ClassUtkLogIn"
            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.koneksiandroidmysql.ClassRegistrasi"
            android:label="@string/nama_aplikasi"  >
        </activity>
        <activity
            android:name="com.vik_sintus.projects.koneksiandroidmysql.ClassTambahKomentar"
            android:label="@string/nama_aplikasi"  >
        </activity>
         <activity
            android:name="com.vik_sintus.projects.koneksiandroidmysql.ClassBacaKomentar"
            android:label="@string/nama_aplikasi"  >
        </activity>
    </application>

</manifest> 
masih ada beberapa file lagi ... stay tune yah

Android, PHP dan MYSQL database bagian 3

Sebelum baca halaman bagian 3 ini, bacalah dahulu Android PHP dan MYSQL bagian 1 dan Android PHP dan MYSQL bagian 2
Bagian 1 dan bagian 2 meliputi halaman Login, halaman Baca Komentar dan halaman Registrasi
Dan sekarang sampailah kita pada halaman untuk Tambah Komentar, baik itu untuk Tambah Komentar di bagian server maupun tentang Tambah Komentar bagian klien-nya. Seperti saya katakan sebelumnya, bahwa bagian klien-nya di bangun pakai java dan bagian server di bangun pakai PHP.

Perhatikan kode di ClassBacaKomentar.java di tutorial bagian 2. Disana saya telah tulis sebuah metode untuk membuka class baru bernama tambahKomentar(); yang nampak sebagai berikut
public void tambahKomentar(View v) {
  Intent intentNya = new Intent(ClassBacaKomentar.this, ClassTambahKomentar.class);
  startActivity(intentNya);
 }

Itu berarti bahwa dari dalam ClassBacaKomentar ada ClassTambahKomentar, dan oleh karena ClassTambahKomentar tersimpan di sebuah tombol di dalam ClassBacaKomentar maka metode tambahKomentar(); di panggil dari UI(user interface) dalam hal ini metode-nya di panggil dari dalam baca_komentar.xml melalui metode android:onClick
Perhatikan kode berikut yang saya ambil dari dalam baca_komentar.xml. Perlu di ingat bahwa baca_komentar.xml adalah UI-nya ClassBacaKomentar

<button 
    android:background="@drawable/tombol_kirim" 
    android:id="@+id/tombol_kirim" 
    android:layout_gravity="right" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:onclick="tambahKomentar" 
    android:text="@string/tombol_kirim" />


Sangat jelas terlihat bahwa sepotong kode xml di atas adalah membicarakan tombol Kirim Komentar yang letaknya pada bagian bawah halaman Baca Komentar, sangat jelas bukan? Mau lihat lagi bentuknya? nihhh

Ok ketika tekan tombol Kirim Komentar tentunya yang di triger adalah halaman Tambah Komentar, Oleh karena itu mari kita bangun sebuah class yang bekerja untuk itu. Kita sebut saja nama class-nya  ClassTambahKomentar.java Berikut adalah isinya
package com.vik_sintus.projects.koneksiandroidmysql;
/**
 * Copyright ©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 java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class ClassTambahKomentar extends Activity implements OnClickListener{
 
 private EditText isiJudul, isiKomentar;
 private Button  kirimKomentar;
 
  // utk progress bar_nya
    private ProgressDialog progressBarNya;
 
    // utk tambah komentar perlu deklarasi class JSON
    ClassJSONParser jsonParserNya = new ClassJSONParser();
    
 // lokasi script utk tambah komentar: bernama tambah_komentar.php

  // biasanya localhost :
  // tapi untuk testing, lebih baik pakai alamat IP
  // kalau tak tahu IP-nya di windows silahkan buka
  // command prompt lalu ketik ipconfig
  // lihat IPv4 Address
  // kalau di mac ketik ifconfig dan cari ip dengan en0 atau en1
  // private static final String LINK_TAMBAH_KOMENTAR =
  // "http://xxx.xxx.x.x.xxx/folderNya/tambah_komentar.php";

  // coba di Emulator:jangan lupa di ganti dengan 
        //alamat IP komputer anda sendiri
    private static final String LINK_TAMBAH_KOMENTAR = "http://192.168.1.109/mysql_android/tambah_komentar.php";
    
    // coba di server jauh(remote), server bayaran:
 // private static final String LINK_TAMBAH_KOMENTAR =
 // http://www.namaWeb.com/folderNya/tambah_komentar.php;

 // berikut adalah identitas dari JSON element yang
 // merespond dari halaman PHP (tambah_komentar.php)
    private static final String TAG_BERHASIL = "sukses";
    private static final String TAG_PESAN = "pesan";
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  
  super.onCreate(savedInstanceState);
  setContentView(R.layout.tambah_komentar);
  
  isiJudul = (EditText)findViewById(R.id.judulKomentar);
  isiKomentar = (EditText)findViewById(R.id.isiKomentar);
  
  kirimKomentar = (Button)findViewById(R.id.kirimKomentar);
  kirimKomentar.setOnClickListener(this);
  
 }

 @Override
 public void onClick(View v) {
    new TambahKomentar().execute();
 }
 
 
 class TambahKomentar extends AsyncTask<String, String, String> {
  
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressBarNya = new ProgressDialog(ClassTambahKomentar.this);
            progressBarNya.setMessage("Sedang kirim Komentarnya...");
            progressBarNya.setIndeterminate(false);
            progressBarNya.setCancelable(true);
            progressBarNya.show();
        }
  
  @Override
  protected String doInBackground(String... args) {
   // priksa jika proses tambah komentar berhasil
    // lihat TAG_BERHASIL
            int komentar_sukses;
            String judulKomentar = isiJudul.getText().toString();
            String komentar = isiKomentar.getText().toString();
            
            //ini harus di ubah 
            SharedPreferences sharedPrefNya = PreferenceManager.getDefaultSharedPreferences(ClassTambahKomentar.this);
            String userNameNya = sharedPrefNya.getString("username_nya", "anon");
            
            try {
                // menyusun parameter-nya
                List<NameValuePair> parameterNya = new ArrayList<NameValuePair>();
                parameterNya.add(new BasicNameValuePair("username_nya", userNameNya));
                parameterNya.add(new BasicNameValuePair("judul_komentar", judulKomentar));
                parameterNya.add(new BasicNameValuePair("isi_komentar", komentar));
 
                Log.d("me-request!", "dimulai");
                
                //kirim data dari user ke halaman php script 
                JSONObject jsonObjectNya = jsonParserNya.membuatHttpRequest(
                  LINK_TAMBAH_KOMENTAR, "POST", parameterNya);
 
                // jawaban dari JSON
                Log.d("mencoba kirim komentar", jsonObjectNya.toString());
 
                // Bagian JSON jika komentarnya berhasil/tidak terkirim
                komentar_sukses = jsonObjectNya.getInt(TAG_BERHASIL);
                if (komentar_sukses == 1) {
                 Log.d("Komentar_nya telah di masukan!", jsonObjectNya.toString());    
                 finish();
                 return jsonObjectNya.getString(TAG_PESAN);
                }else{
                 Log.d("Kirim komentar_nya Gagal!", jsonObjectNya.getString(TAG_PESAN));
                 return jsonObjectNya.getString(TAG_PESAN);
                 
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
 
            return null;
   
  }
  
        protected void onPostExecute(String url_link_nya) {
            // matikan progressBarnya dengan metode dismiss();
            progressBarNya.dismiss();
            if (url_link_nya != null){
             Toast.makeText(ClassTambahKomentar.this, url_link_nya, Toast.LENGTH_LONG).show();
            }
 
        }
  
 }
   

}

Agar ClassTambahKomentar.java dapat di lihat oleh manusia maka di perlukan tampang UI_nya dengan nama tambah_komentar.xml berikut adalah isinya:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true"
        android:src="@drawable/lodok" />

    <EditText
        android:id="@+id/isiKomentar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/kirimKomentar"
        android:layout_alignParentLeft="true"
        android:layout_alignRight="@+id/textView2"
        android:layout_below="@+id/TextView01"
        android:ems="10"
         />

    <EditText
        android:id="@+id/judulKomentar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/textView1"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/imageView1"
        android:text="isi Judul" />

    <Button
        android:id="@+id/kirimKomentar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:text="Kirim Komentar" />

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/judulKomentar"
        android:layout_marginTop="14dp"
        android:text="isi Komentar" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:gravity="center"
        android:text="Koneksi Android MYSQL"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textStyle="bold" />

</RelativeLayout>

Berikut adalah tampang dari halaman Tambah Komentar pada layar HP anda

Bandingkan kode XML-nya dengan tampangnya, disana dengan jelas terlihat bahwa UI android tidak sesulit yang di bayangkan.
Kode untuk halaman Tambah Komentar bagian klien sudah selesai...
Berikut adalah kode untuk halaman Tambah Komentar bagian server yang saya beri nama tambah_komentar.php
<?php
/**
 * Copyright ©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.
 * 
 * 
 */
//perlu data dari konfigurasi_nya.php untuk bisa koneksi
require("/konfigurasi_nya.php");

if (!empty($_POST)) {
     
  if (empty($_POST['judul_komentar']) || empty($_POST['isi_komentar'])) {
        
        
        // data yang di pakai oleh JSON untuk respond ke android 
        $jawaban_dari_server["sukses"] = 0;
        $jawaban_dari_server["pesan"] = "Mohon di isi Judul dan komentarNya.";
        
        // kalau judul dan komentar belum di isi maka
  // hentikan aplikasi-nya dengan metode die(); sambil mengeluarkan 
  // pesan tsb diatas ke android
        die(json_encode($jawaban_dari_server));
    }

 //query yang di perlukan utk isi komentar
 $query = "INSERT INTO tempat_komentar ( username_nya, judul_komentar, isi_komentar ) VALUES ( :user, :judul, :komentar ) ";

    //query-nya perlu di update karena VALUES belum ada di database,
 // :user, :judul, :komentar hanya di buat2 sebagai
 //  place holder persiapkan tempat kosong yg 
 // akan di tempatkan data
    $query_parameter_nya = array(
        ':user' => $_POST['username_nya'],
        ':judul' => $_POST['judul_komentar'],
  ':komentar' => $_POST['isi_komentar']
    );
  
 //query_nya di eksekusi
    try {
        $statement_nya   = $db->prepare($query);
        $result = $statement_nya->execute($query_parameter_nya);
    }
    catch (PDOException $ex) {
        // boleh saja pakai metode. 
        die("Gagal menjalankan query: " . $ex->getMessage());
        
        //atau lebih ringan pakai sbb::
        $jawaban_dari_server["sukses"] = 0;
        $jawaban_dari_server["pesan"] = "ada kesalahan database. Tak bisa kirim komentarnya!";
        die(json_encode($jawaban_dari_server));
    }

    $jawaban_dari_server["sukses"] = 1;
    $jawaban_dari_server["pesan"] = "Komentarnya berhasil di kirim!";
    echo json_encode($jawaban_dari_server);
   
} else {
?>
  <h1>Isi Komentar</h1> 
  <form action="tambah_komentar.php" method="post"> 
      Nama User:<br /> 
      <input type="text" name="username_nya" placeholder="username" /> 
      <br /><br /> 
      Judul:<br /> 
      <input type="text" name="judul_komentar" placeholder="kirim_judul" /> 
      <br /><br />
   Komentar:<br /> 
      <input type="text" name="isi_komentar" placeholder="kirim_komentar" /> 
      <br /><br />
      <input type="submit" value="Tambah Komentar" /> 
  </form> 
 <?php
}

?> 

Kode untuk halaman Tambah Komentar sudah selesai.... berikutnya akan saya bangun sebuah class JSON(JavaScript Object Notation) yang akan di siarkan ke semua halaman agar aplikasinya menjadi responsive.
Semua kode yang saya telah tulis telah ada elemen JSON_nya..... silahkan baca tentang class JSON_nya dengan klik disini

Android PHP dan MYSQL database bagian 2

Sebelum membaca halaman ini, bacalah dahulu 'Android PHP dan MYSQL database bagian 1' di sana sudah di cantumkan kode untuk halaman login baik dari sisi server maupun dari sisi klien. Disana juga telah di jelaskan bahwa halaman login,.. juga akan membuka halaman komentar agar user yang sudah register bisa membaca komentar maka berikut adalah isi dari class Baca Komentar yang saya berinama ClassBacaKomentar.java
 package com.vik_sintus.projects.koneksiandroidmysql;
/*
 * ©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.
 * 
 * 
 */
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class ClassBacaKomentar extends ListActivity {

 // Progress bar_nya
 private ProgressDialog progressBarNya;

 // lokasi script utk baca_komentar.php

  // biasanya localhost :
  // tapi untuk testing, lebih baik pakai alamat IP
  // kalau tak tahu IP-nya di windows silahkan buka
  // command prompt lalu ketik ipconfig
  // lihat IPv4 Address
  // kalau di mac ketik ifconfig dan cari ip dengan en0 atau en1
  // private static final String LINK_SEMUA_KOMENTAR =
  // "http://xxx.xxx.x.x.xxx/folderNya/baca_komentar.php";

  // coba di Emulator:jangan lupa ganti dengan IP sendiri yah
 private static final String LINK_SEMUA_KOMENTAR = "http://192.168.1.102/mysql_android/baca_komentar.php";

 // kalau di server benaran:
  // private static final String LINK_SEMUA_KOMENTAR =
  // "http://www.namaWeb.com/folderNya/baca_komentar.php";

  // berikut adalah identitas dari JSON element yang
  // merespond dari halaman PHP (baca_komentar.php)
 private static final String TAG_SUKSES = "koneksi_sukses";
 private static final String TAG_JUDUL_KOMENTAR = "judul_komentar";
 private static final String TAG_SEMUA_KOMENTAR = "semua_komentar";
 private static final String TAG_POST_ID = "komentar_id";
 private static final String TAG_USERNAME = "username_nya";
 private static final String TAG_ISI_KOMENTAR = "isi_komentar";

 // sebuah array utk semua komentar
 private JSONArray semuaKomentar = null;
 // atur semua komentar dalam bentuk berbaris(daftar).
 private ArrayList<HashMap<String, String>> susunanKomentar;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // tampilan yg di pakai disini adalah baca_komentar.xml dan
  // bukan single_post.xml yah
  setContentView(R.layout.baca_komentar);
 }

 @Override
 protected void onResume() {
  super.onResume();
  // pasang(loading) semua komentar melalui AsyncTask
  new TampilSemuaKomentar().execute();
 }
    //pada class BacaKomentar ini juga akan ada intent baru utk
 //membuka halaman(activity) baru yaitu activity utk classTambahKomentar
 //maka di buat metode 'tambahKomentar' berikut ini yg akan di
 //panggil dari xml dengan metode onclick... lihat di 'baca_komentar.xml'
 public void tambahKomentar(View v) {
  Intent intentNya = new Intent(ClassBacaKomentar.this, ClassTambahKomentar.class);
  startActivity(intentNya);
 }

 /**
  * ambil posting terbaru dari server dengan
  * meng-update JSON-nya.
  */
 public void jsonDataNyaDiUpdate() {
        //buatkan arraylist utk menampung semua JSON data dan
  //kita akan menggunakan beberapa 'key value pairs' ber
  //dasarkan nama JSON element yang kita tanam di 
  //halaman php yg identitasnya telah di sebutkan 
  //pada beberapa TAG di atas
 
  susunanKomentar = new ArrayList<HashMap<String, String>>();

  // hidupkan JSONParser-nya
  ClassJSONParser jsonParserNya = new ClassJSONParser();
  // masukan url untuk komentar-nya, sehingga 
  // JSONObject memuntahkan isi komentar yang ada
  JSONObject jsonObjectNya = jsonParserNya.ambilJsonDariUrl(LINK_SEMUA_KOMENTAR);

  // ketika parsing sesuatu lewat JSON , ada baiknya
  // di pasang 'try catch exceptions' utk menanggkap hal2 yang
  // tak terduga(error) :
  try {

   semuaKomentar = jsonObjectNya.getJSONArray(TAG_SEMUA_KOMENTAR);

   // terus looping ke semua komentar yang telah ada sesuai
   // dengan apa yang di dapatkan oleh JSONObject
   for (int i = 0; i < semuaKomentar.length(); i++) {
    JSONObject komentarNya = semuaKomentar.getJSONObject(i);

    // ambil isi dari masing2 tag
    String username_nya = komentarNya.getString(TAG_USERNAME);
    String judul_komentar = komentarNya.getString(TAG_JUDUL_KOMENTAR);
    String isi_komentar = komentarNya.getString(TAG_ISI_KOMENTAR);
    

    // buatkan HashMap baru utk mencocokan TAG dan parameter-nya
    HashMap<String, String> map = new HashMap<String, String>();
                
    map.put(TAG_USERNAME, username_nya);
    map.put(TAG_JUDUL_KOMENTAR, judul_komentar);
    map.put(TAG_ISI_KOMENTAR, isi_komentar);
    
    susunanKomentar.add(map);

   }

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

 /**
  * masukan data yg sudah di parsing
  * ke dalam listview.
  */
 private void updateListViewNya() {
  //utk listActivity kita perlu memasang List Adapter dengan 
  //mendeklarasikan-nya
  //SimpleAdapter ini akan memakai HashMap arrayList yang
  //telah di update.
  //gunakan komentar_tunggal.xml sebagai template utk 
  //setiap item di dalam list dan perhatikan identitas GUI_nya
  //agar jangan salah mengikuti susunan-nya
  ListAdapter adapterNya = new SimpleAdapter(this, susunanKomentar,
    R.layout.komentar_tunggal, new String[] { TAG_USERNAME, TAG_JUDUL_KOMENTAR, TAG_ISI_KOMENTAR
       }, new int[] { R.id.usernameNya, R.id.judul, R.id.komentar
       });

  // kalau semuanya sudah benar maka
  //pasanglah ListAdapter-nya
  setListAdapter(adapterNya);
  //ketika klik pada satu komentar sebenarnya 
  //bisa melakukan sesuatu, misalnya pergi ke activity 
  //lain atau ke link tapi disini saya pilih utk 
  //tidak melakukan apa2
  ListView lv = getListView(); 
  lv.setOnItemClickListener(new OnItemClickListener() {

   @Override
   public void onItemClick(AdapterView<?> parent, View view,
     int posisiNya, long idNya) {

   }
  });
 }

 public class TampilSemuaKomentar extends AsyncTask<Void, Void, Boolean> {

  @Override
  protected void onPreExecute() {
   super.onPreExecute();
   progressBarNya = new ProgressDialog(ClassBacaKomentar.this);
   progressBarNya.setMessage("Tunggu yah, masih loading...");
   progressBarNya.setIndeterminate(false);
   progressBarNya.setCancelable(true);
   progressBarNya.show();
  }

  @Override
  protected Boolean doInBackground(Void... arg0) {
   jsonDataNyaDiUpdate();
   return null;

  }

  @Override
  protected void onPostExecute(Boolean tampilkanHasilNya) {
   super.onPostExecute(tampilkanHasilNya);
//setelah tampil hasilnya matikan progress barnya 
//dengan metode dismiss();
   progressBarNya.dismiss();
   updateListViewNya();
  }
 }
}




Perhatikan kode di atas dan lihat di baris yang nampak sbb:
 Intent intentNya = new Intent(ClassBacaKomentar.this, ClassTambahKomentar.class);
  startActivity(intentNya);
IntentNya apa? atau tujuan bentuknya halaman ini untuk apa?...tentunya untuk buka classBacaKomentar itu sendiri dan juga buka ClassTambahKomentar. Tetapi... sebelum saya tulis ClassTambahKomentar ada baiknya saya tulis dahulu tampang design dari ClassBacaKomentar tersebut di atas dengan nama baca_komentar.xml yang di dalam kode java nampak sebagai berikut
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // tampilan yg di pakai disini adalah baca_komentar.xml
  setContentView(R.layout.baca_komentar);
 }
Berikut adalah isi dari baca_komentar.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff" >

    <LinearLayout
        android:id="@+id/baret_hijau_atas"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/baret_hijau"
        android:orientation="horizontal" >

        <TextView
            style="@style/huruf_hitam"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="@string/baca_komentar_judul"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/baret_hijau_bawah"
        android:layout_below="@+id/baret_hijau_atas"
        android:background="#fff"
        android:divider="@android:color/transparent"
        android:scrollbars="none" />

    <LinearLayout
        android:id="@+id/baret_hijau_bawah"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:background="@drawable/baret_hijau"
        android:orientation="horizontal"
        android:weightSum="2" >

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical" >
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical" >

            <Button
                android:id="@+id/tombol_kirim"
                style="@style/huruf_putih"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="right"
                android:background="@drawable/tombol_kirim"
                android:onClick="tambahKomentar"
                android:text="@string/tombol_kirim" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>
Berikut adalah tampilan halaman baca komentar dan saya sudah masukan dua orang anggota untuk di gunakan sebagai contoh ... tuh telah registrasi bernama Tirok Ndibol dan Kristina Molas. Keduanya telah meninggalkan pesan seperti terlihat pada gambar Baca Komentar berikut:
Baca Komentar

Silahkan mempelajari android UI design dengan membandingkan kode xml dan gambar di atas. Mungkin ada beberapa object yang redundant, tapi saya malas membersihkan-nya. Tapi yang jelas redundancy tersebut tidak akan mengurangi proses kerja aplikasi
Kedua kode yang telah saya tulis di atas adalah untuk sisi klien yaitu di buat di project android... berikut adalah kode PHPnya untuk sisi server yang saya beri nama baca_komentar.php. Antara sisi server dan sisi klien, keduanya harus saling bercermin yah
<?php
//©Vik Sintus Projects
//di sini juga perlu konfigurasi_nya.php agar
//bisa konek ke server
require("/konfigurasi_nya.php");

//agar bisa lihat semua komentar maka
//Select * ( pilih semua) FROM tempat_komentar
$query = "Select * FROM tempat_komentar";

//query-nya di eksekusi
try {
    $apa_yang_di_query  =  array();
    $statement_nya   = $db->prepare($query);
    $result = $statement_nya->execute($apa_yang_di_query);
 
}
catch (PDOException $ex) {
    $jawab["sukses"] = 0;
    $jawab["pesan"] = "Database_nya Salah!";
    die(json_encode($jawab));
}
// ambil semua baris komentar yang di ketemukan dan
// masukan semuanya kedalam sebuah array() menggunakan fetchAll() 
$rows = $statement_nya->fetchAll();


if ($rows) {
    $jawab["sukses"] = 1;
    $jawab["pesan"] = "Telah ada komentar!";
    $jawab["semua_komentar"]   = array();
    
    foreach ($rows as $baris) {
        $komentar             = array();
  $komentar["komentar_id"]  = $baris["komentar_id"];
        $komentar["username_nya"] = $baris["username_nya"];
        $komentar["judul_komentar"]    = $baris["judul_komentar"];
        $komentar["isi_komentar"]  = $baris["isi_komentar"];
        
        
        //setelah di masukan ke dalam array maka
  //jawaban JSON harus di update
        array_push($jawab["semua_komentar"], $komentar);
    }
    
    // tunjukan jawaban JSON ke layar
    echo json_encode($jawab);
    
    
} else {
    $jawab["sukses"] = 0;
    $jawab["pesan"] = "Belum ada komentar!";
    die(json_encode($jawab));
}

?>


Kode di atas cukup self-explanatory-lah, silahkan di telusuri... Halaman baca_komentar.php yang nota bene adalah berada di sisi server adalah hanya untuk menyusun data output dalam format JSON, sehingga isinya gampang di parsing dan di olah oleh class JSON yang berada di sisi klien. Saya telah masukan beberapa anggota di dalam aplikasi forum ini yang kita akan pakai sebagai contoh, dua di antaranya yaitu si Tirok Ndibol dan si Kristina Molas telah isi komentar di forum seperti terlihat pada gambar Baca Komentar di atas. Berikut tampilan data mentah dari JSON (atau sering di sebut JSON format) yang di hasilkan dari kode di halaman baca_komentar.php di atas. Perhatikan komentar dari Tirok Ndibol dan Kristina Molas.... sangat tak rapi untuk di lihat manusia tapi aplikasi akan sangat senang untuk konsumsi data seperti itu
{"sukses":1,"pesan":"Telah ada komentar!",<br />"semua_komentar":[{"komentar_id":"1","username_nya":"tirokNdibol",<br />"judul_komentar":"cobay di e... kesa",<br />"isi_komentar":"halo...halo test"},<br />{"komentar_id":"2","username_nya":"kristinaMolas","judul_komentar":"cobab di tah",<br />"isi_komentar":"oe... lawa, aku hi Kristina e... nia ngaok lawa"}]}
Kalau mau paham benar akan pekerjaan JSON maka perhatikan secara saksama antara lain kode php, hasil olahan JSON dan hasil olahan manusia. Hasil olahan manusia tentunya nampak lebih cantik seperti terlihat pada gambar 'Baca Komentar' ... semua itu kita patut berterima kasih kepada ClassBacaKomentar.java dan pasangan cantiknya si baca_komentar.xml dan juga sebuah ClassJSONParser.java yang akan segera saya tulis.
Halaman baca komentar sudah selesai, Tapi di ClassUtkLogIn.java juga ada tombol Registrasi yang mengarahkan ke Halaman Registarasi ... maka untuk itu mari kita buatkan class untuk halaman Registrasi yang saya beri nama ClassRegistrasi.java
Berikut adalah isi dari ClassRegistrasi.java
package com.vik_sintus.projects.koneksiandroidmysql;
/*
 * ©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.
 * 
 * 
 */
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class ClassRegistrasi extends Activity implements OnClickListener {
 private EditText kotakUser, kotakPassword;
 private Button  tombolRegistrasi;
 
  // utk progress bar
    private ProgressDialog progressBarNya;
 
    // panggil ClassJsonParser ke sisni
    ClassJSONParser classJSONParserNya = new ClassJSONParser();
    
    //lokasi registrasi.php
    
    //kalau localhost atau komputer rumah lebih baik pakai
    // alamat IP
    //kalau di windows, buka command prompt lalu ketik ipconfig
    //lihat IPv4 Address
    //atau kalau di aple mac terminal silahkan ketik ifconfig dan 
    //lihat IPnya di bawah en0 or en1
    
    //sehingga kalau coba di Emulator akan terlihat mirip sbb:
    private static final String LINK_UTK_REGISTRASI = "http://192.168.1.102/mysql_android/registrasi.php";
    
    //tapi kalau di server bayaran(remote) maka akan terlihat sbb:
    //private static final String LOGIN_URL = "http://www.namaWebMu.com/namafolderNya/registrasi.php";
    
    //id's
    private static final String TAG_BERHASIL = "sukses";
    private static final String TAG_PESAN = "pesan";
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.tampilan_registrasi);
  
  kotakUser = (EditText)findViewById(R.id.username);
  kotakPassword = (EditText)findViewById(R.id.password);
  

  tombolRegistrasi = (Button)findViewById(R.id.register);
  tombolRegistrasi.setOnClickListener(this);
  
 }

 @Override
 public void onClick(View v) {
  // klik tombol register untuk apa?
    new MendaftarPenggunaBaru().execute();
  
 }
 
 class MendaftarPenggunaBaru extends AsyncTask<String, String, String> {

   /**
         * saat setelah tekan tombol registrasi tunjukanlah progressBar kepada 
         * *pengguna agar ia tahu aplikasi sedang apa
         * */
  boolean failure = false;
  
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressBarNya = new ProgressDialog(ClassRegistrasi.this);
            progressBarNya.setMessage("Menyimpan User...");
            progressBarNya.setIndeterminate(false);
            progressBarNya.setCancelable(true);
            progressBarNya.show();
        }
  
  @Override
  protected String doInBackground(String... args) {
    // priksa TAG_BERHASIL
            int berhasil;
            String usernameNya = kotakUser.getText().toString();
            String passwordNya = kotakPassword.getText().toString();
            try {
                // Cocokan parameternya yah 'username ke username dan
             // password ke password
                List<NameValuePair> parameterNya = new ArrayList<NameValuePair>();
                parameterNya.add(new BasicNameValuePair("username_nya", usernameNya));
                parameterNya.add(new BasicNameValuePair("password_nya", passwordNya));
 
                Log.d("Request ke server!", "dimulai");
                
                // kirim data dari user ke script di server 
                JSONObject jsonObjectNya = classJSONParserNya.membuatHttpRequest(
                       LINK_UTK_REGISTRASI, "POST", parameterNya);
 
                // json response-nya
                Log.d("Coba Login", jsonObjectNya.toString());
 
                // json berhasil
                berhasil = jsonObjectNya.getInt(TAG_BERHASIL);
                if (berhasil == 1) {
                 Log.d("Proses Registrasi berhasil!", jsonObjectNya.toString());               
                 finish();
                 return jsonObjectNya.getString(TAG_PESAN);
                }else{
                 Log.d("Registrasi_nya Gagal!", jsonObjectNya.getString(TAG_PESAN));
                 return jsonObjectNya.getString(TAG_PESAN);
                 
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
 
            return null;
   
  }
  /**
         * kalau sudah selesai tugas background_nya matikan 
         * progressbar_nya
         * **/
        protected void onPostExecute(String url_registrasi_nya) {
            // matikan progressBar-nya setelah selesai di gunakan
            progressBarNya.dismiss();
            if (url_registrasi_nya != null){
             Toast.makeText(ClassRegistrasi.this, url_registrasi_nya, Toast.LENGTH_LONG).show();
            }
 
        }
  
 }
   


}



Dan berikut adalah UI_nya yang saya beri nama tampilan_registrasi.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true"
        android:src="@drawable/lodokn_one" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/password"
        android:layout_centerVertical="true"
        android:text="NamaUser" />

    <EditText
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:ems="10" />

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/username"
        android:layout_below="@+id/username"
        android:text="PasswordNya" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:gravity="center"
        android:text="Android PHP Mysql"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textStyle="bold" />

    <EditText
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/TextView01"
        android:layout_centerHorizontal="true"
        android:ems="10"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/password"
        android:layout_below="@+id/password"
        android:text="Register" />

</RelativeLayout>

Berikut adalah tampang dari halaman Registrasi setelah tekan tombol Registrasi
Registrasi

Dan berikut adalah kode untuk sisi server dengan nama registrasi.php
<?php

/* ©Vik Sintus Projects
agar bisa register... konek dulu yah
untuk konek kita perlu sertakan halaman konfigurasi koneksi
*/
require("/konfigurasi_nya.php");

//kalau data tak kosong... lanjut bro..
if (!empty($_POST)) {
    //tapi kalau datanya kosong ketika tekan tombol 'Register' maka
 //halaman harus berhenti eksekusi dengan menggunakan metode die(); dan
 //berikan peringatan kepada pengguna agar 
 //di isi username dan password_nya
    //Menggunakan metode die(); adalah tidak cukup, maka kita perlu
 //meninggalkan pesan kepada pengguna..apa yang terjadi? berikan jawaban_nya
 //Untuk mempertebal pertahanan keamanan nanti kita juga akan melakukan
 //validasi dari front_end di ClassRegistrasi.java
    if (empty($_POST['username_nya']) || empty($_POST['password_nya'])) {
        
        //berikut adalah data yang di buat untuk di
  //pakai oleh JSON untuk memberikan penjelasan kepada 
  //pengguna apa yang sedang terjadi agar dia tidak melongo
        $jawaban_nya["sukses"] = 0;
        $jawaban_nya["pesan"] = "Mohon di isi NamaUser dan PasswordNya.";
        
  //matikan halaman registrasi dan kirim pesan balik ke 
  //aplikasi android melalui JSON
        die(json_encode($jawaban_nya));
    }
    //priksa database apakah sudah ada username dengan nama yang sama
 //itu sebabnya saya pakai :username hanya sebagai variabel kosong
 //yang akan berubah saat eksekusi query-nya
    //cara ini cukup bagus untuk menangkal sql injection dari orang jahil
    $query        = " SELECT 1 FROM anggota WHERE username_nya = :username";
    //di update untuk melihat siapa pengguna sebenarnya
    $yang_di_query = array(
        ':username' => $_POST['username_nya']
    );
    
    //jalankan query-nya
    try {
        // bikin statement apa yang mau di query ke database. 
        $statement_nya   = $db->prepare($query);
        $result = $statement_nya->execute($yang_di_query);
    }
    catch (PDOException $ex) {
        
        //jadi developer yg baik yah, jelaskan kepada user apa yg terjadi:
        $jawaban_nya["sukses"] = 0;
        $jawaban_nya["pesan"] = "Databasenya salah. Di coba lagi yah!";
        die(json_encode($jawaban_nya));
    }
    
 // ambil semua data yang telah tercatat di database sehingga 
 // aplikasi bisa lihat apakah nama tsb sudah ada atau belum dan
 // kalau nama sudah ada maka berhenti eksekusi dengan membunuh 
 // aplikasinya dengan metode die();
    $row = $statement_nya->fetch();
    if ($row) {
        
        $jawaban_nya["sukses"] = 1;
        $jawaban_nya["pesan"] = "Maaf, nama tersebut suda ada di pakai";
        die(json_encode($jawaban_nya));
    }
    
 // tapi kalau nama usernya ok maka aplikasi masih terus hidup dan
 // di lanjutkan dengan masukan data yang di input oleh user
 // maka perlu membuat query baru pakai cara berikut yah biar
 // cukup susah buat orang nakal untuk buat sql injection
 
    $query = "INSERT INTO anggota ( username_nya, password_nya ) VALUES ( :username_kosong, :password_kosong ) ";
    
 // berikut adalah blanko kosong harus di update dengan data yang sebenarnya
    
    $yang_di_query = array(
        ':username_kosong' => $_POST['username_nya'],
        ':password_kosong' => $_POST['password_nya']
    );
    // jalankan query akhir untuk mendaftar user baru
    try {
        $statement_nya   = $db->prepare($query);
        $result = $statement_nya->execute($yang_di_query);
    }
    catch (PDOException $ex) {
        
        $jawaban_nya["sukses"] = 0;
        $jawaban_nya["pesan"] = "Username dan PassworNya tak benar. Coba lagi yah!";
        die(json_encode($jawaban_nya));
    }
    
    $jawaban_nya["sukses"] = 1;
    $jawaban_nya["pesan"] = "Registrasi Berhasil!";
    echo json_encode($jawaban_nya);
    
    //mau bawa kemana usernya? terserah anda sebagai developer.
    //header("Location: login_nya.php"); 
    //die("Redirecting ke halaman login_nya.php");
 //tapi disini saya hanya bilang bahwa registrasinya berhasil
 //dan kalau mau baca komentar silahkan login lah kawan
    
    
} else {
?>
 <h1>Register</h1> 
 <form action="registrasi.php" method="post"> 
     UsernameNya:<br /> 
     <input type="text" name="username" value="" /> 
     <br /><br /> 
     PasswordNya:<br /> 
     <input type="password" name="password" value="" /> 
     <br /><br /> 
     <input type="submit" value="Register User Baru" /> 
 </form>
 <?php
}

?>

Halaman in sudah terlalu panjang... oleh karena itu saya tulis halaman Tambah Komentar pada halaman baru .. silahkan kesan dengan klik disini yah

Android PHP dan MYSQL Database bagian 1

Bagaimana aplikasi Android bisa berkomunikasi dengan Mysql database?

Pertanyaan di atas banyak bergentayangan di internet. Jawaban_nya bervariasi sesuai dengan pengalaman orang yang menjawabnya. Di sini saya hanya ingin ikut meramaikan dan ingin melanjutkan percakapan tentang hal tesebut karena menurut saya hal itu adalah sangat penting sebagai basis untuk berkiprah dalam dunia develop aplikasi android.

Banyak developer yang ingin mejawab pertanyaan tsb, tapi jawaban-nya tak ada yang singkat tapi semuanya  panjang dan berliku karena memang develop aplikasi memakan waktu panjang dan dengan jalan yang penuh liku. Itulah indahnya kalau mau jadi developer, selalu ada tantangan setiap saat.
Saya akan mencoba menjelaskan-nya sebisa saya dan sesingkat mungkin. Semoga ada yang lain akan menambahkan-nya.
Untuk menjawab pertanyaan di atas, saya harus membuat sebuah kasus atau skenario untuk sebuah aplikasi yang sangat singkat, sehingga coding-nya nanti juga akan lebih singkat untuk bisa di telusuri.... developing tak ada yang singkat, kawan...

Kasus yang saya pakai sebagai contoh adalah sebuah forum kecil yang sifatnya sbb:
  1. Registrasi dulu sebelum bisa jadi anggota 
  2. Aplikasi akan menolak meregistrasi dengan nama yang sama
  3. Hanya anggota, yang bisa membaca dan bisa menulis komentar
  4. Setelah jadi anggota harus login dulu sebelum bisa membaca komentar
  5. Pasang kotak utk isi username dan password di halaman login
  6. Di halaman login juga ada tombol 'Registrasi' utk yg belum registrasi
  7. Beri peringatan jikalau login dengan username dan password yang salah
  8. Setelah sukses login bawalah anggota ke halaman komentar
  9. Bubuhkan tombol 'Isi Komentar' untuk mengisi komentar
  10. Bubuhkan tempat untuk tulis 'Judul Komentar' dan 'Isi Komentar
  11. Bubuhkan tombol 'Kirim Komentar' untuk bisa kirim komentar 
  12. Beri peringatan jika 'Judul Komentar' dan 'Isi Komentar'  kosong
Dari daftar tersebut di atas kita bisa mengambil kesimpulan, halaman apa saja yang di butuhkan untuk aplikasi ini.  Di android, sebuah halaman biasanya di representasikan dengan sebuah 'activity' yang cara kerjanya di renda oleh sebuah 'class java'.
Di lihat dari sifat aplikasi tersebut di atas maka kita akan membutuhkan beberapa halaman atau 'activity atau class, antara lain:

  • Halaman Login
  • Halaman Registrasi
  • Halaman Baca Komentar
  • Halaman Tambah  Komentar
  • Halaman JSON 
Halaman JSON
Kita tambahkan halaman JSON (Javascript Object Notation)
JSON adalah language independent artinya ia di mengerti oleh hampir semua bahasa programan sehingga ia sangat cocok menjadi jembatan antara  bahasa program yang berbeda. JSON-lah yang akan bertanggung jawab agar aplikasi-nya dinamik dan responsive, misalnya memberi peringatan kepada pengguna jikalau mereka masukan password dan username yang salah dll
Silahkan baca tentang json di http://en.wikipedia.org/wiki/JSON

Halaman Login
Halaman login akan ada tempat untuk isi username, password. dan dua buah tombol satunya tombol Login dan yang lain-nya adalah tombol Registrasi.
Ketika tekan tombol login tanpa password maka aplikasi memberikan peringatan kepada pengguna agar mengisi password dan usernamenya. Demikian juga ketika tekan tombol Registrasi tanpa username dan password.

Halaman Baca Komentar
User yang login dengan benar langsung di antar ke halaman Baca Komentar dan pada bagian bawah halaman komentar ada tombol Tambah Komentar agar pengguna bisa ikut berkomentar. Aplikasi akan menolak untuk submit komentar yang kosong dengan memberikan warning.

Halaman-halaman tersebut (terkecuali JSON) akan di bangun di dua sisi. Di sisi klien akan di bangun menggunakan java(android) dan di sisi server akan di bangun menggunakan PHP. (alasan-nya karena PHP teman baik dengan MYSQL).

Apa saja yang di perlukan untuk membangun aplikasi seperti ini
  • Server
  • Android dan Eclipse
  • PHP dan Mysql
Server
Jikalau sudah ada server bayaran, silahkan atur Mysql database-nya disana. Tapi kalau tak bisa bayar server, saya rekomendasikan untuk download server yang free dari internet untuk di pasang di komputer sendiri. Di internet bergentayangan server seperti WAMP ada juga XAMPP. Silahkan pilih menurut selera masing2. Walaupun sudah ada server bayaran, namun untuk develop ada baiknya install server di komputer sendiri agar semua server side code bisa di coba tanpa harus selalu konek ke internet.
Saya akan membicarakan tentang server pada kesempatan lain... semoga

Android dan Eclipse
Download Android dan Eclipse .. free loh...

PHP dan Mysql
Hampir semua server bisa PHP dan Mysql.
Saya berasumsi bahwa anda membaca tutorial ini karena ingin melihat cara kerja aplikasi android, sehingga saya tidak meng-elaborasi lebih jauh tentang PHP, MYSQL dan yang lain-nya. Tapi kalau ingin membaca PHP dan MYSQL silahkan kesana dahulu dengan tekan link yang sudah saya sediakan di atas.

Kembali ke daftar sifat-sifat aplikasi di atas...... Halaman pertama yang harus di bangun tentunya adalah halaman 'Login' ...Kode halaman Login ini akan di representasikan dengan dua buah halaman yaitu sebuah halaman di sisi klien dan sebuah halaman di sisi server. Di sisi server saya beri nama login_nya.php  di bangun dengan php, dan di sisi klien dengan nama ClassUtkLogIn.java  di bangun pakai java. Semua server side script dalam hal ini adalah halaman PHP harus di simpan di dalam sebuah folder dengan nama sesuka hati, tapi di dalam contoh disini saya menamakan folder-nya mysql_android.
Di server XAMPP folder mysql_android tersebut di masukan lagi di dalam folder htdocs, Sedangkan di server lain mungkin di simpan di dalam folder bernama www atau public_html dan lain-lain. Mohon baca petunjuk server-nya

Tapi... sebelum itu buatlah terlebih dahulu databasenya di server dengan nama tampung_data saya sengaja menamakan_nya demikian karena semua data akan di tampung disana, baik data pengguna maupun data komentarnya.
Di dalam database tampung_data tersebut, masukan dua buah table, satunya dengan nama 'tempat_komentar' untuk menampung komentar dengan isi sbb:

CREATE TABLE tempat_komentar
(
komentar_id int(11) UNIQUE AUTO_INCREMENT,
username_nya varchar(64),
judul_komentar varchar(120),
isi_komentar varchar(255)
)

dan table 'anggota' untuk menampung keterangan tentang anggota sbb:

CREATE TABLE anggota
(
anggota_id int(11) UNIQUE AUTO_INCREMENT,
username_nya varchar(64) UNIQUE,
password_nya varchar(120),

)

Berikut adalah isi dari login_nya.php yang harus di simpan di server sebagai server side code


 <?php
//©Vik Sintus Projects
//pasang halaman konfigurasi_nya.php agar
//bisa konek
require("/konfigurasi_nya.php");

if (!empty($_POST)) {

if (empty($_POST['username_nya']) || empty($_POST['password_nya'])) {
        
        
  // kalau 'username' dan 'password' kosong
  // JSON menjawab agar pengguna tahu apa yg terjadi

        $jawaban_nya["berhasil"] = 0;
        $jawaban_nya["tampilkan_pesan"] = "Masukan NamaUser dan PasswordNya!.";
        
  // metode die() akan matikan halaman dan tidak 
  // mengeksekusi kode2 selanjutnya, dan juga akan
  // memperlihatkan parameter2, yaitu JSON data yang
  // akan di parsing oleh android
        die(json_encode($jawaban_nya));
    }
    // ambil info dari user berdasarkan username.
    $query = " 
            SELECT 
                anggota_id, 
                username_nya, 
                password_nya
            FROM anggota 
            WHERE 
                username_nya = :username 
        ";
    
    $parameter_nya = array(
        ':username' => $_POST['username_nya']
    );
    
    try {
        $statement_nya   = $db->prepare($query);
        $result = $statement_nya->execute($parameter_nya);
    }
    catch (PDOException $ex) {
        // utk percobaan, bisa saja menggunaka metode die(); 
        //atau pakai cara berikut untuk menampilkan data dari JSON
        $jawaban_nya["berhasil"] = 0;
        $jawaban_nya["tampilkan_pesan"] = "DatabaseNya salah. Di coba lagi yah!";
        die(json_encode($jawaban_nya));
        
    }
    
    //bikin satu variable utk priksa kebenaran login dan
    //di inisialisasikan dengan false.
    $validasi_identitas = false;
    
 //tarik semua parameter pada 'query' di atas dengan
 //metode fetch()
    $row = $statement_nya->fetch();
    if ($row) {
  //kalau passwordnya di encrypt, maka di lakukan di sini tapi
  //saya bukan ahli encrypt, silahkan baca2 tentang encrypt,
  //disini saya hanya berkepentingan utk 
  //menjalankan script ini sejajar dengan java (android) sehingga
  //saya hanya membandingkan password yg di input dan
  //password yg ada di database
        if ($_POST['password_nya'] === $row['password_nya']) {
            $login_nya_ok = true;
        }
    }
    
    // kalau login-nya berhasil, orangnya di antar ke halaman users 
    // kalau tidak, tampilkan pesan gagal dan tunjukan form lagi 
    if ($login_nya_ok) {
        $jawaban_nya["berhasil"] = 1;
        $jawaban_nya["tampilkan_pesan"] = "LoginNya Berhasil!";
        die(json_encode($jawaban_nya));
    } else {
        $jawaban_nya["berhasil"] = 0;
        $jawaban_nya["tampilkan_pesan"] = "LoginNya Gagal!";
        die(json_encode($jawaban_nya));
    }
} 
else {
 ?>
<h1>Login</h1> 
  <form action="login_nya.php" method="post"> 
      Username:<br /> 
      <input type="text" name="username" placeholder="username" /> 
      <br /><br /> 
      Password:<br /> 
      <input type="password" name="password" placeholder="password" value="" /> 
      <br /><br /> 
      <input type="submit" value="Login" /> 
  </form> 
  <a href="registrasi.php">Register</a>
 <?php
}

?> 
Saya sisipkan penjelasan dalam kode di atas, silahkan telusuri... mereka yang jago PHP pasti tidak asing dengan kode di atas
Di baris pertama ia minta 'require("/konfigurasi_nya.php");' maka berikut adalah isi dari konfigurasi_nya.php
<?php 
    // ©Vik Sintus Projects
    // 4 variable berikut harus cocok dengan yang ada di database
    $username = "root"; 
    $password = ""; 
    $host = "localhost"; 
    $dbname = "tampung_komentar"; 

 // pakai utf8 agar databasenya bisa muat banyak jenis karakter seperti
 // huruf dan agka 
 // silahkan baca2 tentang utf8 di 
 // http://en.wikipedia.org/wiki/UTF-8 
    $pakai_utf8 = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); 
     
 // bagi mereka yang pintar PHP tentunya tak asing dengan try/catch
 // Metode tersebut di pakai utk menangkap kesalahan pada kode yg
 // bersifat object oriented,
 // pertama di eksekusi dalam 'try' dan kalau memukan kesalahan maka akan
 // berhenti eksekusi dan melompat ke 'catch' dengan sebuah pesan agar
 // pengguna tak garuk2 kepala 
 // Silahkan baca2 tentang exceptions di  
 // http://us2.php.net/manual/en/language.exceptions.php 
    try 
    { 
  // statement dalam wilayah 'try' ini membukan koneksi ke datbase menggunakan
  // PDO library 
  // PDO di design utk menyediakan flexible interface antara PHP dengan 
  // banyak jenis database servers. 
  // silahkan baca2 tentang PDO di 
  // http://us2.php.net/manual/en/class.pdo.php 
        $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $pakai_utf8); 
    } 
    catch(PDOException $eksepsinya) 
    { 
  // jika ada kesalahan saat buka koneksi ke database maka 
  // akan terperangkap disini dan berhenti eksekusi dan
  // menunjukan pesan (apanya yg salah)
  // Kalau utk produksi mungkin tak perlu output $eksepsinya->getMessage(). 
  // agar tak mudah di mainkan oleh orang nakal. 
         
        die("Koneksi ke database Gagal: " . $eksepsinya->getMessage()); 
    } 
     
 // berikut adalah konfigurasi PDO mengeluarkan exception ketika
 // menemukan kesalahan dalam kode, agar bisa di pakai utk 
 // try/catch  
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     
 // berikut adalah konfigurasi PDO utk melihat barisan data(rows) di
 // dalam database menggunakan 'associative array'
 // maksudnya array akan ada 'string indexes', dimana isi 
 // string me-representasikan nama kolom di database . 
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 
     
 // get_magic_quotes_gpc sudah wafat tapi jaga kemungkinan jikalau
 // ada manusia yg masih pakai PHP tua bangka (PHP 5.3 kebawah) maka
 // kode berikut adalah berguna untuk mengagaglkan magic quotes.  
 // baca tentang magic qoutes selengkapnya di: 
 // http://php.net/manual/en/security.magicquotes.php 
    if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) 
    { 
        function matikan_magic_quotes_nya(&$array) 
        { 
            foreach($array as &$value) 
            { 
                if(is_array($value)) 
                { 
                    matikan_magic_quotes_nya($value); 
                } 
                else 
                { 
                    $value = stripslashes($value); 
                } 
            } 
        } 
     
        matikan_magic_quotes_nya($_POST); 
        matikan_magic_quotes_nya($_GET); 
        matikan_magic_quotes_nya($_COOKIE); 
    } 
     
 // berikut utk informasikan web browser bahwa isinya adalah di
 // encoded dengan UTF-8 sehingga content yang di return adalah
 // dalam bentuk utf8 juga
    header('Content-Type: text/html; charset=utf-8'); 
     
 // 'sessions' di gunakan utk menyimpan informasi tentang
 // pengunjung dari halaman ke halaman
 // Berbeda dengan 'cookie', sessions menyimpan infromasi di server
 // Namun demikian, dalam banyak kasus 'sessions' masih menggunakan
 // cookies tapi pengunjung juga harus menghidupkan cookie_nya  
 // silahkan baca2 tentang cookie di: 
 // http://us.php.net/manual/en/book.session.php 
    session_start(); 

?>

Halaman untuk login dari sisi server sudah selesai, berikut adalah halaman login dari sisi klien yaitu dari aplikasi android dengan nama ClassUtkLogIn.java


package com.vik_sintus.projects.koneksiandroidmysql;

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

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class ClassUtkLogIn extends Activity implements OnClickListener {

 private EditText isiNamaUser, isiPassword;
 private Button tombolLogin, tombolRegistrasi;

 // utk progress bar_nya
 private ProgressDialog progressBarNya;

 // pasang class JSON parser
 ClassJSONParser classJsonParser = new ClassJSONParser();

 // lokasi script utk login: bernama login_nya.php

   // biasanya localhost :
   // tapi untuk testing, lebih baik pakai alamat IP
   // kalau tak tahu IP-nya di windows silahkan buka
   // command prompt lalu ketik ipconfig
   // lihat IPv4 Address
   // kalau di mac ketik ifconfig dan cari ip dengan en0 atau en1
   // private static final String LINK_UNTUK_LOGIN =
   // "http://xxx.xxx.x.x.xxx/folderNya/login_nya.php";

 // kalau cobe di emulator:
 private static final String LINK_UNTUK_LOGIN = "http://192.168.1.102/mysql_android/login_nya.php";

     // coba di server jauh(remote), server bayaran:
  // private static final String LINK_UNTUK_LOGIN =
  // http://www.namaWeb.com/folderNya/login_nya.php;

 // identitas elemen yg perlu di 
 // jawab oleh JSON dari php script:
 private static final String TAG_SUKSES = "berhasil";
 private static final String TAG_PESAN = "tampilkan_pesan";

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

  // utk kotak input yg perlu di di isi pengguna
  isiNamaUser = (EditText) findViewById(R.id.username);
  isiPassword = (EditText) findViewById(R.id.password);

  // utk tombol
  tombolLogin = (Button) findViewById(R.id.login);
  tombolRegistrasi = (Button) findViewById(R.id.register);

  // agar tombol bisa di klik
  tombolLogin.setOnClickListener(this);
  tombolRegistrasi.setOnClickListener(this);

 }

 @Override
 public void onClick(View apaYgDiKlik) {
  
  switch (apaYgDiKlik.getId()) {
  case R.id.login:
   new MencobaLogin().execute();
   break;
  case R.id.register:
   Intent i = new Intent(this, ClassRegistrasi.class);
   startActivity(i);
   break;

  default:
   break;
  }
 }

 class MencobaLogin extends AsyncTask<String, String, String> {

  @Override
  protected void onPreExecute() {
   super.onPreExecute();
   progressBarNya = new ProgressDialog(ClassUtkLogIn.this);
   progressBarNya.setMessage("Mencoba login...");
   progressBarNya.setIndeterminate(false);
   progressBarNya.setCancelable(true);
   progressBarNya.show();
  }

  @Override
  protected String doInBackground(String... args) {
   
   // jika sukses
   int jikaSukses;
   String namaUser = isiNamaUser.getText().toString();
   String password = isiPassword.getText().toString();
   try {
    // menyusun parameternya (disini parameternya 
    // cuma 2 (username dan password))
    List<NameValuePair> namaDanPassword = new ArrayList<NameValuePair>();
    namaDanPassword.add(new BasicNameValuePair("username_nya", namaUser));
    namaDanPassword.add(new BasicNameValuePair("password_nya", password));

    Log.d("requestNya!", "dimulai");
    // utk melengkapi proses login, maka 
    // perlu membuatHttpRequst ke server
    JSONObject jsonObjectNya = classJsonParser.membuatHttpRequest(LINK_UNTUK_LOGIN, "POST",
      namaDanPassword);

    // priksa log jawaban dari JSON
    Log.d("Coba login", jsonObjectNya.toString());

    // apa kata JSON tentang TAG_SUKSES
    jikaSukses = jsonObjectNya.getInt(TAG_SUKSES);
    if (jikaSukses == 1) {
     Log.d("Login_nya Sukses!", jsonObjectNya.toString());
     // simpan data yg di masukan pengguna
     SharedPreferences sharedPrefNya = PreferenceManager
       .getDefaultSharedPreferences(ClassUtkLogIn.this);
     Editor editorNya = sharedPrefNya.edit();
     editorNya.putString("username_nya", namaUser);
     editorNya.commit();
     
     Intent intentNya = new Intent(ClassUtkLogIn.this, ClassBacaKomentar.class);
     finish();
     startActivity(intentNya);
     return jsonObjectNya.getString(TAG_PESAN);
    } else {
     Log.d("Login_nya Gagal!", jsonObjectNya.getString(TAG_PESAN));
     return jsonObjectNya.getString(TAG_PESAN);
    }
   } catch (JSONException e) {
    e.printStackTrace();
   }

   return null;

  }

  protected void onPostExecute(String urlFileNya) {
   // kalau sudah selesai di gunakan, matikanlah
   // progressbar_nya dengan metode dismiss();
   progressBarNya.dismiss();
   if (urlFileNya != null) {
    Toast.makeText(ClassUtkLogIn.this, urlFileNya, Toast.LENGTH_LONG).show();
   }

  }

 }

}


Dalam kode java di atas di minta tampang atau user interface(UI) dari halaman login di setContentView(R.layout.tampilan_login);
Berikut adalah isi dari tampilan_login.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <Button
        android:id="@+id/register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/login"
        android:layout_alignParentBottom="true"
        android:layout_alignRight="@+id/login"
        android:layout_marginBottom="25dp"
        android:text="Registrasi" />

    <Button
        android:id="@+id/login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/register"
        android:layout_alignLeft="@+id/password"
        android:layout_alignRight="@+id/password"
        android:text="Login" />

    <EditText
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/login"
        android:layout_centerHorizontal="true"
        android:ems="10"
        android:inputType="textPassword" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="17dp"
        android:gravity="center"
        android:text="Belajar Android PHP Mysql"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textStyle="bold" />

    <ImageView
        android:contentDescription="Lodokn One Cicingn Pe'ang"
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView2"
        android:layout_centerHorizontal="true"
        android:src="@drawable/lodok" />

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/password"
        android:layout_alignLeft="@+id/password"
        android:layout_marginLeft="22dp"
        android:text="PasswordNya" />

    <EditText
        android:inputType="text"
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/TextView01"
        android:layout_centerHorizontal="true"
        android:ems="10" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignRight="@+id/TextView01"
        android:layout_centerVertical="true"
        android:text="NamaUserNya" />

</RelativeLayout>


Berikut adalah tampilan halaman Login
Halaman Login
Ketika user berhasil login maka bawalah dia ke halaman komentar agar bisa baca komentar, jadi... tujuan pembuatan halaman Login ini bukan saja untuk Login tapi juga memiliki kemampuan untuk mengantar user ke halaman lain.  Didalam bahasa program java dan atau android hal itu di lakukan dengan class Intent. Perhatikan kode pada ClassUtkLogIn.java dan lihat
Intent intentNya = new Intent(ClassUtkLogIn.this, ClassBacaKomentar.class);
     finish();
     startActivity(intentNya);
  intentNya apa? Kode di antas menunjukan bahwa intentNya adalah untuk buka halaman Login dan juga buka halaman Baca Komentar ... Dengan demikian kini saatnya kita membuat class untuk baca komentar yang saya beri nama ClassBacaKomentar.java.
Tetapi... oleh karena halaman ini sudah terlalu panjang maka saya akan memulai ClassBacaKomentar pada post baru... silahkan baca di http://belajar-android-indonesia.blogspot.com.au/2013/10/android-php-dan-mysql-database-bagian-2.html