Android Programming
Candra Adiputra
cbnd
Daftar Isi
1 Kalkulator Konversi
1.1 Project . . . . . .
1.2 Layout . . . . . .
1.3 Activity . . . . .
1.4 Running . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
5
9
14
2 Image Viewer
2.1 Project . .
2.2 Layout . .
2.3 Activity .
2.4 Running .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
17
17
19
23
3 Audio Player
3.1 Project . .
3.2 Layout . .
3.3 Activity .
3.4 Running .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
25
26
26
28
40
4 Web Browser
42
4.1 Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.2 Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
i
Android Programming - candra.web.id
4.3
4.4
Activity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Running dan Set Permission . . . . . . . . . . . . . . . . . . . 47
5 Map Application
5.1 Google Map API Key . . .
5.2 Project . . . . . . . . . . . .
5.3 Layout . . . . . . . . . . . .
5.4 Uses Permission dan Library
5.5 Activity dan Running . . . .
5.6 Location API . . . . . . . .
6 Kontak Online
6.1 Overview . . . . . . . . . .
6.2 Menyiapkan Server . . . . .
6.2.1 Database . . . . . .
6.2.2 Web Service (PHP +
6.3 Aplikasi Client Android . .
6.3.1 Project . . . . . . .
6.3.2 Layout dan Menu . .
6.3.3 Program . . . . . . .
6.3.4 Permission . . . . .
6.4 Running . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . .
. . . . .
. . . . .
JSON)
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
ii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
50
51
52
53
53
54
56
.
.
.
.
.
.
.
.
.
.
63
64
64
64
64
66
66
66
70
96
99
MODUL
1
Kalkulator Konversi
Target
Gambar 1.1: Kalkulator Konversi
1
Android Programming - candra.web.id
1.1 Project
Untuk membuat aplikasi Kalkulator ini, kita perlu membuat Project terlebih
dahulu. Langkah langkah untuk membuat Project yakni:
• Melalui menu File > New > Android Project.
Atau dapat juga melalui Button New yang ada pada Toolbars. Jika
Tidak ada, maka pilih Project pada suv menu New, kemudain pada
dialog New Project, pilih Android > Android Project.
• Pada dialog new Android Project, beri nama Project dengan nama
”Kalkulator Konversi”. Kemudian pilih Next >.
Gambar 1.2: Android Project
• Pilih build target menjadi Android 2.3.3, Kemudian pilih Next >.
• Selanjutnya pada Application Info, isi dengan:
2
Android Programming - candra.web.id
Gambar 1.3: Build Target
– Application Name: Kalkulator Konversi
– Package Name: lab.andro.android.kalkulatorkonversi
– Create Activity: KalkulatorKonversiActivity
– Minimum SDK: 10
Kemudian klik Finish.
3
Android Programming - candra.web.id
Gambar 1.4: Application Info
Project Overview
Setelah Project berhasil dibuat, secara otomatis framework aplikasi Android
Anda akan digenerate (dapat anda lihat pada gambar 1.5 dibawah). Beberapa hal penting yang perlu Anda perhatikan dari project ini diantaranya
yakni:
• src
berisi source code Java untuk Program.
• gen
berisi file-file yang digenerate otomatis oleh SDK. Penting: Jangan
mengubah file-file yang ada di dalamnya, karena akan secara otomatis
di ubah oleh SDK.
• res
Berisi file-file resource yang dibutuhkan aplikasi. Seperti file gambar,
audio, layout, theme dan lainnya.
4
Android Programming - candra.web.id
Gambar 1.5: Kalkulator Konversi
• AndroidManifest.xml
Berisi konfigurasi Activity aplikasi dan perizinan akses aplikasi terhadap system.
1.2 Layout
Tampilan aplikasi Android diatur menggunakan Layout. Sebuah aplikasi
Android, dapat menggunakan lebih dari satu layout untuk dapat berinteraksi
dengan user. Layout-layout ini dapat dibuat dengan menggunakan XML.
Anda tidak perlu khawatir jika Anda belum terlalu paham dengan XML,
karena plugin ADT yang terinstall pada Eclipse telah disertai dengan Layout
Editor untuk memudahkan kita dalam membuat Layout ini.
Setiap kali Project baru dibuat, sebuah layout akan digenerate oleh SDK.
Layout ini terletak dalam direktory res/layout dengan nama main.xml.
Gambar 1.6 dibawah ini adalah contoh Layout main.xml yang dibuka dengan
Layout Editor.
5
Android Programming - candra.web.id
Gambar 1.6: Layout Editor
Ada dua mode yang bisa digunakan untuk membuat layout melalui Layout
Editor ini yakni dengan menggunakan mode Grafis atau mode XML. Pada
mode Grafis telah disediakan Pallete yang didalamnya terdapat Widgetwidget yang dapat digunakan pada aplikasi.
Untuk aplikasi Kalkulator ini kita akan mencoba membuat layout dengan
menggunakan mode grafis. Berikut langkah-langkahnya:
1. Buka layout main (main.xml).
2. Hapus Text widget yang telah ada (bertuliskan ”Hello World, KalkulatorKonversiActivity!” pada layout).
3. Tambahkan beberapa widget berikut secara berurutan:
(a) TextView (berada pada pallete Form Widgets),
(b) EditText (berada pada pallete Text Field, bila perlu pilih EditText dengan format Number),
(c) RadioGroup (berada pada pallete Form Widgets), dan
(d) Button (berada pada pallete Form Widgets).
6
Android Programming - candra.web.id
Gambar 1.7: Layout yang telah diubah
4. Selanjutnya, kita perlu mengubah property masing-masing widget yang
telah kita tambahkan pada layout. Ada beberapa cara untuk mengubah propertynya yakni dengan cara meng-klik kanan pada widget
tersebut, kemudian pilih sub-menu yang merepresentasikan propertynya. Atau dengan cara mengubahnya langsung pada file XML-nya
dengan memasuki mode XML Editor.
Untuk lebih memudahkan pemahaman, kita akan mengubah propertinya melalui XML editornya. Masuk ke mode XML editor dengan
mengklik tab main.xml yang berada persis dibawah editor layout.
Kemudian Ubah property masing-masing Widget yang ada menjadi:
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nilai" />
7
Android Programming - candra.web.id
12
13
14
15
16
17
18
19
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="numberDecimal" >
<requestFocus />
</EditText>
20
21
22
23
24
25
26
27
28
29
30
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/radio0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="Meter ke Feet" />
31
32
33
34
35
36
<RadioButton
android:id="@+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Feet ke Meter" />
37
38
39
40
41
42
43
<RadioButton
android:id="@+id/radio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RadioButton" />
</RadioGroup>
44
45
46
47
48
49
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Proses" />
50
51
</LinearLayout>
8
Android Programming - candra.web.id
Catatan: Ubah bagian yang dicetak biru dan hapus bagian yang
dicetak merah.
Sehingga jika layout dilihat pada mode Grafik akan terlihat seperti
gambar 1.8 di bawah ini.
Gambar 1.8: Layout Jadi
1.3 Activity
Untuk menggunakan layout dan menambahkan logika program ke dalamnya
kita perlu membuatkan Activity untuk layout tersebut. Pada program pertama ini, kita akan menggunakan Activity yang telah kita buat saat pembuatan project yang kita beri nama KalkulatorKonversiActivity. Activity
ini berada dalam file KalkulatorKonversiActivity.java yang berada di
dalam direktory src > lab.andro.android.kalkulatorkonversi.
Buka file tersebut untuk mengubahnya.
9
Android Programming - candra.web.id
package lab.andro.android.kalkulatorkonversi;
1
2
import android.app.Activity;
import android.os.Bundle;
3
4
5
public class KalkulatorKonversiActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
6
7
8
9
10
11
12
13
Atur layout agar menggunakan layout main.xml –pada activity utama yang
digenerate pada saat pembuatan Project, layout akan langsung di set ke
main.xml.
Selanjutnya kita perlu menambahkan logika program ke dalamnya. Skenario
aplikasinya yakni:
• User memasukkan input berupa angka ke dalam Text Field,
• Kemudian user memilih jenis konversi Meter ke Feet atau Feet ke
Meter, pilihan default adalah Meter ke Feet (1 meter = 3.2808399
feet).
• Ketika user menekan button ”Proses”, program akan mengkalkulasi
angka yang dimasukkan pada text field sesuai dengan pilihan modenya.
Berikut adalah langkah-langkahnya:
a. Tambahkan beberapa baris kode berikut pada Activity KalkulatorKonversiActivity sebelum methode onCreate:
4
...
5
6
7
8
9
10
public class KalkulatorKonversiActivity extends Activity {
/** Called when the activity is first created. */
private EditText etAngka;
private RadioButton rbMeterFeet;
private Button btnProses;
11
12
@Override
10
Android Programming - candra.web.id
13
14
...
public void onCreate(Bundle savedInstanceState) {
b. Kemudian tekan tombol Ctrl+Shift+O untuk melakukan import kelas
secara otomatis.
c. Selanjutnya, pada methode onCreate, link-kan semua Objek etAngka,
rbMeterFeet dan btnProses dengan komponen Widget yang ada pada Layout. Caranya:
11
...
12
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
13
14
15
16
17
18
19
20
21
22
23
...
}
etAngka = (EditText) findViewById(R.id.editText1);
rbMeterFeet = (RadioButton) findViewById(R.id.radio0);
rbMeterFeet.setChecked(true);
btnProses = (Button) findViewById(R.id.button1);
d. Atur event onCLickListener pada Button btnProses agar dapat menghandle event ketika button ti klik:
20
...
btnProses = (Button) findViewById(R.id.button1);
21
22
23
24
25
26
27
28
29
30
...
}
btnProses.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
kalkulasi();
}
});
Jangan lupa untuk menekan kombinasi tombol Ctrl+Shift+O.
e. Tambahkan methode kalkulasi() setelah methode onCreate:
11
Android Programming - candra.web.id
30
...
31
32
public void kalkulasi() {
double meter = 3.2808399;
33
double angka = 0;
try {
angka = Double.parseDouble(
etAngka.getText().toString());
} catch (Exception e) {
Toast.makeText(this, "Masukkan Angka",
Toast.LENGTH_LONG).show();
}
34
35
36
37
38
39
40
41
42
String hasil;
if(rbMeterFeet.isChecked()) {
hasil = angka + " Meter = " +
(angka * meter) + " Feet";
} else {
hasil = angka + " Feet = " +
(angka / meter) + " Meter";
}
43
44
45
46
47
48
49
50
51
AlertDialog.Builder ab = new AlertDialog.Builder(this);
ab.setTitle("Hasil");
ab.setMessage(hasil);
ab.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
}
}
AlertDialog dialog = ab.create();
dialog.show();
Keterangan: Toast digunakan untuk menampilkan notifikasi pada layar. Sedangkan AlertDialog.Builder dan AlertDialog digunakan untuk membuat Alert dialog, dimana nati hasil
12
Android Programming - candra.web.id
kalkulasi akan ditampilkan ke dalam dialog ini.
Full Source:
✞
1 package lab. andro . android . kalkulatorkonversi ;
2
3
4
5
6
7
8
9
10
11
import
import
import
import
import
import
import
import
import
android .app. Activity ;
android .app. AlertDialog ;
android . content . DialogInterface ;
android .os. Bundle ;
android .view.View;
android . widget . Button ;
android . widget . EditText ;
android . widget . RadioButton ;
android . widget . Toast ;
12
13
14
15
16
17
public class KalkulatorKonversiActivity extends Activity {
/** Called when the activity is first created . */
private EditText etAngka ;
private RadioButton rbMeterFeet ;
private Button btnProses ;
18
19
20
21
22
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main);
23
24
25
26
27
etAngka = ( EditText ) findViewById (R.id. editText1 );
rbMeterFeet = ( RadioButton ) findViewById (R.id. radio0 );
rbMeterFeet . setChecked (true);
btnProses = ( Button ) findViewById (R.id. button1 );
28
29
30
31
32
33
34
btnProses . setOnClickListener (new View. OnClickListener ()
{
public void onClick (View v) {
kalkulasi ();
}
});
}
35
36
37
public void kalkulasi () {
double meter = 3.2808399;
38
39
40
41
42
43
44
double angka = 0;
try {
angka = Double . parseDouble (
etAngka . getText (). toString ());
} catch ( Exception e) {
Toast . makeText (this , " Masukkan Angka ",
13
Android Programming - candra.web.id
45
}
46
Toast . LENGTH_LONG ).show ();
47
String hasil ;
if( rbMeterFeet . isChecked ()) {
hasil = angka + " Meter = " +
(angka * meter ) + " Feet";
} else {
hasil = angka + " Feet = " +
(angka / meter ) + " Meter ";
}
48
49
50
51
52
53
54
55
56
AlertDialog . Builder ab = new AlertDialog . Builder (this);
ab. setTitle ("Hasil");
ab. setMessage ( hasil );
ab. setPositiveButton ("Ok",
new DialogInterface . OnClickListener () {
public void onClick ( DialogInterface dialog ,
int which ) {
dialog . dismiss ();
}
});
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
}
✝
}
AlertDialog dialog = ab. create ();
dialog .show ();
KalkulatorKonversiActivity.java
Setelah semua ditambahkan, simpan perubahan. Pastikan semua kelas yang
perlu di-import telah diimport.
1.4 Running
Sebelum dapat menjalankan program, pastikan terlebih dahulu Anda telam
membuat Virtual Device android dengan versi 2.3.3 (Api 10) atau versi setelahnya (untuk pembuatan AVD, lihat Appendix). Atau jika Anda memiliki
perangkat handset Android, Anda dapat menggunakannya sebagai tempat
uji coba program dengan menghubungkannya melalui USB.
Ada beberapa cara untuk menjalankan program, Pertama dengan menekan
kombinasi tombol Ctrl+F11 atau melalui menu Run > Run atau dengan
menekan Button Run pada toolbar. Gambar 1.9 di bawah ini adalah gambar
dialog run saat pertama kali menjalankan aplikasi.
14
✆
Android Programming - candra.web.id
Gambar 1.9: Run As –Pilih Android Application
Contoh hasil Running aplikasi yang telah jadi:
Gambar 1.10: Hasil Running Aplikasi
15
MODUL
2
Image Viewer
Target
Gambar 2.1: Image Viewer
16
Android Programming - candra.web.id
2.1 Project
Pada modul ini kita akan mencoba membuat aplikasi untuk mengolah gambar dengan resource gambar berasal dari SD Card. Selain menampilkan
Gambar, pada modul ini kita juga akan mencoba menggunakan dan memanggil Aplikasi built-in Android dari dalam aplikasi kita.
Untuk mencobanya, kita perlu membuat sebuah Project baru. Buat sebuah
Project baru dengan konfigurasi Project sebagai berikut:
• Project name:Image Viewer
• Build target: Api 10
• Application name: Image Viewer
• Package name: lab.andro.android.imageviewer
• Create Activity: ImageViewerActivity
• Minimum SDK: 10
2.2 Layout
Setelah Project dibuat, selanjutnya kita perlu mengubah layout main.xml
yang telah ada. Tambahkan beberapa Widget secara berurutan beserta propertynya yakni:
a. Button (berada pada pallete Form Widgets)
• id= ”@+id/button1”
• text= ”Buka Gambar”
• layout_width= ”match_parent”
b. ImageView (berada pada pallete Images & Media)
Pada saat menambahkan akan dikonfirmasi mengenai gabar yang akan
digunakan. Pilih saja gambar Icon yang ada (ic_launcher).
• id=”@+id/imageView1”
• layout_width= ”match_parent”
• layout_height= ”match_parent”
17
Android Programming - candra.web.id
Kurang lebih layout akan terlihat seperti gambar 2.2 di bawah ini.
Gambar 2.2: Layout
Dengan isi file main.xml menjadi:
✞
1 <?xml version ="1.0" encoding ="utf -8"?>
2 <LinearLayout xmlns:android =" http: // schemas . android .com/apk/res/
android "
3
android:layout_width =" fill_parent "
4
android:layout_height =" fill_parent "
5
android:orientation =" vertical " >
6
7
8
9
10
11
<Button
android:id ="@+id/ button1 "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:text ="Buka Gambar " />
12
18
Android Programming - candra.web.id
<ImageView
android:id ="@+id/ imageView1 "
android:layout_width =" match_parent "
android:layout_height =" match_parent "
android:src =" @drawable / ic_launcher " />
13
14
15
16
17
18
19
</ LinearLayout >
✝
main.xml
Kemudian simpan perubahan pada layout.
2.3 Activity
Setelah layout selesai dibuat, selanjutnya kita perlu mengimplementasikan
logika program ke dalam Activitynya. Skenarionya yakni:
• Ketika user menekan button ”Buka Gambar” user akan masuk ke galeri
Gambar yang ada pada Handset Android.
• Gambar yang dipilih oleh user pada galeri, akan ditampilkan dibawah
button ”Buka Gambar”.
Berdasarkan skenario tersebut, kita akan membutuhkan Activity lain yakni
Activity Galery. Activity galery yang akan kita gunakan adalah acitivity
galery built-in dari Android. Sehingga kita tidak perlu repot-repot untuk
membuat Activity baru yang serupa.
Untuk mengimplementasikan skenario tersebut, berikut adalah langkahlangkahnya:
a. Buka Activity ImageViewerActivity, kemudian tambahkan beberapa
property berikut:
7
8
9
10
11
12
...
public class ImageViewerActivity extends Activity {
public static final int _PILIH_GAMBAR = 1;
private Button btnBuka;
private ImageView ivGambar;
...
Jangn lupa untuk menekan tombol Ctrl+Shift+O untuk mengimport
kelas secara otomatis.
19
✆
Android Programming - candra.web.id
b. Selanjutnya pada methode onCreate, linkan btnBuka dan ivGambar dengan widget-widget yang ada pada layout:
12
13
14
15
16
17
18
19
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnBuka = (Button) findViewById(R.id.button1);
ivGambar = (ImageView) findViewById(R.id.imageView1);
...
c. Buat handler untuk menghandle event Klik pada Button btnBuka di dalam
methode onCreate:
19
20
...
btnBuka.setOnClickListener(new View.OnClickListener() {
21
22
23
24
25
26
});
...
public void onClick(View v) {
bukaGambar();
}
d. Tambahkan methode bukaGambar ke dalam activity:
30
31
32
33
34
35
36
37
...
private void bukaGambar() {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images
.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, _PILIH_GAMBAR);
}
...
e. Dan yang terakhir, tambahkan Override methode onActivityResult untuk menghandle ketika user memilih gambar dari galeri:
37
38
39
...
@Override
protected void onActivityResult(int requestCode,
20
Android Programming - candra.web.id
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
40
41
42
switch (requestCode) {
case _PILIH_GAMBAR:
if(resultCode == RESULT_OK){
Uri gambarTerpilih = data.getData();
InputStream gbrStream = null;
try {
gbrStream = getContentResolver()
.openInputStream(gambarTerpilih);
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}
Bitmap bitGambar = BitmapFactory
.decodeStream(gbrStream);
ivGambar.setImageBitmap(bitGambar);
}
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
break;
60
61
62
63
64
}
...
65
66
default:
break;
}
f. Sehingga, source untuk activity ini menjadi:
1
✞
package lab. andro . android . imageviewer ;
2
3
4
import java.io. FileNotFoundException ;
import java.io. InputStream ;
5
6
7
8
9
10
11
12
13
import
import
import
import
import
import
import
import
android .app. Activity ;
android . content . Intent ;
android . graphics . Bitmap ;
android . graphics . BitmapFactory ;
android .net.Uri;
android .os. Bundle ;
android .view.View;
android . widget . Button ;
21
Android Programming - candra.web.id
14
import android . widget . ImageView ;
15
16
17
18
19
public class ImageViewerActivity extends Activity {
public static final int _PILIH_GAMBAR = 1;
private Button btnBuka ;
private ImageView ivGambar ;
20
21
22
23
24
25
26
@Override
public void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
setContentView (R. layout .main);
btnBuka = ( Button ) findViewById (R.id. button1 );
ivGambar = ( ImageView ) findViewById (R.id. imageView1 );
27
btnBuka . setOnClickListener (new View. OnClickListener () {
28
29
30
31
32
33
34
}
public void onClick (View v) {
bukaGambar ();
}
});
35
36
37
38
39
40
41
private void bukaGambar () {
Intent i = new Intent ( Intent . ACTION_PICK ,
android . provider . MediaStore . Images
. Media . EXTERNAL_CONTENT_URI );
startActivityForResult (i, _PILIH_GAMBAR );
}
42
43
44
45
@Override
protected void onActivityResult (int requestCode , int
resultCode , Intent data) {
super. onActivityResult ( requestCode , resultCode , data);
46
47
48
49
50
51
52
53
54
55
56
57
58
59
switch ( requestCode ) {
case _PILIH_GAMBAR :
if( resultCode == RESULT_OK ){
Uri gambarTerpilih = data. getData ();
InputStream gbrStream = null;
try {
gbrStream = getContentResolver (). openInputStream (
gambarTerpilih );
} catch ( FileNotFoundException e) {
e. printStackTrace ();
return ;
}
Bitmap bitGambar = BitmapFactory . decodeStream (
gbrStream );
ivGambar . setImageBitmap ( bitGambar );
22
Android Programming - candra.web.id
}
60
61
break;
62
63
64
65
66
67
68
}
✝
}
default :
break;
}
ImageViewerActivity.java
g. Simpan semua perubahan.
2.4 Running
Sebelum mencoba menjalankan aplikasi Image Viewer ini, kita perlu
menambahkan file gambar ke dalam SD-Card emulator terlebih dahulu. Untuk menambahkan file gambar ini caranya yakni:
• Jalankan emulator yang akan digunakan untuk menguji aplikasi.
• Setelah emulator berhasil dijalankan dan system Android nya berjalan
sempurna, buka perspective DDMS pada Eclipse, melalui menu Window > Open Perspective > DDMS.
• Pada DDMS, buka tab File Explorer.
• Untuk menyimpan ke dalam SD-Card, masuk ke direktory mnt >
sdcard. Pilih direktory sdcard kemudian klik button berlogo HP yang
ada persis di pojok kanan-atas list direktory pada tab tersebut. Sebagai
contoh lihat Gambar 2.3.
• Kemudian pilih file gambar yang akan di-upload ke dalam emulator.
• Setelah file berhasil di-upload, pada beberapa kasus kadang kita harus
merestart emulator untuk dapat melihat hasilnya.
23
✆
Android Programming - candra.web.id
Gambar 2.3: File Explorer
Setelah file gambar berhasil di-upload ke emulator, selanjutnya tinggal menguji coba Aplikasi Image viewer kita ini. Contoh hasil Run program:
Gambar 2.4: Hasil Run aplikasi Image Viewer
24
MODUL
3
Audio Player
Target
Gambar 3.1: Target: Music Player
25
Android Programming - candra.web.id
3.1 Project
Pada modul ini kita akan mencoba membuat aplikasi Music Player. Pada
aplikasi ini, kita akan mencoba kontrol-kontrol sederhana media player untuk dapat menjalankan music seperti play, pause dan resume. Untuk mencobanya, kita perlu membuat sebuah project baru, dengan konfigurasi sebagai berikut:
• Project name:Music Player
• Build target: Api 10
• Application name: Music Player
• Package name: lab.andro.android.musicplayer
• Create Activity: MusicPlayerActivity
• Minimum SDK: 10
3.2 Layout
Buat layout sederhana, untuk media player ini. Pada layout ini kita akan
mengggunakan RelativeLayout untuk membuat tampilan yang menarik
dan lebih flexible. (Tips: Untuk membuat layout ini sebaiknya menggunakan mode XML, karena akan terasa lebih mudah dibandingkan dengan
mode grafis)
Buat layout sebagai berikut:
✞
<?xml version ="1.0" encoding ="utf -8"?>
2 <RelativeLayout xmlns:android ="http: // schemas . android .com/apk/
res/ android "
3
android:layout_width =" fill_parent "
4
android:layout_height =" fill_parent " >
1
5
6
7
8
9
10
11
12
<ImageButton
android:id ="@+id/ imageButtonAdd "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentBottom ="true"
android:layout_alignTop ="@+id/ imageButtonPlay "
android:src =" @android:drawable / ic_input_add " />
13
14
<ImageButton
26
Android Programming - candra.web.id
15
16
17
18
19
20
android:id ="@+id/ imageButtonPlay "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentBottom ="true"
android:layout_toRightOf ="@+id/ imageButtonAdd "
android:src =" @android:drawable / ic_media_play " />
21
22
23
24
25
26
27
<SeekBar
android:id ="@+id/ seekBar1 "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:layout_alignTop ="@+id/ imageButtonPlay "
android:layout_toRightOf ="@+id/ imageButtonPlay " />
28
29
30
31
32
33
34
35
36
<TextView
android:id ="@+id/ textView1 "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_above ="@+id/ imageButtonAdd "
android:layout_alignParentLeft ="true"
android:layout_alignParentRight ="true"
android:text =" TextView " />
37
38
39
40
41
42
43
44
45
46
<ImageView
android:id ="@+id/ imageView1 "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_above ="@+id/ textView1 "
android:layout_alignParentLeft ="true"
android:layout_alignParentRight ="true"
android:layout_alignParentTop ="true"
android:src =" @android:drawable / divider_horizontal_dark "
/>
47
48
</ RelativeLayout >
✝
Layout main.xml
Catatan: Semua gambar atau icon yang digunakan pada widget ImageButton, menggunakan icon yang ada dalam SDK. Anda bisa menggantinya dengan icon atau gambar sendiri yang di taruh di dalam direktory res > drawable.
Jika layout ditampilkan dari mode grafis, maka akan terlihat seperti Gambar
3.2 di bawah ini.
27
✆
Android Programming - candra.web.id
Gambar 3.2: Layout main.xml dengan menggunakan RelativeLayout
3.3 Activity
Selanjutnya kita perlu mengubah Activity MusicPlayerActivity. Skenario
aplikasi Music Player ini yakni:
• User memilih file dari dalam galeri Music dengan mengklik button
bergambar ”plus”.
• Setelah file dipilih, User baru bisa menjalankan filenya dengan menekan
Button ”Play”.
• Ketika music sedang berjalan, seek bar akan ter-update secara otomatis, Button play berubah menjadi button ”Pause”, jika file musicnya
memiliki Cover Art maka Cover Art-nya akan ditampilkan dalam Image View dan Informasi file Music akan ditampilkan di TextView yang
terletak dibawah ImageView.
• User dapat men-seek music ke posisi tertentu dengan mengklik pada
seekbar.
28
Android Programming - candra.web.id
Untuk mengimplementasikan skenario program diatas, mari kita tambahkan
beberapa perubahan pada Activity MusicPlayerActivity.
a. Tambahkan beberapa Property berikut:
...
private
private
private
private
private
private
private
private
private
private
private
private
...
static final int _BUKA_GALERY = 1;
MediaPlayer mPlayer;
ImageButton ibPlay;
ImageView ivGambar;
SeekBar sbProgress;
TextView tvFileInfo;
ImageButton btn;
Uri uriFile;
Uri lastUri;
MediaMetadataRetriever mRetriever;
boolean played;
final Handler handler = new Handler();
b. Pada methode onCreate, linkkan semua widget yang telah dibuat di atas
dengan widget yang ada dalam layout. Serta implementasikan semua
objek (selain Widget) yang telah dideklarasikan di atas.
...
...
ibPlay = (ImageButton) findViewById(R.id.imageButtonPlay);
ibPlay.setEnabled(false);
ivGambar = (ImageView) findViewById(R.id.imageView1);
sbProgress = (SeekBar) findViewById(R.id.seekBar1);
tvFileInfo = (TextView) findViewById(R.id.textView1);
btn = (ImageButton) findViewById(R.id.imageButtonAdd);
mRetriever = new MediaMetadataRetriever();
mPlayer = new MediaPlayer();
played = false;
c. Atur Listener untuk event-event onClickListener pada button, onTouch
pada SeekBar dan onCompleteListener untuk objek MediaPlayer.
29
Android Programming - candra.web.id
...
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
bukaFile();
}
});
ibPlay.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
playPause();
}
});
mPlayer.setOnCompletionListener(
new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
played = false;
ibPlay.setImageResource(
android.R.drawable.ic_media_play);
}
});
sbProgress.setOnTouchListener(
new View.OnTouchListener() {
...
public boolean onTouch(View v,
MotionEvent event) {
seekChange(v);
return false;
}
});
d. Implementasikan methode seekChange(View v):
...
protected void seekChange(View v) {
if (mPlayer.isPlaying()) {
SeekBar sb = (SeekBar) v;
mPlayer.seekTo(sb.getProgress());
}
30
Android Programming - candra.web.id
}
...
e. Implementasikan methode bukaFile():
...
private void bukaFile() {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore
.Audio.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, _BUKA_GALERY);
}
...
f. Tambahkan Overide Methode onActivityResult untuk mengambil uri dari
file yang dipilih pada Galeri.
...
@Override
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case _BUKA_GALERY:
if (resultCode == RESULT_OK) {
Uri file = data.getData();
setFile(file);
}
break;
}
...
default:
break;
}
g. Tambahkan methode setFile(Uri file):
...
private void setFile(Uri file) {
31
Android Programming - candra.web.id
}
...
uriFile = file;
ibPlay.setEnabled(true);
h. Buat methode untuk menjalankan thread yang bertugas untuk mengupdate SeekBar.
...
public void startPlayProgressUpdater() {
sbProgress.setProgress(mPlayer.getCurrentPosition());
if (mPlayer.isPlaying()) {
Runnable notifikasi = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
handler.postDelayed(notifikasi, 1000);
} else {
mPlayer.pause();
ibPlay.setImageResource(
android.R.drawable.ic_media_play);
}
}
...
i. Buat methode playPause():
...
private void playPause() {
...
}
...
j. Pada methode playPause, tambahkan kode untuk mengecek status MediaPlayer mPlayer dan uri dari file yang akan dimainkan:
...
if (played && lastUri == uriFile) {
mPlayer.pause();
ibPlay.setImageResource(
32
Android Programming - candra.web.id
android.R.drawable.ic_media_play);
played = false;
return;
} else if (!played && lastUri == uriFile) {
mPlayer.start();
ibPlay.setImageResource(
android.R.drawable.ic_media_pause);
played = true;
startPlayProgressUpdater();
return;
}
...
if (lastUri != uriFile) {
if (played) {
mPlayer.stop();
}
mPlayer.reset();
played = false;
ibPlay.setImageResource(
android.R.drawable.ic_media_play);
}
Pengecekan dilakukan agar tidak terjadi kesalahan logika saat menjalankan media player.
k. Implementasikan kode untuk mengontrol objek MediaPlayer pada methode ini, serta beberapa kode untuk mendapatkan informasi mengenai file
Audio yang dijalankan (Title, Artist, Cover Art dan lainnya):
...
try {
mPlayer.setDataSource(this, uriFile);
mPlayer.prepare();
mPlayer.start();
played = true;
lastUri = uriFile;
mRetriever.setDataSource(this, uriFile);
String judul = mRetriever
33
Android Programming - candra.web.id
.extractMetadata(
MediaMetadataRetriever
.METADATA_KEY_TITLE);
String artist = mRetriever
.extractMetadata(
MediaMetadataRetriever
.METADATA_KEY_ARTIST);
tvFileInfo.setText(artist + " - " + judul);
byte[] albumArt = mRetriever.getEmbeddedPicture();
if (albumArt != null) {
Bitmap artwork = BitmapFactory.decodeByteArray(
albumArt, 0,
albumArt.length);
ivGambar.setImageBitmap(artwork);
} else {
ivGambar.setImageResource(
R.drawable.ic_launcher);
}
ibPlay.setImageResource(
android.R.drawable.ic_media_pause);
sbProgress.setMax(mPlayer.getDuration());
sbProgress.setProgress(0);
startPlayProgressUpdater();
...
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this,
"Gagal membuka file", Toast.LENGTH_LONG)
.show();
}
34
Android Programming - candra.web.id
Keterangan: kode program:
1
2
3
4
5
6
7
8
9
mRetriever.setDataSource(this, uriFile);
String judul = mRetriever
.extractMetadata(
MediaMetadataRetriever
.METADATA_KEY_TITLE);
String artist = mRetriever
.extractMetadata(
MediaMetadataRetriever
.METADATA_KEY_ARTIST);
10
11
tvFileInfo.setText(artist + " - " + judul);
12
13
14
15
16
17
18
19
20
21
22
byte[] albumArt = mRetriever.getEmbeddedPicture();
if (albumArt != null) {
Bitmap artwork = BitmapFactory.decodeByteArray(
albumArt, 0,
albumArt.length);
ivGambar.setImageBitmap(artwork);
} else {
ivGambar.setImageResource(
R.drawable.ic_launcher);
}
23
24
25
ibPlay.setImageResource(
android.R.drawable.ic_media_pause);
Digunakan untuk mendapatkan informasi dari file Audio. Dengan menggunakan objek dari MediaMetadataRetriever, kita dapat mengambil metadata file mengenai Title (MediaMetadataRetriever.METADATA_KEY_TITLE), Artist dan lainnya. Sedangkan untuk mengambil Cover Art dengan memanfaatkan methode
getEmbeddedPicture dari objek MediaMetadataRetriever. Namun
embedded picture ini masih bertype byte, sehingga perlu dikonversi
menjadi bitmap terlebih dahulu.
l. Sehingga keseluruhan kode program akan menjadi:
1
✞
package lab. andro . android . musicplayer ;
2
3
4
5
import java.io. IOException ;
import android .app. Activity ;
import android . content . Intent ;
35
Android Programming - candra.web.id
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android . graphics . Bitmap ;
android . graphics . BitmapFactory ;
android . media . MediaMetadataRetriever ;
android . media . MediaPlayer ;
android .net.Uri;
android .os. Bundle ;
android .os. Handler ;
android .view. MotionEvent ;
android .view.View;
android . widget . ImageButton ;
android . widget . ImageView ;
android . widget . SeekBar ;
android . widget . TextView ;
android . widget . Toast ;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MusicPlayerActivity extends Activity {
private static final int _BUKA_GALERY = 1;
private MediaPlayer mPlayer ;
private ImageButton ibPlay ;
private ImageView ivGambar ;
private SeekBar sbProgress ;
private TextView tvFileInfo ;
private ImageButton btn;
private Uri uriFile ;
private Uri lastUri ;
private MediaMetadataRetriever mRetriever ;
private boolean played ;
private final Handler handler = new Handler ();
34
35
36
37
38
39
/** Called when the activity is first created . */
@Override
public void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
setContentView (R. layout .main);
40
41
42
43
44
45
46
47
ibPlay = ( ImageButton ) findViewById (R.id. imageButtonPlay );
ibPlay . setEnabled (false );
ivGambar = ( ImageView ) findViewById (R.id. imageView1 );
sbProgress = ( SeekBar ) findViewById (R.id. seekBar1 );
tvFileInfo = ( TextView ) findViewById (R.id. textView1 );
btn = ( ImageButton ) findViewById (R.id. imageButtonAdd );
mRetriever = new MediaMetadataRetriever ();
48
49
50
mPlayer = new MediaPlayer ();
played = false ;
51
52
53
54
btn. setOnClickListener (new View. OnClickListener () {
public void onClick (View v) {
bukaFile ();
36
Android Programming - candra.web.id
}
});
55
56
57
ibPlay . setOnClickListener (new View. OnClickListener () {
public void onClick (View v) {
playPause ();
}
});
58
59
60
61
62
63
mPlayer . setOnCompletionListener (new MediaPlayer .
OnCompletionListener () {
public void onCompletion ( MediaPlayer mp) {
played = false ;
ibPlay . setImageResource ( android .R. drawable .
ic_media_play );
}
});
64
65
66
67
68
69
70
sbProgress . setOnTouchListener (new View. OnTouchListener () {
71
72
public boolean onTouch (View v, MotionEvent event ) {
seekChange (v);
return false;
}
});
73
74
75
76
77
78
79
}
80
81
82
83
84
85
86
protected void seekChange (View v) {
if ( mPlayer . isPlaying ()) {
SeekBar sb = ( SeekBar ) v;
mPlayer . seekTo (sb. getProgress ());
}
}
87
88
private void playPause () {
89
90
91
92
93
94
95
96
97
98
99
100
101
if ( played && lastUri == uriFile ) {
mPlayer . pause ();
ibPlay . setImageResource (
android .R. drawable . ic_media_play );
played = false;
return ;
} else if (! played && lastUri == uriFile ) {
mPlayer . start ();
ibPlay . setImageResource (
android .R. drawable . ic_media_pause );
played = true;
startPlayProgressUpdater ();
37
Android Programming - candra.web.id
102
103
}
return ;
104
105
106
107
108
109
110
111
112
113
if ( lastUri != uriFile ) {
if ( played ) {
mPlayer .stop ();
}
mPlayer . reset ();
played = false;
ibPlay . setImageResource (
android .R. drawable . ic_media_play );
}
114
115
try {
116
117
118
119
120
121
mPlayer . setDataSource (this , uriFile );
mPlayer . prepare ();
mPlayer . start ();
played = true;
lastUri = uriFile ;
122
123
124
125
126
127
128
129
130
131
mRetriever . setDataSource (this , uriFile );
String judul = mRetriever
. extractMetadata (
MediaMetadataRetriever
. METADATA_KEY_TITLE );
String artist = mRetriever
. extractMetadata (
MediaMetadataRetriever
. METADATA_KEY_ARTIST );
132
133
tvFileInfo . setText ( artist + " - " + judul );
134
135
136
137
138
139
140
141
142
143
144
byte [] albumArt = mRetriever . getEmbeddedPicture ();
if ( albumArt != null) {
Bitmap artwork = BitmapFactory . decodeByteArray (
albumArt , 0,
albumArt . length );
ivGambar . setImageBitmap ( artwork );
} else {
ivGambar . setImageResource (
R. drawable . ic_launcher );
}
145
146
147
ibPlay . setImageResource (
android .R. drawable . ic_media_pause );
148
149
150
sbProgress . setMax ( mPlayer . getDuration ());
sbProgress . setProgress (0);
38
Android Programming - candra.web.id
startPlayProgressUpdater ();
151
152
} catch ( IllegalArgumentException e) {
e. printStackTrace ();
} catch ( SecurityException e) {
e. printStackTrace ();
} catch ( IllegalStateException e) {
e. printStackTrace ();
} catch ( IOException e) {
e. printStackTrace ();
Toast . makeText (this ,
"Gagal membuka file", Toast . LENGTH_LONG )
.show ();
}
153
154
155
156
157
158
159
160
161
162
163
164
165
166
}
167
168
169
170
171
172
173
private void bukaFile () {
Intent i = new Intent ( Intent . ACTION_PICK ,
android . provider . MediaStore
. Audio . Media . EXTERNAL_CONTENT_URI );
startActivityForResult (i, _BUKA_GALERY );
}
174
175
176
177
178
@Override
protected void onActivityResult (int requestCode ,
int resultCode , Intent data) {
super. onActivityResult ( requestCode , resultCode , data);
179
switch ( requestCode ) {
case _BUKA_GALERY :
if ( resultCode == RESULT_OK ) {
Uri file = data. getData ();
setFile (file);
}
break;
180
181
182
183
184
185
186
187
188
189
190
191
}
default :
break;
}
192
193
194
195
196
private void setFile (Uri file) {
uriFile = file;
ibPlay . setEnabled (true);
}
197
198
199
public void startPlayProgressUpdater () {
sbProgress . setProgress ( mPlayer . getCurrentPosition ());
39
Android Programming - candra.web.id
200
201
202
203
204
205
206
207
208
209
210
211
212
213
}
✝
}
if ( mPlayer . isPlaying ()) {
Runnable notifikasi = new Runnable () {
public void run () {
startPlayProgressUpdater ();
}
};
handler . postDelayed ( notifikasi , 1000) ;
} else {
mPlayer . pause ();
ibPlay . setImageResource (
android .R. drawable . ic_media_play );
}
Activity MusicPlayerActivity
3.4 Running
Setelah semua methode diimplementasikan, sekarang kita perlu mencoba Aplikasi ini. Namun sebelumnya kita perlu mengupload beberapa file Music ke
dalam emulator. Caranya dapat Anda baca kembali pada modul sebelumnya.
Berikut adalah contoh running aplikasi MusicPlayer yang telah kita buat di
atas:
40
✆
Android Programming - candra.web.id
Gambar 3.3: Hasil akhir aplikasi
41
MODUL
4
Web Browser
Target
Gambar 4.1: Target Aplikasi: Web Browser
42
Android Programming - candra.web.id
4.1 Project
Pada modul ini kita akan mencoba membuat aplikasi Music Player. Pada
aplikasi ini, kita akan mencoba kontrol-kontrol sederhana media player untuk dapat menjalankan music seperti play, pause dan resume. Untuk mencobanya, kita perlu membuat sebuah project baru, dengan konfigurasi sebagai berikut:
• Project name:Web Browser
• Build target: Api 10
• Application name: Web Browser
• Package name: lab.andro.web.browser
• Create Activity: WebBrowserActivity
• Minimum SDK: 10
4.2 Layout
Setelah Project dibuat, selanjutnya kita perlu mengubah layout main.xml
yang telah ada. Tambahkan beberapa Widget secara berurutan beserta propertynya yakni:
• Ubah orientasi LinearLayout yang telah ada menjadi vertikal,
• Tambahkan sebuah Linier Layout dengan orientasi ”horizontal” kemudian isi dengan beberapa widget berikut beserta propertynya:
– EditText
id=”@+id/editText1”
– Button
id=”@+id/button1”
layout width=”80dip”
layout height=”wrap_content”
text=”Go”
43
Android Programming - candra.web.id
• Tambahkan widget WebView dibawah LinearLayout yang telah
ditambahkan pada point sebelumnya dengan property:
id=”@+id/webView1”
layout width=”match_parent”
layout height=”match_parent”
Sehingga layout menjadi:
Gambar 4.2: Layout
Dengan kode XML sebagai berikut:
✞
1 <?xml version ="1.0" encoding ="utf -8"?>
2 <LinearLayout xmlns:android =" http: // schemas . android .com/apk/res/
android "
3
android:layout_width =" fill_parent "
4
android:layout_height =" fill_parent "
5
android:orientation =" vertical " >
6
7
8
9
10
<LinearLayout
android:id ="@+id/ linearLayout1 "
android:layout_width =" match_parent "
android:layout_height =" wrap_content " >
11
44
Android Programming - candra.web.id
12
13
14
15
16
<EditText
android:id ="@+id/ editText1 "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_weight ="1" >
17
18
19
<requestFocus />
</ EditText >
20
21
22
23
24
25
26
<Button
android:id ="@+id/ button1 "
android:layout_width ="80 dip"
android:layout_height =" wrap_content "
android:text ="Go" />
</ LinearLayout >
27
28
29
30
31
<WebView
android:id ="@+id/ webView1 "
android:layout_width =" match_parent "
android:layout_height =" match_parent " />
32
33
</ LinearLayout >
✝
Layout main.xml
✆
4.3 Activity
Setelah Layout dibuat, selanjutnya kita perlu mengubah activity WebBrowserActivity.
1. Tambahkan beberapa property berikut:
...
private EditText etAddress;
private Button btnGoToAddr;
private WebView webView;
...
2. Pada methode onCreate, link-kan semua objek widget di atas dengan
widgetnya yang ada di layout:
...
etAddress = (EditText) findViewById(R.id.editText1);
btnGoToAddr = (Button) findViewById(R.id.button1);
45
Android Programming - candra.web.id
...
webView = (WebView) findViewById(R.id.webView1);
3. Set web client untuk webView agar web dapat ditampilkan melalui
widget web view yang ada pada layout:
...
...
webView.setWebViewClient(new WebViewClient());
4. Set listener on Click untuk button Go:
...
...
btnGoToAddr.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
String addr = etAddress.getText().toString();
webView.loadUrl(addr);
}
});
5. Sehingga akan menjadi:
1
✞
package lab. andro .web. browser ;
2
3
4
5
6
7
8
9
import
import
import
import
import
import
import
android .app. Activity ;
android .os. Bundle ;
android .view.View;
android . webkit . WebView ;
android . webkit . WebViewClient ;
android . widget . Button ;
android . widget . EditText ;
10
11
12
13
14
15
16
17
18
19
public class WebBrowserActivity extends Activity {
/** Called when the activity is first created . */
private EditText etAddress ;
private Button btnGoToAddr ;
private WebView webView ;
@Override
public void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
setContentView (R. layout .main);
20
46
Android Programming - candra.web.id
etAddress = ( EditText ) findViewById (R.id. editText1 );
btnGoToAddr = ( Button ) findViewById (R.id. button1 );
webView = ( WebView ) findViewById (R.id. webView1 );
webView . setWebViewClient (new WebViewClient ());
21
22
23
24
25
btnGoToAddr . setOnClickListener (new View.
OnClickListener () {
26
27
28
29
30
31
32
33
34
}
✝
public void onClick (View v) {
String addr = etAddress . getText (). toString ();
webView . loadUrl (addr);
}
});
}
Activity: WebBrowserActivity
4.4 Running dan Set Permission
Setelah semua kode kita implementasikan, program belum dapat dijalankan
langsung. Karena butuh perizinan untuk menggunakan koneksi Internet.
Jika dijalankan tanpa mengatur perizinannya, maka ketika dijalankan akan
terlihat seperti pada gambar 4.3.
Gambar 4.3: Web Browser
47
✆
Android Programming - candra.web.id
Untuk menanggulangi masalah ini, buka file AndroidManifest.xml yang
berada pada root project. Kemudian Tambahkan satu baris kode berikut di
luar tag application.:
...
<uses-permission android:name="android.permission.INTERNET"/>
...
Sehingga menjadi:
✞
1 <?xml version ="1.0" encoding ="utf -8"?>
2 <manifest xmlns:android =" http: // schemas . android .com/apk/res/
android "
3
package ="lab. andro .web. browser "
4
android:versionCode ="1"
5
android:versionName ="1.0" >
6
7
8
<uses -sdk android:minSdkVersion ="10" />
<uses - permission android:name =" android . permission . INTERNET "/
>
9
10
11
12
13
14
15
16
17
<application
android:icon =" @drawable / ic_launcher "
android:label =" @string / app_name " >
<activity
android:label =" @string / app_name "
android:name =". WebBrowserActivity " >
<intent - filter >
<action android:name =" android . intent . action .MAIN
" />
18
19
20
21
22
<category android:name =" android . intent . category .
LAUNCHER " />
</intent - filter >
</ activity >
</ application >
23
24
</ manifest >
✝
Activity: WebBrowserActivity
Kemudian jalankan kembali program. Jika tidak ada masalah, maka hasilnya
akan menjadi:
48
✆
Android Programming - candra.web.id
Gambar 4.4: Hasil Running Aplikasi Web Browser
49
MODUL
5
Map Application
Target
Gambar 5.1: Target
50
Android Programming - candra.web.id
5.1 Google Map API Key
Sebelum kita membuat project, pertama kita mengenerate API key untuk
Aplikasi kita. Sebagai catatan, API key yang digunakan pada komputer
yang berbeda akan berbeda juga.
Untuk mendapatkan Google Map API key, langkah-langkahnya yakni:
a. Buka terminal (Untuk Linux atau Mac) atau Command Prompt (untuk
Windows). Sebelumnya pastikan PATH ke binary/executable jre telah di
setting terlebih dahulu agar binary keytool dapat di eksekusi.
b. Melalui Terminal ketikkan perintak berikut:
$ keytool -list -keystore KEYSTORE -v
Ganti KEYSTORE dengan lokasi debug.keystore yang ada pada komputer
Anda masing-masing.
• Windows Vista:
C:\Users\<user>\.android\debug.keystore}
• Windows XP:
C:\Documents and Settings\<user>\.android\debug.keystore
• OS X and Linux:
~/.android/debug.keystore
Contoh hasilnya:
Enter keystore password:
***************** WARNING WARNING WARNING *****************
* The integrity of the information stored in your keystore *
* has NOT been verified! In order to verify its integrity, *
* you must provide your keystore password.
*
***************** WARNING WARNING WARNING *****************
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
51
Android Programming - candra.web.id
Alias name: androiddebugkey
Creation date: Apr 14, 2012
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 1a95b440
Valid from: Sat Apr 14 17:09:12 WIT 2012 until: Mon Apr 07 ...
Certificate fingerprints:
MD5: 99:8D:B7:9D:14:A6:EE:48:33:0C:7B:AF:41:62:CD:10
SHA1: E9:D6:F2:56:AE:F0:D9:63:D6:73:93:42:E9:BE:5B:E1:...
SHA256: C7:47:AA:0E:DC:72:08:B0:24:F5:CB:C9:2C:F1:81:72:...
Signature algorithm name: SHA256withRSA
Version: 3
...
c. Ambil MD5 dari fingerprint keystore tersebut (dicetak biru pada contoh
di atas).
d. Buka browser, kemudian masuk ke alamat:
https://developers.google.com/android/maps-api-signup
e. Masukkan MD5 fingerprint tadi, kemudian klik ”Generate API Key”.
Untuk sementara simpan API key yang Anda dapatkan untuk digunakan
nanti pada program.
5.2 Project
Buat Project Android baru dengan konfigurasi sebagai Berikut:
• Project name:Petaku
• Build target: Api 7
• Application name: Petaku
• Package name: lab.andro.petaku
• Create Activity: PetakuActivity
• Minimum SDK: 7
52
Android Programming - candra.web.id
5.3 Layout
Setelah Project berhasil dibuat, selanjutnya kita perlu mengubah Layout
aplikasi agar dapat menggunakan Map. Buka layout main.xml, kemudian
ubah menjadi:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="API_KEY"
/>
Kemudian ganti API_KEY dengan API Key yang telah didapatkan pada
bagian 5.1 di atas. Misalnya:
android:apiKey="0zEcmwFgGjgueJd8BWFmQBUy2DEagV6RxjnSQ3w"
5.4 Uses Permission dan Library
Menggunakan Google Map membutuhkan koneksi internet. Sehingga
kita perlu memberikan permission untuk dapat menggunakan INTERNET
untuk aplikasi kita.
Selain Internet, kita juga membutuhkan beberapa Akses permission lainnya yakni ACCESS_COARSE_LOCATION dan
ACCESS_FINE_LOCATION untuk dapat menggunakan GPS.
Buka file AndroidManifest.xml kemudian tambahkan baris berikut diluar
tag application:
<uses-permission android:name=
"android.permission.INTERNET" />
<uses-permission android:name=
"android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name=
"android.permission.ACCESS_FINE_LOCATION" />
Selain itu, kita juga perlu menambahkan akses ke library external untuk
dapat menggunakan MapView. Tambahkan baris berikut di dalam tag
application:
53
Android Programming - candra.web.id
<uses-library android:name="com.google.android.maps" />
Sehingga file AndroidManifest.xml akan menjadi:
✞
1 <?xml version ="1.0" encoding ="utf -8"?>
2 <manifest xmlns:android =" http: // schemas . android .com/apk/res/
android "
3
package ="lab. andro . android . petaku "
4
android:versionCode ="1"
5
android:versionName ="1.0" >
6
7
<uses -sdk android:minSdkVersion ="7" />
8
9
10
11
<uses - permission android:name =" android . permission . INTERNET "
/>
<uses - permission android:name =" android . permission .
ACCESS_COARSE_LOCATION " />
<uses - permission android:name =" android . permission .
ACCESS_FINE_LOCATION " />
12
13
14
15
16
17
18
19
20
<application
android:icon =" @drawable / ic_launcher "
android:label =" @string / app_name " >
<activity
android:name =". PetakuActivity "
android:label =" @string / app_name " >
<intent - filter >
<action android:name =" android . intent . action .MAIN
" />
21
22
23
24
<category android:name =" android . intent . category .
LAUNCHER " />
</intent - filter >
</ activity >
25
26
27
<uses - library android:name ="com. google . android .maps" />
</ application >
28
29
</ manifest >
✝
AndroidManifest.xml
5.5 Activity dan Running
Selanjutnya kita perlu mengubah Activity PetakuActivity untuk dapat
menggunakan MapView pada aplikasi. Buka Activity PetakuActivity kemudian lakukan perubahan berikut:
54
✆
Android Programming - candra.web.id
a. Tambahkan baris import berikut untuk mengimport MapActivity:
import com.google.android.maps.MapActivity;
b. Ubah activity yang tadinya merupakan turunan dari kelas Activity menjadi MapActivity:
...
public class PetakuActivity extends MapActivity {
...
c. Implement semua methode yang belum di implementasikan dari kelas
MapActivity (seharusnya hanay satu methode saja):
...
@Override
protected boolean isRouteDisplayed() {
return false;
}
...
d. Sehingga Activity menjadi:
1
✞
package lab. andro . android . petaku ;
2
3
4
import android .os. Bundle ;
import com. google . android .maps. MapActivity ;
5
6
7
8
9
10
11
12
public class PetakuActivity extends MapActivity {
/** Called when the activity is first created . */
@Override
public void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
setContentView (R. layout .main);
}
13
14
15
16
17
18
19
}
✝
@Override
protected boolean isRouteDisplayed () {
// TODO Auto - generated method stub
return false;
}
Activity: PetakuActivity
55
✆
Android Programming - candra.web.id
e. Selanjutnya coba run program untuk mencoba apakah Map berhasil di
load dengan baik atau tidak. Contoh hasil Run programnya yakni:
Gambar 5.2: Petaku
5.6 Location API
Untuk dapat menggunakan Location API agar kita dapat mengakses Lokasi,
ada beberapa hal yang perlu kita tambahkan dalam program, yakni:
a. Implements LocationListener pada kelas/activity PetakuActivity.
...
public class PetakuActivity extends MapActivity
implements LocationListener {
...
b. Implementasikan semua methode yang belum diimplementasikan dari kelas LocationListener (Biarkan methode-methode tersebut kososng terlebih dahulu):
56
Android Programming - candra.web.id
...
public void onLocationChanged(Location arg0) {
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider,
int status, Bundle extras) {
}
...
c. Tambahkan beberapa property berikut:
...
private
private
private
private
...
LocationManager locationManager;
MapView petaView;
MyLocationOverlay myLocationOverlay;
String provider;
d. Pada methode onCreate, tambahkan beberapa baris berikut untuk
menginisialisasi Lokasi:
...
locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria,
false);
Location location = locationManager
.getLastKnownLocation(provider);
57
Android Programming - candra.web.id
...
if(location == null) {
Toast.makeText(this,
"Lokasi tidak diperoleh",
Toast.LENGTH_LONG).show();
}
e. Setelah itu tambahkan baris berikut setelah inisialisasi Lokasi, untuk mengontrol Map dan menambahkan overlay:
...
...
petaView = (MapView) findViewById(R.id.mapview);
petaView.displayZoomControls(true);
petaView.setBuiltInZoomControls(true);
petaView.getController().setZoom(10);
myLocationOverlay = new MyLocationOverlay(this,
petaView);
myLocationOverlay.enableCompass();
petaView.getOverlays().add(myLocationOverlay);
myLocationOverlay.runOnFirstFix(new Runnable() {
public void run() {
petaView.getController().animateTo(
myLocationOverlay.getMyLocation());
}
});
f. Pada methode onLocationChanged, tambahkan baris berikut agar setiap
kali lokasi berubah, maka peta akan secara otomatis mengarah ke lokasi
tersebut:
petaView.getController().animateTo(
myLocationOverlay.getMyLocation());
g. Optional: Overide methode onResume dan onPause:
...
@Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider,
58
Android Programming - candra.web.id
}
400, 1, this);
myLocationOverlay.enableCompass();
myLocationOverlay.enableMyLocation();
@Override
protected void onPause() {
locationManager.removeUpdates(this);
myLocationOverlay.disableCompass();
myLocationOverlay.disableMyLocation();
super.onPause();
}
...
h. Source lengkap untuk Activity PetakuActivity:
✞
1 package lab. andro . android . petaku ;
2
3
4
5
6
7
8
9
import
import
import
import
import
import
import
android . content . Context ;
android . location . Criteria ;
android . location . Location ;
android . location . LocationListener ;
android . location . LocationManager ;
android .os. Bundle ;
android . widget . Toast ;
10
11
12
13
import com. google . android .maps. MapActivity ;
import com. google . android .maps. MapView ;
import com. google . android .maps. MyLocationOverlay ;
14
15
16
17
18
19
public class PetakuActivity extends MapActivity implements
LocationListener {
private LocationManager locationManager ;
private MapView petaView ;
private MyLocationOverlay myLocationOverlay ;
private String provider ;
20
21
22
23
24
@Override
public void onCreate ( Bundle savedInstanceState ) {
super. onCreate ( savedInstanceState );
setContentView (R. layout .main);
25
26
27
locationManager = ( LocationManager )
getSystemService ( Context . LOCATION_SERVICE );
28
29
Criteria criteria = new Criteria ();
59
Android Programming - candra.web.id
provider = locationManager . getBestProvider (criteria , false
);
Location location = locationManager . getLastKnownLocation (
provider );
30
31
32
if( location == null) {
Toast . makeText (this ,
" Lokasi tidak diperoleh ",
Toast . LENGTH_LONG ).show ();
}
33
34
35
36
37
38
petaView = ( MapView ) findViewById (R.id. mapview );
petaView . displayZoomControls (true);
petaView . setBuiltInZoomControls (true);
39
40
41
42
petaView . getController (). setZoom (10);
43
44
45
46
47
48
49
50
51
52
53
}
54
myLocationOverlay = new MyLocationOverlay (this ,
petaView );
myLocationOverlay . enableCompass ();
petaView . getOverlays ().add( myLocationOverlay );
myLocationOverlay . runOnFirstFix (new Runnable () {
public void run () {
petaView . getController (). animateTo (
myLocationOverlay . getMyLocation ());
}
});
55
56
57
58
59
@Override
protected boolean isRouteDisplayed () {
return false;
}
60
61
62
63
public void onLocationChanged ( Location arg0) {
petaView . getController (). animateTo (
myLocationOverlay . getMyLocation ());
64
65
}
66
67
public void onProviderDisabled ( String provider ) {
68
69
}
70
71
public void onProviderEnabled ( String provider ) {
72
73
}
74
75
public void onStatusChanged ( String provider , int status ,
60
Android Programming - candra.web.id
Bundle extras ) {
76
}
77
78
@Override
protected void onResume () {
super. onResume ();
locationManager . requestLocationUpdates (provider , 400, 1,
this);
myLocationOverlay . enableCompass ();
myLocationOverlay . enableMyLocation ();
}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
}
✝
@Override
protected void onPause () {
locationManager . removeUpdates (this);
myLocationOverlay . disableCompass ();
myLocationOverlay . disableMyLocation ();
super. onPause ();
}
Activity: PetakuActivity
i. Simpan perubahan dan coba run Program. Berikut adalah contoh hasil
running aplikasi Petaku ini:
Gambar 5.3: Hasil Akhir
61
✆
Interfacing Web Services
62
MODUL
6
Kontak Online
Target
Gambar 6.1: Target
63
Android Programming - candra.web.id
6.1 Overview
Pada modul terakhir ini kita akan mencoba mambuat Aplikasi sederhana
yang melakukan akses ke database server. Idenya mirip seperti Aplikasi
Notepad yang ada pada Android, akan tetapi pada contoh ini data akan
disimpan ke dalam server.
Beberapa hal yang perlu kita siapkan sebelum mebuat aplikasi Androidnya
yakni:
• Database Server (MySQL, PostgreSQL atau lainnya),
• Web Server (Apache, XAMPP atau lainnya) dan
• PHP, untuk membuat aplikasi web servicenya.
6.2 Menyiapkan Server
6.2.1 Database
Siapkan Database sederhana dengan nama ”kontak” yang berisi sebuah tabel
dengan nama ”kontakku”. Beri empat buah field dalam tabel kontakku yakni
id, nama, alamat dan flag (flag untuk memberikan pada tanda).
CREATE TABLE kontakku (
id int(11) NOT NULL AUTO_INCREMENT,
nama varchar(255) NOT NULL,
alamat text NOT NULL,
flag enum('normal','penting') NOT NULL DEFAULT 'normal',
PRIMARY KEY (id)
);
6.2.2 Web Service (PHP + JSON)
Buat sebuah tiga buah file PHP sederhana untuk mengakses database yakni:
• koneksi.php
✞
1
2
3
<?php
$link = mysql_connect ('localhost ', 'root ', 'lupa ');
mysql_select_db (" kontak ");
64
Android Programming - candra.web.id
4
5
6
7
?>
if (! $link) {
die('Could not connect : ' . mysql_error ());
}
✝
koneksi.php
✆
• get-kontak.php
✞
1
<?
2
3
include ('koneksi .php ');
$query =" SELECT * FROM kontakku ";
4
$result = pg_query ( $query ) or die('Query failed : ' .
pg_last_error ());
5
6
7
8
9
10
11
12
?>
$data= array ();
while ($r = pg_fetch_array ($result , null , PGSQL_ASSOC
)) {
$data [] = $r;
}
echo json_encode ($data);
✝
get-kontak.php
• insert-kontak.php
✞
1
2
3
4
5
<?
include ('koneksi .php ');
$nama= $_POST ['nama '];
$alamat = $_POST ['alamat '];
$flag= $_POST ['flag '];
6
7
8
$query =" INSERT INTO kontakku (nama ,alamat ,flag)
VALUES
(' $nama ', '$alamat ', '$flag ')";
9
10
11
12
13
14
$result = pg_query ( $query ) or die('Query failed : ' .
pg_last_error ());
if( $result ) {
echo 1;
} else {
echo 0;
65
✆
Android Programming - candra.web.id
15
16
?>
}
✝
insert-kontak.php
Catatan: Untuk keperluan service Delete dan Update, Anda dapat mengembangkannya sendiri nanti setelah anda dapat membuat sebuah interface untuk masing-masing service yang ada di atas.
6.3 Aplikasi Client Android
6.3.1 Project
Buat project Android dengan konfigurasi sebagai berikut:
• Project name: Kontak Online
• Build target: Api 10 (atau lainnya)
• Application name: Kontak Online
• Package name: lab.andro.android.kontakonline
• Create Activity: KontakOnlineActivity
• Minimum SDK: 10 (sesuaikan dengan build target).
6.3.2 Layout dan Menu
Pada aplikasi ini, kita akan membuat beberapa Layout. Yakni layout utama
yang berisikan ListView, layout item untuk mengganti item dalam list view
dan layout untuk membuat Kontak. Mari kita siapkan satu persatu semua
layout ini.
• Layout Utama (main.xml)
✞
1
2
3
4
5
<?xml version ="1.0" encoding ="utf -8"?>
<LinearLayout xmlns:android =" http: // schemas . android .
com/apk/res/ android "
android:layout_width =" fill_parent "
android:layout_height =" fill_parent "
android:orientation =" vertical ">
66
✆
Android Programming - candra.web.id
6
7
8
9
10
11
<ListView
android:id =" @android:id /list"
android:layout_width =" match_parent "
android:layout_height =" wrap_content " >
</ ListView >
</ LinearLayout >
✝
✆
main.xml
Catatan: Property android:id pada widget ListView harus berisi
"@android:id/list".
• Layout untuk item
(item_kontak.xml)
dalam
List
View
pada
main.xml
✞
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version ="1.0" encoding ="utf -8"?>
<LinearLayout xmlns:android =" http: // schemas . android .
com/apk/res/ android "
android:layout_width =" match_parent "
android:layout_height =" match_parent "
android:orientation =" vertical " >
<RelativeLayout
android:layout_width =" match_parent "
android:layout_height =" wrap_content " >
<TextView
android:id ="@+id/ textNama "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentLeft ="true"
android:layout_alignParentTop ="true"
android:text ="Large Text"
android:textAppearance ="? android:attr /
textAppearanceLarge " />
<ImageView
android:id ="@+id/ imageFlag "
android:layout_alignParentRight ="true"
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentTop ="true"
android:src =" @android:drawable / star_big_on
" />
</ RelativeLayout >
</ LinearLayout >
✝
item_kontak.xml
67
✆
Android Programming - candra.web.id
• Layout untuk membuat Kontak (kontak_baru.xml)
✞
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?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:orientation =" vertical " >
<TextView
android:id ="@+id/ textView1 "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentTop ="true"
android:layout_alignParentRight ="true"
android:layout_alignParentLeft ="true"
android:text =" Nama: "
android:textAppearance ="? android:attr /
textAppearanceMedium " />
<EditText
android:id ="@+id/ editTextNama "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:singleLine ="true"
android:layout_alignParentRight ="true"
android:layout_alignParentLeft ="true"
android:layout_below ="@+id/ textView1 "
android:ems ="10" >
<requestFocus />
</ EditText >
<TextView
android:id ="@+id/ textView2 "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:text =" Alamat: "
android:layout_alignParentRight ="true"
android:layout_alignParentLeft ="true"
android:layout_below ="@+id/ editTextNama "
android:textAppearance ="? android:attr /
textAppearanceMedium " />
<EditText
android:id ="@+id/ editTextAlamat "
android:layout_width =" match_parent "
android:layout_height =" wrap_content "
android:layout_above ="@+id/ checkBoxPenting "
68
Android Programming - candra.web.id
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
android:layout_alignParentLeft ="true"
android:layout_alignParentRight ="true"
android:layout_below ="@+id/ textView2 "
android:gravity ="top"
android:autoText ="false "
android:ems ="10" />
<CheckBox
android:id ="@+id/ checkBoxPenting "
android:layout_width =" wrap_content "
android:layout_height =" wrap_content "
android:layout_alignParentRight ="true"
android:layout_alignParentLeft ="true"
android:layout_alignParentBottom ="true"
android:text =" Penting " />
</ RelativeLayout >
✝
kontak_baru.xml
Dan kita juga membutuhkan dua buah file XML lagi untuk membuat menu.
Cara pembuatan menu ini sama seperti pembuatan Layout baru, akan tetapi
pilih Resource Type-nya menjadi Menu. Berikut beberapa menu yang
perlu dibuat:
• Menu utama (menu_utama.xml) untuk menu pada Activity utama:
✞
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version ="1.0" encoding ="utf -8"?>
<menu xmlns:android =" http: // schemas . android .com/apk/
res/ android " >
<item
android:id ="@+id/ menuKontakBaru "
android:icon =" @android:drawable / ic_menu_add "
android:title =" Tambah Kontak ">
</item >
<item
android:id ="@+id/ menuAbout "
android:icon =" @android:drawable / ic_menu_help "
android:title =" About ">
</item >
<item
android:id ="@+id/ menuRefresh "
android:icon =" @android:drawable / ic_menu_rotate
"
android:title =" Refresh ">
</item >
69
✆
Android Programming - candra.web.id
18
</menu >
✝
menu_utama.xml
✆
• Menu simpan (menu_simpan.xml) untuk menu pada Activity
BuatKontakBaru:
✞
1
2
3
4
5
6
7
8
<?xml version ="1.0" encoding ="utf -8"?>
<menu xmlns:android =" http: // schemas . android .com/apk/
res/ android " >
<item
android:id ="@+id/ menuSimpan "
android:icon =" @android:drawable / ic_menu_save "
android:title =" Simpan ">
</item >
</menu >
✝
menu_simpan.xml
6.3.3 Program
Setelah layout selesai dibuat, selanjutnya kita perlu menambahkan kode ke
dalam program. Ada beberapa hal yang perlu kita tambahkan ke dalam
program selain Activity utama yang telah di buat pada saat pembuatan
Project yakni: kelas CustomHTTPClient untuk memudahkan akses HTTP
(Socket Programming –Topik Advance), kelas Kontak dan dua buah Activity lain yakni KontakBaruActivity dan BacaKontakActivity. Mari kita
tambahkan satu-persatu.
HTTP Client (CustomHTTPClient.java)
Buat sebuah kelas baru pada package lab.andro.android.kontakonline
dengan nama CustomHTTPClient kemudian isi dengan koe-kode beikut:
✞
1
package lab.andro. android . kontakonline ;
2
3
4
5
6
7
import
import
import
import
import
java.io. BufferedReader ;
java.io. IOException ;
java.io. InputStreamReader ;
java.net.URI;
java.util. ArrayList ;
8
9
import org. apache .http. HttpResponse ;
70
✆
Android Programming - candra.web.id
10
11
12
13
14
15
16
17
18
import
import
import
import
import
import
import
import
import
org. apache .http. client . HttpClient ;
org. apache .http. client . entity . UrlEncodedFormEntity ;
org. apache .http. client . methods . HttpGet ;
org. apache .http. client . methods . HttpPost ;
org. apache .http.conn. params . ConnManagerParams ;
org. apache .http.impl. client . DefaultHttpClient ;
org. apache .http. params . HttpConnectionParams ;
org. apache .http. params . HttpParams ;
org. apache .http. params . HttpProtocolParams ;
19
20
21
22
public class CustomHTTPClient {
public static final int HTTP_TIMEOUT = 30 * 1000;
private static HttpClient mHttpClient ;
23
24
25
26
27
28
29
30
31
32
33
34
private static HttpClient getHttpClient () {
if ( mHttpClient == null) {
mHttpClient = new DefaultHttpClient ();
final HttpParams params = mHttpClient . getParams ();
HttpConnectionParams . setConnectionTimeout (params ,
HTTP_TIMEOUT );
HttpConnectionParams . setSoTimeout (params ,
HTTP_TIMEOUT );
HttpProtocolParams . setUseExpectContinue ( mHttpClient .
getParams (), false );
ConnManagerParams . setTimeout (params , HTTP_TIMEOUT );
}
return mHttpClient ;
}
35
36
37
38
39
40
41
42
43
44
45
@SuppressWarnings ({ " unchecked ", " rawtypes " })
public static String executeHttpPost ( String url , ArrayList
postParameters ) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient ();
HttpPost request = new HttpPost (url);
UrlEncodedFormEntity formEntity = new
UrlEncodedFormEntity ( postParameters );
request . setEntity ( formEntity );
HttpResponse response = client . execute ( request );
in = new BufferedReader (new InputStreamReader (
response . getEntity (). getContent ()));
46
71
Android Programming - candra.web.id
StringBuffer sb = new StringBuffer ("");
String line = "";
String NL = System . getProperty ("line. separator ");
while (( line = in. readLine ()) != null) {
sb. append (line + NL);
}
in.close ();
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
}
String result = sb. toString ();
return result ;
} finally {
if (in != null) {
try {
in.close ();
} catch ( IOException e) {
e. printStackTrace ();
}
}
}
67
68
69
70
71
72
73
74
75
public static String executeHttpGet ( String url) throws
Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient ();
HttpGet request = new HttpGet ();
request . setURI (new URI(url));
HttpResponse response = client . execute ( request );
in = new BufferedReader (new InputStreamReader (
response . getEntity (). getContent ()));
76
77
78
79
80
81
82
83
StringBuffer sb = new StringBuffer ("");
String line = "";
String NL = System . getProperty ("line. separator ");
while (( line = in. readLine ()) != null) {
sb. append (line + NL);
}
in.close ();
84
85
86
87
String result = sb. toString ();
return result ;
} finally {
72
Android Programming - candra.web.id
88
89
90
91
92
93
94
95
96
97
}
}
}
if (in != null) {
try {
in.close ();
} catch ( IOException e) {
e. printStackTrace ();
}
}
✝
Kelas CustomHTTPClient
Kelas Kontak
Buat kelas baru dengan nama Kontak dengan mengimplementasikan interface android.os.Parcelable.
✞
1
package lab.andro. android . kontakonline ;
2
3
4
import android .os. Parcel ;
import android .os. Parcelable ;
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Kontak implements Parcelable {
private String id;
private String nama;
private String alamat ;
private String flag;
public Kontak ( String id , String nama , String alamat ,
String flag) {
super ();
this.id = id;
this.nama = nama;
this. alamat = alamat ;
this.flag = flag;
}
public Kontak () {
super ();
this.id = "";
this.nama = "";
this. alamat = "";
this.flag = " normal ";
}
public Kontak ( Parcel s) {
73
✆
Android Programming - candra.web.id
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
this.id = s. readString ();
this.nama = s. readString ();
this. alamat = s. readString ();
this.flag = s. readString ();
}
public String getId () {
return id;
}
public void setId( String id) {
this.id = id;
}
public String getNama () {
return nama;
}
public void setNama ( String nama) {
this.nama = nama;
}
public String getAlamat () {
return alamat ;
}
public void setAlamat ( String isi) {
this. alamat = isi;
}
public int describeContents () {
return 0;
}
public String getFlag () {
return flag;
}
public void setFlag ( String flag) {
this.flag = flag;
}
public void writeToParcel ( Parcel dest , int flags) {
dest. writeString (id);
dest. writeString (nama);
dest. writeString ( alamat );
dest. writeString (flag);
}
public static Parcelable .Creator <Kontak > CREATOR
= new Parcelable .Creator <Kontak >() {
public Kontak createFromParcel ( Parcel source ) {
return new Kontak ( source );
}
74
Android Programming - candra.web.id
69
70
71
72
73
}
};
public Kontak [] newArray (int size) {
return new Kontak [size ];
}
✝
Kelas Kontak
✆
Activity dan JSON Parser
Sebelum membuat semua Activity yang lainnya, buatlah sebuah Interface
baru dengan nama KontakOnline sebagai berikut:
✞
1
package lab.andro. android . kontakonline ;
2
3
4
5
6
7
public interface KontakOnline {
String SERVER_ADDR = "http ://10.0.2.2/ kontak - online /";
String GET_KONTAK = SERVER_ADDR + "get - kontak .php";
String INSERT_KONTAK = SERVER_ADDR + "insert - kontak .php";
}
✝
Interface KontakOnline
✆
Catatan: Alamat http://10.0.2.2 adalah alamat untuk server lokal (PC
development). Untuk server yang telah dihostingkan, ganti String
SERVER_ADDR dengan alamat yang menuju tempat file get-kontak.php
tersimpan.
Selanjutnya Kita perlu mengubah Activity KontakOnlineActivity
dan menambahkan dua Activity baru lainnya yakni Activity
KontakBaruActivity dan BacaKontakActivity. Mari kita bahas satu
persatu:
a. Activity KontakOnlineActivity
• Ubah Activity ini menjadi ListActivity dengan mengganti superclass-nya yang tadinya dari kelas Activity menjadi ListActivity
agar dapat lebih mudah memproses ListView. Kemudian implementasikan interface KontakOnline pada kelas ini.
...
public class KontakOnlineActivity extends ListActivity implements
KontakOnline {
..
75
Android Programming - candra.web.id
• Tambahkan beberapa Property sebagai berikut:
...
private
private
private
private
...
List<Kontak> kontak = new ArrayList<Kontak>();
final static int ACT_KONTAK_BARU = 0;
ProgressDialog pd;
KontakAdapter adapter;
• Buat tiga buah internal kelas bari di dalam kelas/Activity ini.
Masing-masing sebagai berikut:
Kelas ViewHolder
...
static class ViewHolder {
TextView textNama;
ImageView imageFlag;
}
...
Kelas KontakAdapter
...
private static class KontakAdapter extends BaseAdapter {
private LayoutInflater lInflater;
@SuppressWarnings("unused")
private Context context;
private List<Kontak> kontak;
public KontakAdapter(Context ctx, List<Kontak> ctt) {
lInflater = LayoutInflater.from(ctx);
this.context = ctx;
this.kontak = ctt;
}
public int getCount() {
return kontak.size();
}
public Object getItem(int position) {
return kontak.get(position);
}
public long getItemId(int position) {
76
Android Programming - candra.web.id
}
return position;
public View getView(int position, View convertView,
ViewGroup parent) {
final ViewHolder holder;
if(convertView == null) {
convertView = lInflater.inflate(R.layout.item_kontak, null);
holder = new ViewHolder();
holder.textNama = (TextView)
convertView.findViewById(R.id.textNama);
holder.imageFlag = (ImageView)
convertView.findViewById(R.id.imageFlag);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
}
holder.textNama.setText(kontak.get(position).getNama());
if(kontak.get(position).getFlag().contains("penting")) {
holder.imageFlag.setImageResource(
android.R.drawable.star_big_on);
} else {
holder.imageFlag.setImageResource(
android.R.drawable.star_big_off);
}
return convertView;
}
...
Kelas DataHandler
...
class DataHandler extends Handler {
public void handleMessage(Message msg) {
boolean aman = msg.getData().getBoolean("stat");
pd.dismiss();
if (aman) {
ArrayList<Kontak> lst = msg.getData()
.getParcelableArrayList("data");
77
Android Programming - candra.web.id
}
...
}
if(!lst.isEmpty()) {
kontak = lst;
fillData();
} else {
Toast.makeText(KontakOnlineActivity.this,
"Data Kosong", Toast.LENGTH_LONG)
.show();
}
} else {
Toast.makeText(KontakOnlineActivity.this,
"Data tidak dapat ditampilkan",
Toast.LENGTH_LONG).show();
}
dan Kelas GetDataThread
...
class GetDataThread extends Thread {
Handler mHandler;
public GetDataThread(Handler mHandler) {
super();
this.mHandler = mHandler;
}
@Override
public void run() {
String res = null;
ArrayList<Kontak> listkontak =
new ArrayList<Kontak>();
try {
res = CustomHTTPClient.executeHttpGet(GET_KONTAK);
Log.d("RESULT", res);
if (res == null) {
return;
}
// Parsing JSON ke Objek
JSONArray jsa = new JSONArray(res);
int i = 0;
78
Android Programming - candra.web.id
while (!jsa.isNull(i)) {
Kontak c = new Kontak();
c.setId(jsa.getJSONObject(i)
.getString("id").trim());
c.setNama(jsa.getJSONObject(i)
.getString("nama").trim());
c.setAlamat(jsa.getJSONObject(i)
.getString("alamat"));
c.setFlag(jsa.getJSONObject(i)
.getString("flag").trim());
listkontak.add(c);
i++;
}
} catch (Exception e) {
Log.d("LOG", e.getMessage());
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putBoolean("stat", false);
msg.setData(b);
mHandler.sendMessage(msg);
return;
}
}
...
}
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
if(listkontak.isEmpty()) {
b.putBoolean("stat", false);
} else {
b.putBoolean("stat", true);
b.putParcelableArrayList("data", listkontak);
}
msg.setData(b);
mHandler.sendMessage(msg);
• Buat methode fillData() yang dipanggil dalam kelas DataHandler
yang telah dibuat di atas:
...
79
Android Programming - candra.web.id
private void fillData() {
adapter = new KontakAdapter(this,kontak);
setListAdapter(adapter);
}
...
• Implementasikan menu serta handlernya:
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_utama, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menuKontakBaru:
kontakBaru();
break;
case R.id.menuAbout:
showAbout();
break;
case R.id.menuRefresh:
getData();
break;
}
default:
break;
}
return super.onOptionsItemSelected(item);
private void showAbout() {
AlertDialog.Builder ab = new AlertDialog.Builder(this);
ab.setTitle("About");
ab.setMessage("Contoh aplikasi untuk Interfacing Web Services");
ab.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
80
Android Programming - candra.web.id
dialog.dismiss();
}
});
ab.setIcon(android.R.drawable.ic_dialog_info);
}
AlertDialog a = ab.create();
a.show();
private void kontakBaru() {
Intent i = new Intent(this, KontakBaruActivity.class);
startActivityForResult(i, ACT_KONTAK_BARU);
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
switch (requestCode) {
case ACT_KONTAK_BARU:
if (resultCode == RESULT_OK) {
getData();
}
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
...
• Buat methode getData() untuk menjalankan Thread yang bertugas
untuk mengambil data ke server:
...
private void getData() {
pd = ProgressDialog.show(this, "Sedang di Proses",
"Mengambil data dari server...", true, false);
DataHandler handler = new DataHandler();
GetDataThread td = new GetDataThread(handler);
td.start();
}
...
81
Android Programming - candra.web.id
• Implementasikan Methode untuk menghandle event Klik pada
item yang ada dalam ListView dengan meng-Override methode
onListItemClick:
...
@Override
protected void onListItemClick(ListView l, View v, int position,
long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, BacaKontakActivity.class);
i.putExtra("kontak", kontak.get(position));
startActivity(i);
}
...
• dan yang terakhir, panggil methode getData() melalui methode
onCreate
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.getData();
}
...
• Sehingga kelas ini akan menjadi seperti berikut:
✞
1
package lab.andro. android . kontakonline ;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.util. ArrayList ;
java.util.List;
lab.andro. android . kontakonline .R;
org.json. JSONArray ;
android .app. AlertDialog ;
android .app. AlertDialog . Builder ;
android .app. ListActivity ;
android .app. ProgressDialog ;
android . content . Context ;
android . content . DialogInterface ;
android . content . Intent ;
android . graphics . drawable . Drawable ;
android .os. Bundle ;
android .os. Handler ;
82
Android Programming - candra.web.id
17
18
19
20
21
22
23
24
25
26
27
28
29
import
import
import
import
import
import
import
import
import
import
import
import
import
android .os. Message ;
android .util.Log;
android .view. LayoutInflater ;
android .view.Menu;
android .view. MenuInflater ;
android .view. MenuItem ;
android .view.View;
android .view. ViewGroup ;
android . widget . BaseAdapter ;
android . widget . ImageView ;
android . widget . ListView ;
android . widget . TextView ;
android . widget .Toast;
30
31
32
33
34
35
36
public class KontakOnlineActivity extends
ListActivity implements
KontakOnline {
private List <Kontak > kontak = new ArrayList <Kontak
>();
private final static int ACT_KONTAK_BARU = 0;
private ProgressDialog pd;
private kontakAdapter adapter ;
37
38
39
40
41
42
43
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout .main);
this. getData ();
}
44
45
46
47
48
49
50
51
private void getData () {
pd = ProgressDialog .show(this , " Sedang di Proses "
,
" Mengambil data dari server ...", true , false )
;
DataHandler handler = new DataHandler ();
GetDataThread td = new GetDataThread ( handler );
td.start ();
}
52
53
54
55
private void fillData () {
adapter = new kontakAdapter (this , kontak );
setListAdapter ( adapter );
83
Android Programming - candra.web.id
56
}
57
58
59
60
61
62
63
64
@Override
protected void onListItemClick ( ListView l, View v,
int position , long id) {
super . onListItemClick (l, v, position , id);
Intent i = new Intent (this , BacaKontakActivity .
class );
i. putExtra (" kontak ", kontak .get( position ));
startActivity (i);
}
65
66
67
68
69
70
71
@Override
public boolean onCreateOptionsMenu (Menu menu) {
MenuInflater inflater = getMenuInflater ();
inflater . inflate (R.menu.menu_utama , menu);
return super . onCreateOptionsMenu (menu);
}
72
73
74
75
76
77
78
79
80
81
82
83
84
@Override
public boolean onOptionsItemSelected ( MenuItem item)
{
switch (item. getItemId ()) {
case R.id. menuKontakBaru :
kontakBaru ();
break ;
case R.id. menuAbout :
showAbout ();
break ;
case R.id. menuRefresh :
getData ();
break ;
85
86
87
88
89
90
}
default :
break ;
}
return super . onOptionsItemSelected (item);
91
92
93
94
private void showAbout () {
AlertDialog . Builder ab = new AlertDialog . Builder (
this);
ab. setTitle (" About ");
84
Android Programming - candra.web.id
ab. setMessage (" Contoh aplikasi untuk Interfacing
Web Services ");
ab. setPositiveButton ("OK", new DialogInterface .
OnClickListener () {
95
96
97
public void onClick ( DialogInterface dialog , int
which) {
dialog . dismiss ();
}
});
ab. setIcon ( android .R. drawable . ic_dialog_info );
98
99
100
101
102
103
AlertDialog a = ab. create ();
a.show ();
104
105
106
107
}
108
109
110
111
112
private void kontakBaru () {
Intent i = new Intent (this , KontakBaruActivity .
class );
startActivityForResult (i, ACT_KONTAK_BARU );
}
113
114
115
116
117
118
119
120
121
122
123
124
125
126
@Override
protected void onActivityResult (int requestCode ,
int resultCode , Intent data) {
switch ( requestCode ) {
case ACT_KONTAK_BARU :
if ( resultCode == RESULT_OK ) {
getData ();
}
break ;
default :
break ;
}
super . onActivityResult (requestCode , resultCode ,
data);
}
127
128
129
130
class DataHandler extends Handler {
public void handleMessage ( Message msg) {
boolean aman = msg. getData (). getBoolean ("stat")
;
85
Android Programming - candra.web.id
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
}
}
pd. dismiss ();
if (aman) {
ArrayList <Kontak > lst = msg. getData ().
getParcelableArrayList ("data");
if (! lst. isEmpty ()) {
kontak = lst;
fillData ();
} else {
Toast. makeText ( KontakOnlineActivity .this ,
"Data Kosong ", Toast. LENGTH_LONG )
.show ();
}
} else {
Toast. makeText ( KontakOnlineActivity .this ,
"Data tidak dapat ditampilkan ", Toast.
LENGTH_LONG )
.show ();
}
149
150
151
class GetDataThread extends Thread {
Handler mHandler ;
152
153
154
155
156
public GetDataThread ( Handler mHandler ) {
super ();
this. mHandler = mHandler ;
}
157
158
159
160
161
162
163
164
165
166
167
168
169
@Override
public void run () {
String res = null;
ArrayList <Kontak > listkontak = new ArrayList <
Kontak >();
try {
res = CustomHTTPClient . executeHttpGet (
GET_KONTAK );
Log.d(" RESULT ", res);
if (res == null) {
return ;
}
// Parsing JSON ke Objek
JSONArray jsa = new JSONArray (res);
86
Android Programming - candra.web.id
int i = 0;
while (! jsa. isNull (i)) {
Kontak c = new Kontak ();
c.setId(jsa. getJSONObject (i). getString ("id"
).trim ());
c. setNama (jsa. getJSONObject (i). getString ("
nama").trim ());
c. setAlamat (jsa. getJSONObject (i). getString (
" alamat "));
c. setFlag (jsa. getJSONObject (i). getString ("
flag").trim ());
listkontak .add(c);
i++;
}
170
171
172
173
174
175
176
177
178
179
180
} catch ( Exception e) {
Log.d("LOG", e. getMessage ());
Message msg = mHandler . obtainMessage ();
Bundle b = new Bundle ();
b. putBoolean ("stat", false );
msg. setData (b);
mHandler . sendMessage (msg);
return ;
}
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
}
}
Message msg = mHandler . obtainMessage ();
Bundle b = new Bundle ();
if( listkontak . isEmpty ()) {
b. putBoolean ("stat", false );
} else {
b. putBoolean ("stat", true);
b. putParcelableArrayList ("data", listkontak );
}
msg. setData (b);
mHandler . sendMessage (msg);
203
204
205
206
207
private static class kontakAdapter extends
BaseAdapter {
private LayoutInflater lInflater ;
@SuppressWarnings (" unused ")
private Context context ;
87
Android Programming - candra.web.id
208
private List <Kontak > kontak ;
209
210
211
212
213
214
public kontakAdapter ( Context ctx , List <Kontak >
ctt) {
lInflater = LayoutInflater .from(ctx);
this. context = ctx;
this. kontak = ctt;
}
215
216
217
218
public int getCount () {
return kontak .size ();
}
219
220
221
222
public Object getItem (int position ) {
return kontak .get( position );
}
223
224
225
226
public long getItemId (int position ) {
return position ;
}
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
public View getView (int position , View
convertView ,
ViewGroup parent ) {
final ViewHolder holder ;
if( convertView == null) {
convertView = lInflater . inflate (R. layout .
item_kontak , null);
holder = new ViewHolder ();
holder . textNama = ( TextView )
convertView . findViewById (R.id. textNama );
holder . imageFlag = ( ImageView )
convertView . findViewById (R.id. imageFlag );
convertView . setTag ( holder );
} else {
holder = ( ViewHolder ) convertView . getTag ();
}
242
243
244
245
holder . textNama . setText ( kontak .get( position ).
getNama ());
if( kontak .get( position ). getFlag (). contains ("
penting ")) {
holder . imageFlag . setImageResource ( android .R.
88
Android Programming - candra.web.id
246
247
248
249
}
250
drawable . star_big_on );
} else {
holder . imageFlag . setImageResource ( android .R.
drawable . star_big_off );
}
return convertView ;
251
}
252
253
254
255
256
257
258
}
static class ViewHolder {
TextView textNama ;
ImageView imageFlag ;
}
✝
Kelas KontakOnlineActivity
b. Activity KontakBaruActivity
• Buat kelas baru dengan nama KontakBaruActivity dengan superclass Activity dan interface KontakOnline:
...
public class KontakBaruActivity extends Activity
implements KontakOnline{
...
• Tambahkan beberapa property/objek widget berikut untuk menangani widget pada Layout:
...
private EditText editNama;
private EditText editAlamat;
private CheckBox checkPenting;
...
• Override methode onCreate kemudian set Layout agar menggunakan layout kontak_baru.xml dan link-kan semua objek widget
yang dibuat di atas:
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
89
✆
Android Programming - candra.web.id
setContentView(R.layout.kontak_baru);
...
}
editNama = (EditText) findViewById(R.id.editTextNama);
editAlamat = (EditText) findViewById(R.id.editTextAlamat);
checkPenting = (CheckBox) findViewById(R.id.checkBoxPenting);
• Buat menu pada Activity sekaligus handlingnya:
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_simpan, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menuSimpan:
simpan();
break;
...
}
default:
break;
}
return super.onOptionsItemSelected(item);
• dan buat methode simpan() untuk mengirim data ke server:
...
private void simpan() {
String nama = null;
String alamat = null;
String flag = "normal";
if(editNama.getText().toString().isEmpty()) {
Toast.makeText(this, "Nama tidak boleh Kosong", Toast.LENGTH_LO
return;
}
90
Android Programming - candra.web.id
if(editAlamat.getText().toString().isEmpty()) {
Toast.makeText(this, "Alamat tidak boleh Kosong", Toast.LENGTH_
return;
}
nama = editNama.getText().toString();
alamat = editAlamat.getText().toString();
if(checkPenting.isChecked()) {
flag = "penting";
}
}
...
String res = null;
ArrayList<NameValuePair> postParameters = new ArrayList<NameValueP
postParameters.add(new BasicNameValuePair("nama", nama));
postParameters.add(new BasicNameValuePair("alamat", alamat));
postParameters.add(new BasicNameValuePair("flag", flag));
try {
res = CustomHTTPClient.executeHttpPost(INSERT_KONTAK, postParam
if(res.trim().equals("1")) {
Toast.makeText(this, "Tersimpan", Toast.LENGTH_LONG).show();
finish();
}
} catch (Exception e) {
Toast.makeText(this, "Gagal Menyimpan", Toast.LENGTH_LONG).show
return;
}
• ✞Sehingga kelas/Activity ini akan menjadi:
1
package lab.andro. android . kontakonline ;
2
3
4
5
6
7
8
9
10
11
import
import
import
import
import
import
import
import
import
java.util. ArrayList ;
org. apache .http. NameValuePair ;
org. apache .http. message . BasicNameValuePair ;
lab.andro. android . kontakonline .R;
android .app. Activity ;
android .os. Bundle ;
android .view.Menu;
android .view. MenuInflater ;
android .view. MenuItem ;
91
Android Programming - candra.web.id
12
13
14
import android . widget . CheckBox ;
import android . widget . EditText ;
import android . widget .Toast;
15
16
17
18
19
public class KontakBaruActivity extends Activity
implements KontakOnline {
private EditText editNama ;
private EditText editAlamat ;
private CheckBox checkPenting ;
20
21
22
23
24
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . kontak_baru );
25
editNama = ( EditText ) findViewById (R.id.
editTextNama );
editAlamat = ( EditText ) findViewById (R.id.
editTextAlamat );
checkPenting = ( CheckBox ) findViewById (R.id.
checkBoxPenting );
26
27
28
29
30
}
31
32
33
34
35
36
37
@Override
public boolean onCreateOptionsMenu (Menu menu) {
MenuInflater inflater = getMenuInflater ();
inflater . inflate (R.menu. menu_simpan , menu);
return super . onCreateOptionsMenu (menu);
}
38
39
40
@Override
public boolean onOptionsItemSelected ( MenuItem
item) {
41
42
43
44
45
switch (item. getItemId ()) {
case R.id. menuSimpan :
simpan ();
break ;
46
47
48
49
default :
break ;
}
92
Android Programming - candra.web.id
50
51
}
return super . onOptionsItemSelected (item);
52
53
54
55
56
57
58
59
60
private void simpan () {
String nama = null;
String alamat = null;
String flag = " normal ";
if( editNama . getText (). toString (). isEmpty ()) {
Toast. makeText (this , "Nama tidak boleh Kosong ",
Toast. LENGTH_LONG ).show ();
return ;
}
61
62
63
64
65
66
67
if( editAlamat . getText (). toString (). isEmpty ()) {
Toast. makeText (this , " Alamat tidak boleh Kosong
", Toast. LENGTH_LONG ).show ();
return ;
}
nama = editNama . getText (). toString ();
alamat = editAlamat . getText (). toString ();
68
69
70
71
if( checkPenting . isChecked ()) {
flag = " penting ";
}
72
73
74
75
76
77
78
79
80
81
82
83
84
String res = null;
ArrayList < NameValuePair > postParameters = new
ArrayList < NameValuePair >();
postParameters .add(new BasicNameValuePair ("nama",
nama));
postParameters .add(new BasicNameValuePair (" alamat
", alamat ));
postParameters .add(new BasicNameValuePair ("flag",
flag));
try {
res = CustomHTTPClient . executeHttpPost (
INSERT_KONTAK , postParameters );
if(res.trim (). equals ("1")) {
Toast. makeText (this , " Tersimpan ", Toast.
LENGTH_LONG ).show ();
finish ();
}
} catch ( Exception e) {
93
Android Programming - candra.web.id
85
86
87
88
89
90
}
}
}
✝
// TODO: handle exception
Toast. makeText (this , " Gagal Menyimpan ", Toast.
LENGTH_LONG ).show ();
return ;
Kelas KontakBaruActivity
✆
c. Activity BacaKontakActivity
• Buat kelas baru dengan nama BacaKontakActivity dengan superclass Activity dan interface KontakOnline (interface optional):
...
public class BacaKontakActivity extends Activity
implements KontakOnline {
...
• Tambahkan beberapa property/objek widget berikut untuk menangani widget pada Layout:
...
private EditText editNama;
private EditText editAlamat;
private CheckBox checkPenting;
...
• Override methode onCreate kemudian set Layout agar menggunakan layout kontak_baru.xml, ambill data yang dikirim dari activity KontakOnlineActivity dan link-kan semua objek widget yang
dibuat di atas serta inisialisasi didalam methode ini:
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.kontak_baru);
Kontak k = this.getIntent().getParcelableExtra("kontak");
if(k==null) {
finish();
}
editNama = (EditText) findViewById(R.id.editTextNama);
94
Android Programming - candra.web.id
editAlamat = (EditText) findViewById(R.id.editTextAlamat);
checkPenting = (CheckBox) findViewById(R.id.checkBoxPenting);
...
}
editNama.setText(k.getNama());
editAlamat.setText(k.getAlamat());
if(k.getFlag().trim().equals("penting")) {
checkPenting.setChecked(true);
}
editNama.setFocusable(false);
editAlamat.setFocusable(false);
checkPenting.setEnabled(false);
• ✞Sehingga kelas/Activity ini akan menjadi:
1
package lab.andro. android . kontakonline ;
2
3
4
5
6
7
import
import
import
import
import
lab.andro. android . kontakonline .R;
android .app. Activity ;
android .os. Bundle ;
android . widget . CheckBox ;
android . widget . EditText ;
8
9
10
11
12
public class BacaKontakActivity extends Activity
implements KontakOnline {
private EditText editNama ;
private EditText editAlamat ;
private CheckBox checkPenting ;
13
14
15
16
17
18
19
20
21
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView (R. layout . kontak_baru );
Kontak k = this. getIntent ().
getParcelableExtra (" kontak ");
if(k== null) {
finish ();
}
22
23
24
editNama = ( EditText ) findViewById (R.id.
editTextNama );
editAlamat = ( EditText ) findViewById (R.id.
editTextAlamat );
95
Android Programming - candra.web.id
checkPenting = ( CheckBox ) findViewById (R.id.
checkBoxPenting );
25
26
27
28
29
30
31
32
33
34
35
36
}
}
editNama . setText (k. getNama ());
editAlamat . setText (k. getAlamat ());
if(k. getFlag ().trim (). equals (" penting ")) {
checkPenting . setChecked (true);
}
editNama . setFocusable ( false );
editAlamat . setFocusable ( false );
checkPenting . setEnabled ( false );
✝
Kelas BacaKontakActivity
Sebelum mengakhiri bagian ini, ada baiknya Anda mengecek kembali apakah
semua kelas/Activity telah dibuat. Berikut kelas/Activity yang harus dibuat:
• BacaKontakActivity
• CustomHTTPClient
• Kontak
• KontakBaruActivity
• KontakOnline dan
• KontakOnlineActivity yang didalamnya terdapat kelas internal:
DataHandler, GetDataThread, KontakAdapter dan ViewHolder.
6.3.4 Permission
Setelah semua bagian program dibuat, program dapat di-run langsung. Namun tentunya akan muncul beberapa masalah diantaranya:
• Data idak dapat ditampilkan (Jika data dalam database telah ada).
• Dan, aplikasi akan di ”Force Close” ketika mencoba memilih menu
Tambah Kontak.
96
✆
Android Programming - candra.web.id
Gambar 6.2: Error (kiri data gagal di load dan kanan Force Close)
Dengan pesan error di DDMS untuk force close:
✞
1 05 -02 20 :58:47 .258: E/ AndroidRuntime (388) : android . content .
ActivityNotFoundException: Unable to find explicit
activity class {lab. andro . android . kontakonline /lab. andro
. android . kontakonline . KontakBaruActivity }; have you
declared this activity in your AndroidManifest .xml?
✝
✆
Log error pada DDMS
Masalah pertama bisa terjadi karena dua hal, pertama server belum siap atau
tidak dapat diakses. Kedua dikarenakan permission untuk menggunakan
INTERNET tidak diberikan pada Android Manifest. Maka untuk menyelesaikannya, tambahkan baris berikut pada file AndroidManifest.xml diluar
tag application:
<uses-permission android:name="android.permission.INTERNET" />
Sedangkan untuk masalah yang kedua, ini dikarenakan Activity
KontakBaruActivity masih belum dikenal di dalam manifest. Sehingga
perlu ditambhakan di dalam manifest:
97
Android Programming - candra.web.id
<activity
android:name=".KontakBaruActivity"
android:label="Buat Kontak Baru"
android:theme="@android:style/Theme.Light" >
</activity>
<activity
android:name=".BacaKontakActivity"
android:label="Baca Kontak"
android:theme="@android:style/Theme.Light" >
</activity>
Kedua tag activity tersebut harus dimasukkan di dalam file AndroidManifest.xml di dalam tag application.
✞
<?xml version ="1.0" encoding ="utf -8"?>
2 <manifest xmlns:android =" http: // schemas . android .com/apk/res/
android "
3
package ="lab. andro . android . kontakonline "
4
android:versionCode ="1"
5
android:versionName ="1.0" >
6
<uses -sdk android:minSdkVersion ="10" />
7
<uses - permission android:name =" android . permission . INTERNET "
/>
1
8
9
10
11
12
13
14
15
16
17
<application
android:icon =" @drawable / ic_launcher "
android:label =" @string / app_name "
android:theme =" @android:style / Theme .Light " >
<activity
android:name =". KontakOnlineActivity "
android:label =" @string / app_name " >
<intent - filter >
<action android:name =" android . intent . action .MAIN
" />
18
19
20
21
22
23
24
25
26
27
28
29
<category android:name =" android . intent . category .
LAUNCHER " />
</intent - filter >
</ activity >
<activity
android:name =". KontakBaruActivity "
android:label ="Buat Kontak Baru"
android:theme =" @android:style / Theme .Light" >
</ activity >
<activity
android:name =". BacaKontakActivity "
android:label ="Baca Kontak "
98
Android Programming - candra.web.id
android:theme =" @android:style / Theme .Light" >
</ activity >
32
</ application >
33 </ manifest >
✝
30
31
Isi AndroidManifest.xml
6.4 Running
Langkah terakhir adalah mencoba running program. Jalankan web server
dan MySQL Server terlebih dahulu. Kemudian coba run program Android
yang telah dibuat di atas.
Gambar 6.3: Contoh hasil akhir: Tampilan Utama
99
✆
Android Programming - candra.web.id
Gambar 6.4: Contoh hasil akhir (kiri Baca Kontak dan kanan Buat kontak)
100
Bibliography
[1] Wikibook LATEX
http://en.wikibooks.org/wiki/LaTeX
[2] Developer Android
http://developer.android.com/index.html
[3] Vogella Android
http://www.vogella.com/android.html
[4] Android Hive
http://www.androidhive.info
[5] StackOverflow Android
http://stackoverflow.com/questions/tagged/android
[6] byte[] to Image Android
http://stackoverflow.com/questions/2714700/byte-to-image-android
101