Professional Documents
Culture Documents
DIKTAT KULIAH
KATA PENGANTAR
Dewasa ini, perangkat telepon pintar bukanlah merupakan barang yang mewah lagi, tetapi telah menjadi kebutuhan bagi individu yang terus bergerak, dan ingin tetap terkoneksi dengan berbagai sumber informasi, perkembangan pasar perangkat telepon pintar tentu saja dapat menjadi peluang baru bagi para pengembang aplikasi untuk bagaimana mengembangkan perangkat lunak yang berjalan pada perangkat tersebut. Salah satu fenomena yang perlu kita cermati dari pasar perangkat telepon pintar adalah perkembangan dari perangkat yang berbasis Android, dan bahkan Android juga berkembang kepada perangkat tablet. Android sendirinya merupakan suatu platform software yang dibangun diatas kernel Linux yang bersifat terbuka dan dikembangkan oleh Open Handset Alliance (OHA). OHA merupakan kolaborasi yang dari operator mobile, pabrikan, pabrikan komponen, dan software provider, serta perusahaan marketing yang dipimpin oleh Google. Diktat kuliah ini kami persiapkan untuk sebagai pengantar kuliah Pemrograman Piranti Bergerak dengan harapan dapat membawa mahasiswa kepada suatu materi kuliah yang up-to-date sesuai dengan arah perkembangan teknologi piranti bergerak dan menangkap peluang yang timbul dari pertumbuhan Android. Medan, 16 November 2011 Penulis
DAFTAR ISI Bagian 1, Pengantar Pemrograman Android................................................................1 Bagian 2, Project Android Anda yang Pertama............................................................8 Bagian 3, Struktur Project Android.............................................................................11 Bagian 4, Pembuatan Resources.................................................................................15 Bagian 5, Linear Layout.............................................................................................20 Bagian 6, Frame, Relative, Table Layout...................................................................24 Bagian 7, Pembuatan Activity....................................................................................28 Bagian 8, Pembuatan Event........................................................................................33 Bagian 9, Mengaktifkan Activity................................................................................37 Bagian 10, Pertukaran Data antar Activity.................................................................40 Bagian 11, Pengaktifan Activity Eksternal.................................................................44 Bagian 12, Mendayagunakan Activity pada Aplikasi Android...................................48 Bagian 13, Broadcast Receiver...................................................................................53 Bagian 14, Database SQLite.......................................................................................57 Bagain 15, Pengolahan Data.......................................................................................62 Bagian 16, Content Provider.......................................................................................66 Bagian 17, Membuat Content Provider......................................................................71 Bagian 18, Membuat Service......................................................................................79 Bagian 19, Lokalisasi Aplikasi...................................................................................82
Sejarah Android
Platform Android merupakan produk dari Open Handset Alliance yang merupakan suatu kelompok organisasi yang berkolaborasi untuk membangun mobile phone yang lebih baik. Kelompok ini dipimpin oleh Google, operator mobile, pabrikan, pabrikan komponen, dan software provider, serta perusahaan marketing. Perangkat Android pertama dipasaran adalah G1 yang dipabrikasi oleh HTC.
SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. SQLite is the most widely deployed SQL database engine in the world. The source code for SQLite is in the public domain.
Arsitektur Android
Arsitektur dari Android terdiri dari 4 lapisan perangkat lunak, dengan lapisan yang paling dasar adalah Linux Kernel yang bertindak sebagai sistim operasi, lapisan yang kedua adalah native library dan Android runtime, native library bertindak sebagai hardware abstraction yang ditulis dengan C/C++ yang disediakan oleh vendor, sedangkan Android runtime lingkungan dimana aplikasi .dex akan dijalankan (terdiri dari library-library dan Dalvik Virtual Machine (DVM)2 yang merupakan Virtual Machine berbasis register3 yang dioptimalkan untuk pemakaian memori yang rendah), lapisan yang ketiga adalah Application Framework yang anda gunakan untuk mengembangkan aplikasi, dan lapisan keempat adalah Applications and Widgets yang merupakan aplikasi yang dapat anda buat ataupun aplikasi yang telah disediakan.
Arsitektur Aplikasi
Android berjalan diatas kernel Linux, dan aplikasi Android ditulis dengan bahasa pemrograman Java, dan dijalankan didalam DVM yang merupakan teknologi open source4, masing-masing aplikasi Android dijalankan didalam suatu instant dari DVM,
2
Berbeda dengan Java Virtual Machine (JVM) yang menggunakan arsitektur berbasis stack, DVM merupakan Virtual Machine dengan arsitektur berbasis register. Bytecode pada DVM berbeda dengan bytecode JVM, dimana file .Class hasil kompilasi dengan Android SDK perlu ditransformasi menjadi Dalvik Executable (.dex) dengan tool dx agar dapat berjalan pada DVM. David Ehringer (2010) menuliskan bahwa arsitektur berbasis register membutuh rata-rata 47% lebih sedikit eksekusi instruktusi virtual machine (VM) dibandingkan dengan berbasis stack, pada sisi lain kode register lebih besar 25% dibandingkankan dengan kode stack sehingga membutuhkan lebih banyak instruksi VM, sehingga secara keseluruhan VM berbasis register membutuhkan rata-rata 32% lebih sedikit waktu berdasarkan hasil benchmark. Android is an open-source software stack for mobile devices, and a corresponding open-source project led by Google. We created Android in response to our own experiences launching mobile apps. We wanted to make sure that there was no central point of failure, so that no industry player can restrict or control the innovations of any other. That's why we created Android, and made its source code open
Pemrograman Piranti Bergerak yang mana menjadi process yang diatur oleh kernel Linux sebagaimana ditunjukan pada Gambar 2.
Aplikasi Android
Suatu aplikasi Android dapat berupa salah satu dari empat komponen yang klasifikasi berikut ini : 1. Activities, merupakan suatu aplikasi yang berfokus pada aktifitas pemakai dan memiliki user interface (UI), suatu activity diaktifkan ketika pemakai mengaktifkan sebuah aplikasi dari home screen atau launcher aplikasi. 2. Services, suatu service berjalan dilatarbelakang dan digunakan untuk kegiatan yang membutuhkan existensi untuk jangka waktu yang lama dan tidak memiliki UI, seperti suatu monitoring jaringan, atau aplikasi pemeriksaan update. 3. Content providers, suatu penyimpan dan penyedia yang bersifiat tetap dan dapat tersedia antar aplikasi, jika aplikasi anda sangat sederhana, anda tidak perlu membuat content provider, jika anda membuat aplikasi yang lebih besar, atau membuat sesuatu data tersedia untuk banyak aktivitas ataupun aplikasi, tentu suatu content provider dibutuhkan. 4. Broadcast dan Intent receivers, suatu aplikasi Android yang menerima message sistem dan melakukan tanggapan respon, seperti menerima suatu pesan teks. Kecuali Content providers, komponen lainnya diaktifkan melalui asynchronus message yang dikenal dengan intent, dan intent dapat memiliki bundle yang mendukung informasi terkait dengan komponen, dan digunakan untuk pertukaran data antar komponen.
Pemrograman Piranti Bergerak Android SDK untuk berbagai platform (Linux, Mac Os, windows) dapat didownload secara gratis pada http://developer.android.com/sdk/index.html
Latihan
Instalasi Komputer untuk Pemrograman Android
1. Instalasi JDK Download dan install JDK dari http://java.sun.com/javase/downloads/index.jsp
2. Instalasi Eclipse Download dan unzip Eclipse dari http://www.eclipse.org/downloads/ direkomendasikan "Eclipse Classic" Lakukan unzip, misalnyua C:\Eclipse 3. Instalasi SDK Starter Package Download dan instalasi SDK Starter Package dari http://developer.android.com/sdk/index.html
Catatan: Jika pada saat instalasi, gagal dengan pesan Java SE JDK tidak ditemukan, maka lakukan klik pada Back dan klik pada Next kembali. Setelah instalasi, maka aktifkan SDK manager untuk mendownload SDK Platform Tools, anda membutuhkan koneksi internet dalam hal ini.
Anda dapat memilih package-package yang ingin diinstall pada bagian Available Package. Catat lokasi instalasi android-sdk misalnya : C:\Program Files\Android\androidsdk (akan digunakan pada langkah 5, dan diketik sebagai C:\PROGRA~1\Android\android-sdk ) Hendra, MT. & Hartono, M.Kom. 6
4. Installing the ADT Plugin untuk Eclipse Aktifkan Eclipse, kemudian pada menu Help, pilih Install New Software
Pada dialog Add Site, ketikan http://dl-ssl.google.com/android/eclipse/ Alternatif: anda dapat mendownload manual pada alamat http://dl.google.com/android/ADT-12.0.0.zip
Pada dialog Add Site, klik Archive, dan browse serta pilih ADT-12.0.0.zip
Isi sebuah nama untuk local update site (misalnya Android Plugin) pada field Name Klik OK. Pada dialog Available Software, pilih checkbox disamping Developer Tools dan klik Next Pada jendela berikutnya, anda akan melihat daftar dari tools yang telah didownload, dan klik Next Baca dan terima license agreements, dan klik Finish Catatan : Jika anda mendapatkan security warning yang mengatakan bahwa authenticity atau validity dari software tidak dapat dilakukan, klik OK Ketika instalasi selesai, restart Eclipse 5. Konfigurasi ADT Plugin Setelah anda berhasil mendownload ADT sebagaimana yang diterangkan diatas, maka langkah berikutnya adalah melakukan modifikasi terhadap ADT preferences pada Eclipse untuk menunjuk pada Android SDK directory. Pada Eclipse, menu Window, pilih Preferences, Pilih Android dari panel sebelah kiri Pada SDK Location pada panel utama, klik Browse... dan tempatkan SDK directory, klik Apply dan Ok.
Pada awal keaktifkan Eclipse akan ditanyakan Workspace yang akan digunakan untuk penyimpanan setting dan file project pengembangan yang akan kita lakukan, jika anda bekerja dengan komputer LAB yang digunakan juga oleh mahasiswa lain, maka kami sarankan untuk membuat sebuah folder dengan Nim Anda pada Drive dimana proses tulis diperbolehkan.
Jika pada New, tidak tersedia pilihan Android Project, maka dapat dipilih Project
Isikan detail dari Project meliputi: 1. Project name : HelloAndroid 2. Build Target: Android 2.2 3. Application name: Hello, Android 4. Package name: com.hendra.helloandroid 5. Create Activity: HelloAndroidActivity 6. Min SDK Version: 8 Catatan: Package name merupakan suatu identitas unique anda dari aplikasi lainnya yang kemungkinan menggunakan Project name yang sama, identitas unique ini sangat penting ketika anda ingin mempublikasi aplikasi anda pada Android Market, anda disarankan untuk menggunakan Package name dengan format penulisan com.namaperusahaananda.namaaplikasi. Build Target dan Min SDK Version menentukan versi minimal Android yang dapat menjalankan aplikasi sehingga Android dan Android Market tahu aplikasi anda berjalan pada perangkat versi apa saja. Dan klik pada OK, sehingga muncul tampilan pada Package Explorer sebagai berikut
10
Otomatis akan ditampilkan emulator dari Android yang menampilkan pesan Hello World, HelloAndroidActivity!
11
Trouble Shooting, jika pada saat Run, muncul pesan kesalahan berikut ini :
[2011-07-10 07:11:06 - Emulator] invalid command-line parameter: Files\Android\androidsdk\tools/emulator-arm.exe. [2011-07-10 07:11:07 - Emulator] Hint: use '@foo' to launch a virtual device named 'foo'. [2011-07-10 07:11:07 - Emulator] please use -help for more information
Ini adalah suatu masalah pada R12 dimana pada lokasi SDK tidak dapat mengandung spasi. Periksa kembali pengetikan ada pada saat mendefinisikan lokasi SDK Android yaitu pada menu Window, Preferences, Android, dan periksa SDK Location Jika berisi C:\Programme Files(x86)\Android\android-sdk dimana pada pengetikan diatas mengandung spasi, sehingga perlu diubah menjadi C:\PROGRA~2\Android\android-sdk. Bagi anda yang menjalankan Windows 32-bit, ubah path ke C:\PROGRA~1\Android\android-sdk.
13
Pemrograman Piranti Bergerak Validity years: 25 First and Lastname: Hendra Soewarno Organizational unit: STMIK Organization: IBBI City or Locality: Medan State or Province:Sumut Country Code XX: ID Kemudian klik next, 4. Isikan lokasi dimana APK akan disimpan (APK modus pelepasan dan sudah ditandatangani secara digital) Ketika suatu aplikasi diupgrade, kunci (file keystore) yang sama diperlukan untuk menandatanganinya untuk memastikan update yang transparant kepada pemakai. File keystore harus disimpan secara aman untuk mencegah kemungkinan pemanfaatan file keystore anda oleh pihak yang tidak berhak dan beresiko terhadap reputasi anda.
Latihan
Buatlah aplikasi Android yang dapat menampilkan pesan Hello World !, dan lakukan proses penandatanganan aplikasi untuk modus pelepasan.
15
Resource (/res)
Merupakan folder dimana kita menempatkan segala sumber daya gambar, deklarasi string dan nilai yang akan digunakan pada aplikasi, pemakaian sumber daya ini dapat dilakukan pada saat pembuatan layout, class java maupun manifest.
Values
Resource values merupakan file XML yang berisi deklarasi nilai untuk array, color, dimensi dan string. Pada proyek HelloWorld, folder /res/value terdapat sebuah file string.xml yang isinya adalah sebagai berikut: Hendra, MT. & Hartono, M.Kom. 16
Pada deklarasi tersebut diatas berarti kita memiliki dua sumber daya string yang bernama hello dan app_name yang masing-masing memiliki nilai Hello World, HelloWorldActivity! dan HelloWorld.
Layout
Resource Layout merupakan rancangan antarmuka Activity pada program Android yang ditulis dalam format XML. Pada proyek HelloWorld, forder /res/layout terdapat file main.xml yang berisi rancangan antarmuka.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>
Berdasarkan XML tersebut diatas dapat dijelaskan bahwa main.xml terdiri dari satu Group View (LinearLayout dengan orientasi vertikal, dan pengaturan ukuran lebar dan tingginya mengisi seluruh ruang parent), kemudian didalam Group View tersebut terdapat sebuah View (TextView dengan ukuran lebar adalah sesuai ukuran lebar parent, dan tingginya sesuai dengan tinggi text pada view tersebut, dan memiliki text dengan menggambil nilai sumber daya resource yang bernama hello (@string/hello))
Adapun penjelasan untuk file HelloWorldActivity.java adalah bahwa setiap Activoty class harus merupakan subclass dari Activity (extends Activity), kemudian perlu dioverride method onCreate dan melakukan pemanggilan terhadap metode onCreate dari super classnya. Metode onCreate merupakan metode yang secara otomatis dipanggil setiap instant dari HelloWorldActivity dibuat. Pada method onCreate akan membuat ContentView berdasarkan layout yang didefinisikan pada /res/layout/main.xml (setContentView(R.layout.main))
AndroidManifest.XML
Merupakan file XML yang berisi informasi mengenai aplikasi Android.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.hendra.helloworld" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".HelloWorldActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
18
Pada manifest ini ditentukan icon Launcher dari aplikasi adalah diambil dari icon yang didefinisikan pada /res/drawable/icon (@drawable/icon), kemudian nama aplikasi akan diambil dari deklarasi app_name yang didefinisikan didalam file /res/values/string.xml. Pada aplikasi ini akan terdapat satu activity yang diberi nama .HelloWorldActivity (sesuai dengan activity yang dengan HelloWordActivity yang didefinisikan pada HelloWorldActivity.java. Activity .HelloWorldActivity ini adalah merupakan aktivitas utama atau dengan kata lain merupakan titik masuk ke aplikasi (android.intent.action.MAIN), dan Activity ini akan ditempatkan pada lokasi Launcher aplikasi (android.intent.category.LAUNCHER) sehingga pemakai dapat mengaktifkan aplikasi.
Catatan:
Atribut package harus bersifat unik sebagaimana Android Marketplace hanya memperbolehkan aplikasi untuk package tertentu sekali saja, sehingga adalah praktek yang baik dengan menggunakan nama domain anda secara terbalik (com.hendra.helloworld) untuk menghindari terjadi benturan dengann developer lain. Nilai @ mengacu pada file sumber daya yang mana mengandung nilai yang sebenarnya, hal ini memudahkan untuk pengaturan sumber daya yang berbeda seperti string, color, icon untuk peralatan yang berbeda. Pada satu aplikasi Android, hanya diperbolehkan satu aktivitas yang memiliki action MAIN dengan kategori LAUNCHER.
Latihan
1. Buatlah aplikasi Android yang menampilkan pesan Hello World ! 2. Lakukan explorasi terhadap struktur project aplikasi tersebut dengan mempelajari masing-masing folder pada proyek. 3. Tuliskan kembali dalam kata-kata anda sendiri struktur suatu program android terkait dengan folder /src, /gen, /res/drawable, /res/layout, /res/values.
4. Tuliskan kembali dalam kata-kata anda fungsi dari AndroidManifest.XML
19
20
Contoh pemakaian:
<TextView android:id="@+id/helloText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor= "@android:color/secondary_text_light" android:text="@string/hello" />
dimana @string/hello mengacu pada resource type string yang memiliki nama variabel hello, dan @android: color/secondary_text_light adalah mengacu pada system resource Android (tidak berada pada package yang sama)
21
Pemrograman Piranti Bergerak Pada contoh diatas penulisan R.id.helloText berarti kita mengacu kepada sumber daya yang memiliki id helloText yang merupakan suatu view yang dideklarasikan pada sumber daya layout, sedangkan R.string.helloHendra mengacu kepada sumber daya string yang memiliki id helloHendra.
Tabel 1, Mengacu kepada resources Android dari XML dan Java
Android Resource res/layout/main.xml res/drawable-hdpi/file.png <string name="helloHendra"> @+id//helloText Reference from XML @layout/main @drawable/file @string/helloHendra @id/helloText Reference from Java R.layout.main R.drawable.file R.string.helloHendra R.id.helloText
String Resource
Sebuah resource string menyediakan teks string untuk aplikasi anda, ada tiga jenis dari resources yang dapat tersedia bagi aplikasi anda yaitu String (XML resource yang menyediakan string tunggal), String Array (XML resource yang menyediakan array dari string)
lokasi file: res/values/filename.xml Syntax: Syntax <?xml version="1.0" encoding="utf8"?> <resources> <string name="string_name"> text_string</string> </resources> <?xml version="1.0" encoding="utf8"?> <resources> <string-array name="array_name"> <item> text_string</item> </string-array> </resources> Contoh <?xml version="1.0" encoding="utf8"?> <resources> <string name="hello"> Hello!</string> </resources> <?xml version="1.0" encoding="utf8"?> <resources> <string-array name="planets_array"> <item>Mercury</item> <item>Venus</item> <item>Earth</item> <item>Mars</item> </string-array> </resources>
22
Anda dapat menggunakan getString, getText untuk mengakses string resource, perbedaannya adalah getText lebih kepada rich text style.
Latihan
1. Buatlah String resource sebagai berikut dan simpan pada file pesan.xml: String name Text string 23
Pemrograman Piranti Bergerak selamat_belajar program_android mata_kuliah Selamat belajar Pemrograman android Di Mata kuliah pemrograman piranti bergerak
2. Tampilkan masing-masing String resource pada TextView. TextView pesan1 pesan2 pesan3 String name selamat_belajar program_android mata_kuliah
3. Tambahkan string resource dengan nama semester yang berisi text string di semester enam, dan kemudian tambahkan TextView pesan3 yang menampilkan string resource semester secara pemrograman Java. 4. Tambahkan Array String yang mendeklarasikan nama-nama hari dalam minggu (Senin, Selasa, Rabu, Kamis, Jumat, Sabtu, Minggu), dan simpan pada file hari.xml. 5. Lakukan pembuatan values resource pada soal 1 dan 4 dengan menggunakan fasilitas pada Resource View.
24
Bagian 5, LinearLayout
Layout merupakan salah satu resource yang digunakan yang mendefinisikan antarmuka suatu activity yang digambarkan di layar. Memahami layout merupakan hal yang penting untuk merancang suatu aplikasi Android yang baik. Secara khususnya layout resource ditempatkan pada folder /res/layout/filename.xml. Referensi terhadap suatu layout resource secara Java adalah R.layout.filename dan secara XML adalah @[package:]layout/filename. Adapun syntax penulisan untuk sebuah layout resource adalah sebagai berikut ini:
<?xml version="1.0" encoding="utf-8"?> <ViewGroup xmlns:android= "http://schemas.android.com/apk/res/android" android:id="@[+][package:]id/resource_name" android:layout_height=["dimension" | "fill_parent" | "wrap_content"] android:layout_width=["dimension" | "fill_parent" | "wrap_content"] [ViewGroup-specific attributes] > <View android:id="@[+][package:]id/resource_name" android:layout_height=["dimension" | "fill_parent" | "wrap_content"] android:layout_width=["dimension" | "fill_parent" | "wrap_content"] [View-specific attributes] > <requestFocus/> </View> <ViewGroup > <View /> </ViewGroup> <include layout="@layout/layout_resource"/> </ViewGroup>
Untuk membantu anda memahami syntax penulisan tersebut diatas, maka akan dijelaskan fungsi dari masing-masing elemen sebagai berikut: <ViewGroup> Merupakan suatu kontainer untuk element view lainnya, atau dengan kata lain didalam suatu ViewGroup dapat ditempatkan element view lainnya baik berupa widget maupun ViewGroup lainnya (nested). Suatu komponen UI tunggal yang umunya disebut dengan suatu widget, suatu object View dapat terdiri dari TextView, Button, 25
<View>
Pemrograman Piranti Bergerak dan CheckBox. <include> Mengikut sertakan suatu layout file kedalam layout ini, pemakaian include digunakan untuk melakukan reuse terhadap layout yang anda.
Contoh:
<?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/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a Button" /> </LinearLayout>
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView.(R.layout.main_activity); }
26
Latihan
1. Buatlah layout resource yang dapat menghasilkan tampil berikut ini dengan menggunakan fasilitas pada Graphical View, bantuan Outline Window dan Properties window (dan buatlah langkah-langkah petunjuk yang dapat digunakan teman anda untuk menghasilkan layout tersebut) Petunjuk :
27
Pemrograman Piranti Bergerak a) Pada Workbench, set konfigurasi ke b) dan lakukan perubahan resolusi menjadi c) Siapkan string resource dan color resource untuk masing-masing text diatas (red = #aa0000, green = #00aa00, blue = #0000aa , yellow = #aaaa00, row one, row two, row three, row four ) d) Gunakan Dua LinearLayout, yaitu dengan orientasi horizontal dan vertikal. e) Pada LinearLayout yang pertama tambah empat TextView, dimana masingmasing properti text dan backgroud diset ke resource (red, green,blue dan yellow), atur juga juga layout_width, layout_height, dan layout_weight. f) Pada LinearLayout yang kedua tambahkan empat TextView, dan set masing-masing Text, kemudian atur ukur textSize menjadi 15pt serta atur juga layout_width, layout_height, dan layout_weight. 2. Buatlah layout resource yang dapat menghasilkan tampilan sebagai berikut, buatlah id untuk masingmasing view, dan fokus pertama pada EditText panjang.
28
Frame Layout
FrameLayout dirancang untuk memblok suatu area pada layar dengan menampilkan satu objek tunggal, jika anda ingin menampilkan lebih dari satu objek, maka objek yang berikutnya akan menimpa objek sebelumnya, untuk meminimalkan hal ini anda dapat mengatur properti android:layout_gravity dari masing-masing objek. Anda dapat juga menentukan gambar background maupun foreground dengan menggunakan properti android:background dan Hendra, MT. & Hartono, M.Kom. 29
Linear Layout
Sebagaimana yang telah dijelaskan sebelumnya bahwa pada linear layout, objek-objek view akan disusun secara vertikal ke bawah ataupun secara horizontal ke samping. Pengaturan ukuran dari masing-masing object child view dapat dilakukan dengan mengatur properti android:layout_width dan android:layout_height ke
match_parent maupun wrap_content, kemudian juga dapat dilakukan pengaturan posisi penempatan dari object view dengan menggunakan properti android:layout_gravity. Kemudian anda dapat juga mengatur ukuran relatif masing-masing object child view didalam Layout dengan menggunakan properti android:layout_weight.
Relative Layout
Sebagaimana dengan namanya, layout ini menempatkan object view childnya relatif satu terhadap lainnya dengan menggunakan ID (@+id/id).
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/a ndroid" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10px"> <TextView android:id="@+id/label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Type here:" /> <EditText android:id="@+id/entry" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/label" /> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/entry" android:layout_marginLeft="10px" android:layout_alignParentRight="true" android:text="OK" /> <Button android:text="Cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/ok" android:layout_toLeftOf="@+id/ok"> </Button> </RelativeLayout>
30
Table Layout
Sesuai dengan namanya, layout ini menempatkan object view pada sel didalam suatu tabel.
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchColumns="1"> <TableRow> <TextView android:layout_column="1" android:text="Open..." android:padding="3dip" /> <TextView android:text="Ctrl-O" android:gravity="right" android:padding="3dip" /> </TableRow> <View android:layout_height="2dip" android:background="#FF909090" />
31
Latihan
Buatlah layout untuk masing-masing jenis dengan hasil tampilan gambar pada Bab ini, kombinasikan pemakaian fasilitas Graphical View, Outline Windows, dan Properties Tab.
32
Membuat Layout
Untuk membuat suatu Activity kita perlu membuat layout yang merupakan rancangan dari user interface dalam bentuk file XML yang ditempatkan didalam folder /res/layout. Sesuatu hal yang perlu diperhatikan adalah penamaan untuk file layout harus menggunakan huruf kecil dan tidak dapat mengandung spasi. Contoh persegi.xml:
33
Adapun koding diatas dapat dijelaskan bahwa pada metode onCreate kita melakukan pemanggilan terhadap metoda onCreate pada super class (jika tidak dilakukan akan terjadi error seperti pada Info Debug), kemudian adalah pemanggilan terhadap setContentView() untuk menentukan resource layout yang akan menjadi UI dari Activity yang kita buat.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.hendra.testdb" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Persegi" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
Catatan: Jika activity anda bersifat self-contained dan tidak memperbolehkan aplikasi lainnya untuk mengaktifkan activity anda, maka anda tidak membutuhkan intent filters, dan hanya ada satu Activity yang memiliki action MAIN dengan kategori LAUNCHER. Pada contoh diatas dapat dijelaskan bahwa didalam aplikasi terdapat satu Activity dengan nama .Persegi (sesuai dengan mana Activity Class yang diawali dengan titik), Activity tersebut merupakan kategori LAUNCHER yang berarti Activity tersebut akan ditempatkan pada system's application launcher (aplikasi dapat diaktifkan secara langsung oleh pemakai). Kemudian Activity tersebut merupakan ACTION_MAIN yang berarti ketika aplikasi diaktifkan oleh pemakai, maka Activity tersebut merupakan titik masuk utama dari aplikasi. Hendra, MT. & Hartono, M.Kom. 34
35
Gambar 1. Siklus hidup suatu Activity Ada tiga kunci loop dimana menarik untuk memantau activity anda: Entire lifetime dari suatu activity terjadi diantara pemanggilan pertama terhadap onCreate(Bundle), sampai kepada panggilan akhir kepada onDestroy(). Suatu activity akan melakukan semua persiapan global pada onCreate(), dan melepas semua resources yang masih ada pada onDestroy(), contohnya misalnya Activity anda membuka database pada onCreate, maka Activity tersebut perlu menutup database pada onDestroy. Visible lifetime dari suatu activity terjadi diantara suatu panggilan kepada onStart() sampai kepada panggilan onStop(), dalam waktu ini pemakai dapat melihat activity pada layar, walaupun dia tidak berada di foreground untuk berinteraksi dengan pemakai. Diantara dua metoda ini anda dapat mengatur sumber daya yang dibutuhkan untuk menampilkan activity kepada pemakai. Sebagai contoh anda dapat mendaftarkan suatu BroardcastReceiver di onStart() untuk memantau perubahan yang mempengaruhi UI anda, dan melakukan unregister pada onStop() ketika user tidak perlu lagi melihat apa yang anda tampilkan. Metode onStart() dan onStop() dapat dipanggil berulang kali, sebagaimana aplikasi menjadi visible dan tersembunyi bagi pemakai. Foreground lifetime dari suatu activity terjadi antara suatu pemanggilan terhadap onResume sampai kepada pemanggilan terhadap onPause(), dan waktu ini activity berada di depan dari semua activity lainnya dan berinteraksi dengna pemakai. 36
Pemrograman Piranti Bergerak Suatu activity dapat berulang kali melalui resume dan pause state sebagai contoh ketika device dalam kondisi sleep, ketika suatu hasil activity disampaikan, ketika suatu intent baru disampaikan sehingga kode yang berada pada metode ini harus cukup ringan. Anda dapat melakukan hook terhadap callback dari masing-masing tahapan siklus hidup dengan melakukan Override pada pada metode yang bersesuaian. Semua activity perlu mengimplementasikan onCreate(Bundle) untuk melakukan persiapan awal; dan banyak yang melakukan implementasi terhadap onPause() untuk memastikan penulisan perubahan data. Anda perlu selalu melakukan pemanggilan terhadap superclass ketika melakukan implementasi terhadap metode ini.
public class Activity extends ApplicationContext { protected void onCreate(Bundle savedInstanceState); protected void onStart(); protected void onRestart(); protected void onResume(); protected void onPause(); protected void onStop(); protected void onDestroy(); }
Latihan
1. Buatlah sebuah activity yang dapat menampilkan tahapan siklus hidup dari Activity tersebut pada saat dijalankan dengan melakukan Override terhadap metode callback onCreate, onStart, onRestart, onResume, onPause, onStop, onDestroy.
@Override public void onStart() { super.onStart(); tampilToast("onStart"); } private void tampilToast(String pesan) { int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(getApplicationContext(), pesan, duration); toast.show(); }
37
package com.hendra.persegi; import import import import import android.app.Activity; android.os.Bundle; android.view.View; android.widget.Button; android.widget.TextView;
public class PersegiActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button buttonHitung = (Button) findViewById(R.id.buttonHitung); buttonHitung.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { TextView panjang = (TextView) findViewById(R.id.panjang); TextView lebar = (TextView) findViewById(R.id.lebar); TextView hasil = (TextView) findViewById(R.id.hasil); Double nPanjang = Double. parseDouble(panjang.getText().toString()); Double nLebar = Double. parseDouble(lebar.getText().toString());
38
Catatan: Secara default, penanganan event onClick dapat juga dilakukan melalui properti android:onClick=hitungOnClick sebagaimana yang ditunjukan pada contoh berikut ini :
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hitung" android:id="@+id/buttonHitung" android:onClick="hitungOnClick"></Button> public class Persegi extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.persegi); } public void hitungOnClick(View target) { TextView panjang = (TextView) findViewById(R.id.panjang); TextView lebar = (TextView) findViewById(R.id.lebar); TextView hasil = (TextView) findViewById(R.id.hasil); Double nPanjang = Double. parseDouble(panjang.getText().toString()); Double nLebar = Double. parseDouble(lebar.getText().toString()); Double nHasil = nPanjang * nLebar; hasil.setText("Hasil : " + nHasil.toString()); } }
Event Listener
Suatu event listener adalah suatu interface didalam class view yang mengandung suatu metode callback tunggal. Metode ini akan dipanggil oleh framework Android ketika View dimana listener tersebut didaftarkan dipicu oleh interaksi pemakai melalui UI, beberapa metode callback yang terkait dengan penanganan event pemakai adalah sebagai berikut:
Callback onClick (View v) onLongClick(View v) Parameter v merupakan objek view yang diklik Return void
v merupakan objek view yang diklik dan ditahan boolean, mengembalikan nilai true/false yang menunjukan
39
Contoh:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android= "http://schemas.android.com/apk/res/android"> <ImageView android:id="@+id/gambarKu" android:layout_width="wrap_content" android:src="@drawable/icon" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_marginLeft="90dp" android:layout_marginTop="102dp"> </ImageView> </RelativeLayout>
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ImageView gambarKu = (ImageView) findViewById(R.id.gambarKu); gambarKu.setOnTouchListener( new View.OnTouchListener() { @Override
40
Pada contoh diatas dapat dijelaskan bahwa kita mempersiapkan suatu UI yang menggunakan RelativeLayout, kemudian didalam layout ditempatkan suatu ImageView yang diberi nama gambarKu yang dialign terhadap sudut kiri atas dengan menggunakan pengaturan margin kiri dan atas. Image view ini menampilkan gambar dari resources @drawable/icon. Kemudian pada class Activity kita melakukan pendaftaran callback onTouch terhadap objek gambarKu , didalam callback onTouch kita melakukan perubahan margin kiri dan atas terhadap objek view yang menerima event tersebut (dalam hal ini objek gambarKu yang diwakili oleh parameter v)
Latihan
1. Buatlah aplikasi Android yang berfungsi menghitung luas persegi berdasarkan ukuran panjang dan lebar yang diberikan pemakai. 2. Buatlah aplikasi yang menampilkan sebuah icon dengan ImageView pada suatu Relative Layout, kemudian gunakan penangan event OnTouch untuk mengatur perpindahan ImageView berdasarkan lokasi yang ditunjuk oleh MotionEvent.
41
Explicit intent
Pemakaian Explicit intent dilakukan dengan menentukan class dari Activity yang akan diaktifkan oleh intent dengan contoh sebagai berikut: Misalnya aplikasi kita memiliki suatu Activity utama yang menampilkan empat tombol pilihan dimana pada masing-masing tombol pilihan jika diklik akan mengaktifkan Activity yang bersesuaian. Agar hal ini dapat dilakukan maka kita perlu membuat penanganan event onClick pada masing-masing button, kemudian pada masing-masing rutin penanganan event dibuat Intent dari komponen Activity class yang akan diaktifkan, dan akhirnya Activity diaktifkan dengan menggunakan perintah startActivity(intent), untuk jelasnya kita akan memberi koding bagaimana mengaktifkan Persegi.class berdasarkan klik pada button Persegi sebagai berikut: Hendra, MT. & Hartono, M.Kom. 42
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button buttonPersegi = (Button) findViewById(R.id.buttonPersegi); buttonPersegi.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setClass(this, Persegi.class5); startActivity(intent); } }); }
Berdasarkan contoh diatas dapat kita jelaskan bahwa, awalnya kita mendaftarkan suatu callback onClick untuk menangani event onClick pada objek buttonPersegi (setOnClickListener), kemudian pada rutin penangan event onClick akan dipersiapkan suatu objek intent (new Intent), dan pada objek intent kita tentukan komponen yang akan diaktifkan, yaitu Persegi.class (setClass), dan akhirnya akhirnya Activity diaktifkan (startActivity).
Merupakan type class dari activity yang akan diluncurkan oleh intent
43
Pemrograman Piranti Bergerak Gambar 1 Activity stack yang mengatur visible Activity Ketika Activity Persegi berakhir, maka Activity Persegi akan kembali ke foreground.
Mengakhiri activity
Secara program anda dapat mengakhir suatu Activity dengan memanggil metode finish(). Contoh:
Button buttonSelesai = (Button) findViewById(R.id.buttonSelesai); buttonSelesai.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { finish(); } });
Latihan
1. Buatlah aplikasi android yang menampilkan pilihan Persegi, Segitiga, Lingkaran, Selesai dalam bentuk button, kemudian buatlah masing-masing activity yang dapat melakukan perhitungan yang dimaksud dan diaktifkan melalui masingmasing tombol pilihan.. 2. Tambahkan juga kemampuan pada masing-masing activity untuk kembali kepada activity yang menampilkan tombol pilihan (gunakan metode finish()).
44
Berdasarkan contoh tersebut diatas dapat dijelaskan bahwa awalnya akan dibuat suatu intent baru dengan perintah new Intent(), kemudian ditentukan komponen yang akan diaktifkan adalah Persegi.class dengan perintah setClass(getApplicationContext(), Persegi.class), dan pada intent akan ditambahkan beberapa data tambahan yaitu panjang=100, lebar=200 dengan perintah putExtra(panjang,100) dan putExtra(lebar,200), dan suatu pesan string kirim data dengan perintah putExtra(pesan,kirim data), dan diakhir dengan pengaktifan target Activity dengan perintah startActivity(intent).
6
Merupakan type class dari activity yang akan diluncurkan oleh intent
45
savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.persegi); Intent intent = getIntent(); Bundle bundle = intent.getExtras(); //pastikan bundle tidak kosong if (bundle != null) { Integer panjang = bundle.getInt("panjang"); Integer lebar = bundle.getInt("lebar"); String pesan = bundle.getString("Pesan"); } }
Berdasarkan koding tersebut diatas dapat dijelaskan bahwa pada metode callback onCreate di target Activity akan diawali dengan pemanggilan terhadap super class onCreate (sebagaimana yang disyaratkan oleh Android), kemudian dilanjutkan dengan penentuan UI Activity dengan setContentView, setelah itu kita mengambil intent yang mengaktifkan Acvitity dengan getIntent(), dan dilanjutkan dengan mengambil bundle dari intent tersebut dengan getBundle(), setelah itu kita perlu memastikan bahwa bundle tidak kosong (null) untuk menghindari terjadinya error, setelah itu kita akan mengambil masing-masing data dengan menggunakan getInt(panjang), getInt(lebar), dan getString(pesan).
46
Berdasarkan contoh tersebut diatas dapat dijelaskan bahwa pada kita mendaftarkan penanggan event onClick pada buttonKembalian, sehingga pada saat pemakai melakukan klik pada button tersebut maka akan dibuat suatu Intent baru, dan kita menuliskan data hasil dengan nilai 2000, kemudian menentukan nilai kembalian resultCode dari Activity adalah RESULT_OK, dan akhirnya Activity diakhir finish().
Berdasarkan contoh tersebut diatas dapat dijelaskan bahwa awalnya akan dibuat suatu Intent baru, kemudian ditentukan komponen yang akan diaktifkan adalah Persegi.class, dan diakhir dengan pengaktifan target Activity dengan perintah startActivityForResult(intent, 1), dimana 1 merupakan requestCode yang akan digunakan untuk mengenali hasil dari Activity ini. Selanjutnya kita mempersiapkan suatu callback rutin onActivityResult yang otomatis akan dipanggil jika target Activity berakhir dan mengembalikan data melalui intent.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode,
7
Merupakan type class dari activity yang akan diluncurkan oleh intent
47
Berdasarkan contoh tersebut diatas dapat kita jelaskan bahwa rutin tersebut diatas merupakan callback yang otomatis dipanggil untuk merespon data kembalian oleh target Activity melalui Intent. Awalnya kita akan melakukan pemanggilan terhadap super class dengan melewatkan parameter yang bersesuaian, kemudian kita perlu melakukan pemeriksaan terhadap resultCode dan requestCode, dan mengambil hasil dari data intent dengan perintah getIntExtra(hasil, 0).
Latihan
1. Buatlah aplikasi android yang menampilkan pilihan Persegi, Segitiga, Lingkaran, Selesai dalam bentuk button, kemudian buatlah masing-masing Activity yang dapat melakukan perhitungan yang dimaksud dan diaktifkan melalui masingmasing tombol pilihan yang disertai dengan pengiriman nilai awal. 2. Tambahkan juga kemampuan pada masing-masing activity untuk mengembalikan nilai hasil kepada Activity yang mengaktifkannya, dan ditampilkan dengan toast.
48
Membuat intent-filter
Agar suatu Activity dapat diaktifkan dari aplikasi eksternal, maka perlu didaftarkan Intent-filter pada Activity tersebut pada saat deklarasi Activity tersebut pada file AndroidManifest.xml. Intent-filter menginformasikan kepada sistim Implicit Intent apa saja yang akan ditangani oleh Activity tersebut. Suatu intent-filter terdiri dari field action, category, dan data yang berfungsi untuk melakukan filter terhadap intent yang melewatinya dengan pencocokan pada ketiga field tersebut diatas. Contoh:
<activity android:name=".PersegiActivity" android:label="@string/app_name"> <intent-filter> <action android:name= "android.intent.action.MAIN" /> <category android:name= "android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name= "android.intent.action.VIEW" /> <category android:name= "android.intent.category.DEFAULT" /> <data android:scheme="foo" android:host="persegi.hendra.com" /> </intent-filter> </activity>
Pada contoh tersebut diatas Activity Persegi memiliki dua intent-filter yaitu ACTION_MAIN dan CATEGORY_LAUNCHER yang artinya Activity tersebut akan ditempatkan pada launcher sistim aplikasi dan merupakan Activity utama yang akan diaktifkan pada saat pengaktifan oleh pemakai, kemudian Activity Persegi juga memiliki intent-filter yang mana terdiri dari field action, category dan data untuk menfilter intent yang memiliki action ACTION_VIEW dan schema "foo" dan host "persegi.hendra.com" dengan kata lain .PersegiActivity juga dapat diaktifkan jika ada intent yang melewati intent-filter yang memiliki action ACTION_VIEW dan data uri yang diawali dengan foo://persegi.hendra.com. Jika kita ingin membatasi pengaktifan Hendra, MT. & Hartono, M.Kom. 49
Pemrograman Piranti Bergerak Activity, maka kita dapat menambahkan atribut permission pada saat mendeklarasikan suatu Activity.
<activity android:name=".PersegiActivity" android:permission="com.hendra.permission.PERSEGI_PERMISSION" filter> <action android:name= "android.intent.action.MAIN" /> <category android:name= "android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name= "android.intent.action.VIEW" /> <category android:name= "android.intent.category.DEFAULT" /> <data android:scheme="foo" android:host="persegi.hendra.com" /> </intent-filter> </activity>
<intent-
Implicit Intent
Pengaktifkan Activity dengan implicit intent dilakukan dengan membuat suatu intent baru disertai dengan action yang akan dilakukan, kemudian ditambahkan Uri dengan contoh sebagai berikut:
public void persegiOnClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); Uri uri = Uri.parse("foo://persegi.hendra.com/hitung"); intent.setData(uri); startActivity(intent); }
Berdasarkan koding tersebut diatas dapat dijelaskan bahwa kita akan mengaktifkan Activity secara implicit dengan mengirim ACTION_VIEW dan data uri "foo://persegi.hendra.com/hitung", yang cocok dengan intent-filter yang telah kita buat pada aplikasi sebelumnya. Jika Activity yang ingin kita aktifkan membutuhkan permission, maka pada AndroidManifest diaplikasi perlu ditambahkan:
<uses-permission android:name= "com.hendra.permission.PERSEGI_PERMISSION"> </uses-permission>
Pemrograman Piranti Bergerak Suatu uri memiliki format schema://host:port/path sehingga uri foo://persegi.hendra.com/hitung adalah terdiri dari komponen schema=foo, host=persegi.hendra.com dan path=hitung. Kita tidak menentukan category dari intent karena android memperlakukan semua intent yang dilewatkan dengan startActivity adalah memiliki kategori CATEGORY_DEFAULT.
Berdasarkan koding tersebut diatas dapat dijelaskan akan dilewatkan melalui Uri data melalui parameter panjang dan lebar masing-masing bernilai 10 dan 20.
51
Pada koding tersebut diatas dapat dijelaskan bahwa Activity ketika diaktifkan akan mengambil uri dengan panggilan getIntent().getData() yang mengembalikan uri atau nilai null, jika uri tidak null maka akan diekstraksi nilai parameter panjang dan lebar dengan panggilan getQueryParameter.
Latihan
1. Buatlah masing-masing aplikasi yang terdiri dari Activity dengan kemampuan sebagai berikut: a) Mengkonversi suhu celcius yang dimasukan pemakai ke suhu fahrenheit. b) Mengkonversi suhu celcius yang dimasukan pemakai ke suhu reamur. c) Mengkonversi suhu celcius yang dimasukan pemakai ke suhu kelvin. 2. Buatlah masing aplikasi yang menampilkan menu pilihan Fahrenheit, Reamur, Kelvin, dan Selesai untuk menjalankan Activity yang bersesuaian secara explicit. 3. Bagaimana jika inisialisasi awal nilai suhu dilewatkan dengan parameter pada uri.
52
Menggunakan Permisi
Untuk mengaktifkan Activity tertentu anda perlu menggunakan permisi dengan mendeklarasikan elemen <uses-permission> yang bersesuaian sebagaimana disyaratkan oleh Activity yang akan kita aktifkan, misalnya anda ingin mengaktifkan panggilan telepon, ataupun menampilkan website maka pada AndroidManifest.xml aplikasi anda anda harus menggunakan permission CALL_PHONE dan INTERNET dengan contoh sebagai berikut.
<uses-permission android:name= "android.permission.CALL_PHONE"> </uses-permission>
Melakukan Call
Sebagaimana pengaktifan Activity eksternal dengan menggunakan Implicit intent, kita perlu membuat suatu intent baru, dengan menambahkan data tambahan berupa uri dari nomor telepon yang akan dipanggil, dan diakhir startActivity dengan contoh sebagai berikut: Hendra, MT. & Hartono, M.Kom. 53
Info DEBUG
Contoh error yang timbul jika permission yang dibutuhkan tidak mencukupi
ERROR/AndroidRuntime(3248): java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel: +81533113285 cmp=com.android.phone/.OutgoingCallBroadcaster } from ProcessRecord{44f25f28 3248:com.hendra.pangillan/10082} (pid=3248, uid=10082) requires android.permission.CALL_PHONE
Menampilkan Website
Untuk mengirim email anda perlu menggunakan ACTION_VIEW, dan diikuti dengan informasi tambahan pada data Uri:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")); startActivity(intent);
54
Mengirim email
Untuk mengirim email anda perlu menggunakan ACTION_SEND, dan diikuti dengan informasi tambahan pada Intent melalui Bundle dengan contoh sebagai berikut:
Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("plain/text"); intent.putExtra(Intent.EXTRA_EMAIL,new String[]{"hendra.soewarno@gmail.com"}); intent.putExtra(Intent.EXTRA_SUBJECT,"Hello World"); intent.putExtra(Intent.EXTRA_TEXT,"Selamat Pagi"); startActivity(Intent.createChooser(intent, "Send mail..."));
Mengirim SMS
Untuk mengirim SMS anda perlu menggunakan ACTION_VIEW, dan diikuti dengan informasi tambahan pada Intent melalui data Uri dan Bundle dengan contoh sebagai berikut:
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri8.parse("sms:+81533113285")); intent.putExtra("sms_body","hello world"); startActivity(intent);
55
<?xml version="1.0" encoding="utf-8"?> <FrameLayout android:id="@+id/frameLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android= "http://schemas.android.com/apk/res/android"> <Button android:layout_height="wrap_content" android:layout_gravity="center|bottom" android:layout_marginBottom="98dp" android:layout_width="wrap_content" android:text="Capture" android:id="@+id/buttonCapture"> </Button> <ImageView android:src="@drawable/icon" android:layout_width="233dp" android:layout_height="233dp" android:layout_gravity="center|top" android:id="@+id/imagePhotoResultView"> </ImageView> </FrameLayout>
9
56
private static final int CAMERA_PIC_REQUEST = 1337; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button buttonCapture = (Button) findViewById(R.id.buttonCapture); buttonCapture.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(intent, CAMERA_PIC_REQUEST); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && requestCode == CAMERA_PIC_REQUEST) { Bitmap thumbnail = (Bitmap) data.getExtras().get("data"); ImageView image = (ImageView) findViewById(R.id.imagePhotoResultView); image.setImageBitmap(thumbnail); } }
Latihan
1. Buatlah aplikasi android yang menampilkan EditText untuk menerima nomor telepon dari pemakai, dan Call dilakukan kalau pemakai melakukan klik pada button Call10. 2. Buatlah aplikasi yang dapat menampilkan google MAP untuk kota Medan. 3. Buatlah aplikasi yang dapat menampilkan google MAP untuk STMIK IBBI.
10
Gunakan Uri.parse("tel:"+(txtNumber.getText()).toString()))
57
58
Berdasarkan koding tersebut diatas, maka dapat dijelaskan bahwa kita membuat sebuah Broadcast receiver dengan nama PhoneReceiver yang merupakan subclass dari BroadcastReceiver, kemudian kita akan memeriksa action dari intent yang mengaktifkan receiver, jika berupa "android.intent.action.PHONE_STATE", maka akan ditampilkan nomor yang memanggil, dan sebaliknya akan ditampilkan nomor pengirim SMS. Pengaktifkan dari receiver ini berkaitan dengan Intent-filter Catatan: Jika anda meninginkan receiver anda tidak melanjutkan Broadcaster ke receiver-receiver berikutnya yang memiliki priority yang lebih rendah, maka anda dapat menggunakan this.abortBroadcast();
Intent-filter
Untuk menentukan pemberitahuan Broadcast apa saja yang akan direspon oleh Broadcast receiver yang kita buat, maka kita perlu membuat Intent-filter pada saat deklarasi receiver pada AndroidManifest.xml, karena sebenarnya message asynchronus yang diBroadcast berupa objek Intent.
59
Berdasarkan koding tersebut diatas dapat dijelaskan bahwa receiver PhoneReceiver akan merespon action "android.intent.action.PHONE_STATE" dan "android.provider.Telephony.SMS_RECEIVED" dengan nilai prioritas 100, semakin tinggi nilai prioritas berarti semakin tinggi pula prioritas receiver terhadap respon yang bersesuaian. Kemudian karena receiver kita akan mengakses beberapa fitur pada perangkat, maka kita perlu menggunakan permisi sebagai berikut:
<uses-permission android:name= "android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.VIBRATE"></uses-permission> <uses-permission android:name="android.permission.RECEIVE_SMS"></usespermission>
Mengirim Broadcast
Anda juga diberi kesempatan untuk membuat custom action yang kemudian dapat diBroadcast secara pemrograman dengan contoh sebagai berikut:
Intent i = new Intent(); i.setAction("hendra.custom.intent.action.HITUNG"); ContextWrapper context = (ContextWrapper) getApplicationContext (); context.sendBroadcast(i);
Latihan
1. Buatlah suatu Broadcast receiver yang dapat menampilkan nomor pemanggil ataupun nomor pengirim SMS. Catatan: Untuk melakukan pengujian terhadap receiver yang anda buat pada soal nomor satu anda dapat memanfaatkan fasilitas Emulator Control yang terdapat pada DDMS
60
Atau anda dapat juga mengaktifan Emulator kedua yang berada pada folder tools yang terdapat pada folder android-sdk, kemudian menjalankan perintah emulator @namadevice, selanjutnya anda dapat melakukan panggilan ataupun sms dengan menggunakan nomor port emulator.
61
Pembuatan Database
Pembuatan database pada Android dapat dilakukan secara langsung secara koding dengan membuat suatu class bantuan yang merupakan subclass dari SQLiteOpenHelper. Pada subclass anda perlu mengimplementasikan metode callback seperti onCreate(SQLiteDatabase) yang secara otomatis akan dipanggil untuk pembuatan database, onUpgrade(SQLiteDatabase, int, int) yang akan secara otomatis akan dipanggil pada saat upgrade database diperlukan, dan secara optional onOpen(SQLiteDatabase). Anda harus menempatkan koding untuk pembuatan dan upgrade database pada masing-masing callback yang bersesuaian. Contoh:
public class MyOpenHelper extends SQLiteOpenHelper { static final String DB_NAME = "MyDb"; static final Integer DB_VERSION = 1; public MyOpenHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE Siswa (" + "nim TEXT PRIMARY KEY," +
62
Koding diatas dapat dijelaskan bahwa kita membuat suatu class MyOpenHelper yang merupakan subclass dari SQLiteOpenHelper. Pada class tersebut dibuat dua konstanta yaitu DB_NAME dan DB_VERSION. Kemudian pada class tersebut juga dibuat suatu konstruktor (memiliki nama yang sama dengan class sebagaimana yang disyaratkan pada Java, pada konstruktor ini kita perlu memanggil konstruktor pada parent class (dalam hal ini adalah SQLiteOpenHelper) dengan mengirim parameter yang bersesuaian. Secara default kita perlu melakukan Override terhadap metoda callback onCreate yang mana secara otomatis akan dipanggil jika database perlu di Create, onUpgrade yang mana secara otomatis dipanggil jika database perlu di Upgrade. Untuk menggunakan class MyOpenHelper dapat dilakukan pada Activity yang membutuhkan akses ke database dengan melakukan instantialisasi terhadap class MyOpenHelper, dan kemudian dilanjutkan dengan membuka database secara readonly (getReadableDatabase) atau secara read/write (getWriteableDatabase) contoh:
public class DatabaseActivity extends Activity { private SQLiteDatabase db; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.addsiswa); MyOpenHelper myOpenHelper = new MyOpenHelper( this.getApplicationContext()); db = myOpenHelper.getWritableDatabase(); } }
Koding tersebut diatas dapat kita jelaskan bahwa awalnya akan melakukan instantialiasi terhadap class MyOpenHelper, kemudian membuka database untuk read/write (getWriteableDatabase). Catatan: Pada saat instantialisasi, database tidak otomatis dibuat, tetapi database akan dibuat pada Hendra, MT. & Hartono, M.Kom. 63
Pemrograman Piranti Bergerak saat proses buka database dilakukan.= Setelah aplikasi tersebut diatas dijalankan, maka otomatis akan terbentuk database MyDb pada folder /data/data/com.hendra.testdb/database
dimana com.hendra.testdb merupakan nama package pada saat pembuatan project android. Untuk melihat database file tersebut dapat menggunakan fasilitas DDMS pada open prespektif di Eclipse.
Perangkat SQLite3
Untuk melakukan eksplorasi terhadap database MyDb kita dapat menggunakan fasilitas adb shell yang disediakan pada android-sdk, adalah proses untuk mengaktifkan perangkat SQLite3 adalah sebagai berikut: 1. Aktifkan ke command prompt 2. Ubah direktori ke c:\progra~1\android\android-sdk
64
Pemrograman Piranti Bergerak 3. Ubah direktori ke platform-tools 4. Jalankan perintah adb shell, dan secara otomatis akan ditampilkan # prompt 5. Pada shell ubah directory ke /data/data/com.hendra.testdb/databases 6. Jalankan perintah sqlite MyDb untuk mengaktifkan perangkat SQLite3 sekaligus membuka database MyDb, dan secara otomatis akan ditampilkan sqlite> prompt 7. Pada sqlite prompt ketikan .schema akan menampikan schema database 8. Pada sqlite prompt ketikan .tables akan menampilkan tabel dalam database 9. Pada sqlite prompt ketikan .quit untuk keluar dari perangkat SQLite3 10. Pada sqlite prompt ketikan .help untuk menampikan fasilitas Help Contoh: Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\PROGRA~1>cd android C:\PROGRA~1\Android>cd android-sdk C:\PROGRA~1\Android\android-sdk>cd platform-tools C:\PROGRA~1\Android\android-sdk\platform-tools>adb shell # cd /data/data/com.hendra.testdb # ls # cd databases # ls # sqlite3 MyDb sqlite3 MyDb SQLite version 3.6.22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .schema .schema Hendra, MT. & Hartono, M.Kom. 65
Pemrograman Piranti Bergerak CREATE TABLE Siswa (nim PRIMARY KEY,nama TEXT, nilai char(1)); CREATE TABLE android_metadata (locale TEXT); sqlite> .tables .tables Siswa sqlite> .quit .quit # android_metadata
Latihan:
1. Buatlah sebuah class yang diturunkan dari SQLiteOpenHelper yang berfungsi membuat database MyDb, dan sebuah tabel Siswa yang memiliki struktur sebagai berikut: nim text primarykey nama text nilai char(1) 2. Buatlah activity yang akan memanfaatkan class tersebut diatas, dan membuka database secara read/write. 3. Eksplorasi keberhasilan pembuatan database dengan fasiltias view Explorer File pada DDMS. 4. Lakukan eksplorasi database yang dihasilkan dengan fasilitas perangkat Sqlite3 yang diaktifkan dari adbshell. FAQ SQLite3 1. Bagaimana membuat suatu field AUTOINCREMET? Deklarasi kolom tersebut sebagai INTEGER PRIMARY KEY AUTOINCREMENT. 2. Tipe data apa saja yang didukung oleh SQLite? SQLite menggunakan dynamic typing, isi dapat disimpan sebagai INTEGER, REAL, TEXT, BLOB atau sebagai NULL. Hendra, MT. & Hartono, M.Kom. 66
Pemrograman Piranti Bergerak 3. SQLite memperbolehkan saya menyisip suatu string pada kolom database yang bertipe integer! Ini adalah fitur, bukan bug. Sqlite menggunakan dynamic typing. SQLite tidak melakukan pemaksaan terhadap tipe data, semua data dapat disisipkan dalam semua kolom, anda dapat mengisi string kedalam kolom integer, floating point, boolean, ataupun tanggal pada kolom text (sesuatu pengecualian adalah kolom dengan tipe INTEGER PRIMARY KEY akan terjadi error kalau pengisian dilakukan dengan data bukan integer). Jika anda sebuah kolom tipe INTEGER, dan anda mencoba untuk menyisip sebuah string ke kolom tersebut, SQLite akan berusaha melakukan konversi string tersebut ke suatu integer, jika berhasil akan disimpan sebagai integer, jika tidak string tersebut akan disimpan, fitur ini disebut sebagai type affinity. Untuk FAQ lainnya dapat dibaca di http://www.sqlite.org/faq.html
67
Membuka database
Untuk membuka suatu objek database secara readonly dapat menggunakan metode getReadableDatabase(), dan secara read/write dapat menggunakan metode getWriteableDatabase(), karena pemakaian getWriteableDatabase(). Suatu SQLiteException akan dilempar jika database gagal dibuka. Contoh:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.editsiswa); MyOpenHelper myOpenHelper = new MyOpenHelper(this); db = myOpenHelper.getWritableDatabase(); }
Menutup database
Untuk menutup database dapat digunakan pemanggilan terhadap metode close. Contoh:
@Override protected void onDestroy() { super.onDestroy(); db.close(); }
Menyisip data
Untuk melakukan insert data dapat menggunakan metoda insert yang terdapat pada objek SQLiteDatabase, dengan syntax sebagai berikut: public long insert (String table, String nullColumnHack, ContentValues values)
68
Mengembalikan row ID dari baris yang baru disisipkan, atau -1 jika terjadi kesalahan Contoh:
ContentValues initialValues = new ContentValues(); initialValues.put("nim", "920403024"); initialValues.put("nama","Hendra"); initialValues.put("nilai", "A"); Integer hasil = db.insert("MyDb", null, initialValues);
Memperbaharui data
Untuk melakukan pembaharuan data, anda dapat menggunakan metode update sebagai berikut: public int update (String table, ContentValues values, String whereClause, String[] whereArgs)
Parameters table values whereClause whereArgs Returns Nama tabel dimana proses update akan dilakukan Suatu data map dimana terdiri dari nama kolom dan nilai, null merupakan nilai yang valid dimana akan diterjemahkan menjadi NULL. Suatu WHERE clause optional yang diaplikasikan pada update. Nilai null berarti update terhadap seluruh baris dalam tabel. Anda dapat mengikutsertakan ? Pada bagian whereClause, yang mana akan diganti dengan nilai yang berasal dari whereArgs.
69
Menghapus data
Untuk melakukan penghapusan data, anda dapat menggunakan metode delete sebagai berikut: public int delete (String table, String whereClause, String[] whereArgs)
Parameters Table whereClause Returns Nama tabel dimana proses hapus dilakukan Suatu WHERE clause optional yang diaplikasikan pada penghapusan. Nilai null artinya penghapusan dilakukan terhadap semua baris.
Membaca data
Untuk membaca data dari Tabel dapat menggunakan perintah query yang akan mengembalikan suatu objek Cursor, adapun syntax penulisan untuk query adalah sebagai berikut: public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
Parameters distinct table columns true jika anda ingin menampilkan masing-masing baris secara unik, dan sebaliknya false. Nama dari tabel yang akan dikompilasi pada query. Suatu daftar dari kolom yang akan dikembalikan. Lewatkan null akan mengembalikan semua kolom, hal ini tidak disarankan untuk mencegah pembacaan data dari storage yang kemungkinan tidak dimanfaatkan. Suatu filter yang mendeklarasikan baris mana yang akan dikembalikan, dengan format penulisan seperti WHERE clause pada SQL, lewatkan null akan mengembalikan semua baris pada tabel.
selection
70
Suatu objek Cursor yang pada diposisikan sebelum isi yang pertama, catatan Cursor adalah tidak disinkronisasi.
Cursor cursor = db.query(false,"Siswa",null,null,null,null,null,null,null);
Perintah diatas akan mengembalikan semua kolom dan semua baris pada tabel Siswa
Cursor cursor = db.query(false,"Siswa",new String[] {"nim","nama"}, null,null,null,null,null,null);
Perintah diatas akan mengembalikan kolom nim, nama dari semua baris pada tabel Siswa
Cursor cursor = db.query(false,"Siswa",new String[] {"count(*)"}, null,null,null,null,null,null);
Perintah diatas akan mengembalikan 1 kolom yang berisi jumlah baris pada tabel Siswa Contoh Query dan pemakaian Cursor:
Cursor cursor = db.query(false,"Siswa",null,null,null,null,null,null,null); if (cursor.getCount() > 0) { cursor.moveToFirst(); do { System.out.println(cursor.getString(0) + "|" +cursor.getString(1) + "|" + cursor.getString(2)); } while (cursor.moveToNext()); } else { System.out.println("Tidak ada data"); }
Latihan:
1. Buatlah suatu aplikasi Android yang memiliki fasilitas Tambah, Perbaiki, dan Hendra, MT. & Hartono, M.Kom. 71
72
URI
Setiap Content Provider diekspos dengan menggunakan suatu public URI (yang dibungkus sebagai suatu object Uri) yang mana merupakan identitas unik, sehingga untuk dapat mengakses suatu Content Provider, maka kita perlu mengetahui URI dari Content Provider tersebut, dan semua URI memiliki format penulisan string content://<authority>/<data_path>/<id>, android mendefinsikan konstanta CONTENT_URI untuk semua provider yang secara default tersedia didalam platformnya. Sebagai contoh, URI untuk tabel pencocokan nomor telepon ke nama orang adalah :
Android.provider.Contacts.Phones.CONTENT_URI
URI tersebut diatas mengacu kepada semua data yang berada pada provider phones, jika anda ingin mengacu pada data dengan _ID tertentu saja maka penulisan URI menjadi:
"content://com.android.contacts/data/phones/1"
73
Untuk melakukan query terhadap suatu content provider, anda dapat menggunakan metode Activity.managedQuery() yang akan mengembalikan suatu objek Cursor. Suatu managed Cursor menangani semua dengan baik, seperti melakukan unload dirinya ketika aktifitas di-pause, dan melakukan requery ketika aktifitas di-restart.
public class ContentproviderActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); String[] projection=new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Phone.NUMBER }; final Cursor cursor = managedQuery(Phone.CONTENT_URI,projection, null, null, null); if (cursor.getCount() > 0) { cursor.moveToFirst(); System.out.println(cursor.getString(cursor .getColumnIndex(Contacts.DISPLAY_NAME))); System.out.println(cursor.getString(cursor .getColumnIndex(Phone.NUMBER))); } else { System.out.println("contact kosong"); } } }
Jika anda ingin melakukan query terhadap record tertentu, anda juga membutuhkan ID dari record tersebut.
Uri myContact = ContentUris.withAppendedId(Phone.CONTENT_URI, 1); System.out.println(myContact.toString()); final Cursor cursor = contentResolver.query(myContact,
74
1.
Pemakaian Permisi
Sebelum suatu aplikasi dapat melakukan akses query ke contact record, maka harus diregistrasi pemakaian permisi melalui file AndroidManifest.xml sebagai berikut:
<uses-permission android:name="android.permission.READ_CONTACTS" />
listcontact_dtl.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" android:id="@+id/linearLayout1"> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textViewNama"> </TextView>
75
ListContact.java
public class ListContact extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.listcontact); } @Override protected void onStart() { super.onStart(); ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); String[] projection = new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Phone.NUMBER }; ContentResolver contentResolver = getContentResolver(); final Cursor cursor = contentResolver.query(Phone.CONTENT_URI, projection, null, null, null); while (cursor.moveToNext()) { HashMap<String, String> item = new HashMap<String, String>(); item.put("id", cursor.getString(0)); item.put("nama", cursor.getString(1)); item.put("nomor", cursor.getString(2)); list.add(item); } SimpleAdapter notes = new SimpleAdapter(this, list, R.layout.listcontact_dtl, new String[] { "nama", "nomor" }, new int[] { R.id.textViewNama, R.id.textViewNomor }); setListAdapter(notes); } @Override protected void onListItemClick(ListView l, View v, int position, long thisID) { super.onListItemClick(l, v, position, thisID); @SuppressWarnings("unchecked") HashMap<String, String> item = (HashMap<String, String>)
76
Latihan:
1. Buatlah suatu aplikasi Android yang dapat menampilkan nomor dan nama dari Content Providers contacts pada suatu listview.
77
Membuat Database
Sebagai langkah awal pembuatan Content Provider adalah mempersiapkan fasilitas penyimpan data, dalam hal ini kita akan menggunakan database SQLite yang secara default telah disediakan pada platform Android. Sebagaimana yang pernah kita bahas pada bagian sebelumnya, untuk memudahkan akses ke database kita perlu membuat suatu class bantuan yang merupakan subclass dari SQLiteOpenHelper dan melakukan override terhadap beberapa callback yang berfungsi untuk membuat dan menguprade database.
public class MyOpenHelper extends SQLiteOpenHelper { static final String DB_NAME = "MyDb"; static final Integer DB_VERSION = 1; public MyOpenHelper(Context context) {
78
Pada class tersebut diatas, kita akan membuat suatu database MyDb yang didalamnya terdapat suatu tabel Siswa yang memiliki empat field yaitu _id, nim, nama dan nilai. Sesuatu hal yang perlu kita ingat adalah suatu tabel yang akan digunakan untuk Content Provider perlu memiliki suatu field primary key autoincrement dengan nama _id.
79
Berikut ini adalah koding kongkrit dari Siswa Provider yang kita buat.
public class SiswaProvider extends ContentProvider { public static final String AUTHORITY = "com.hendra.buatcontentprovider.SiswaProvider"; private static final int SISWA = 1; private static final int SISWA_ID = 2; private static final String TABLE_NAME = "Siswa"; private SQLiteDatabase db; private static final UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "siswas", SISWA); uriMatcher.addURI(AUTHORITY, "siswas/#", SISWA_ID); } @Override public boolean onCreate() { Context context = getContext(); MyOpenHelper myOpenHelper = new MyOpenHelper(context); db = myOpenHelper.getWritableDatabase(); return (db == null) ? false : true; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { // ---ambil semua siswa--case SISWA: return "vnd.android.cursor.dir/vnd.hendra.siswa "; // ---ambil siswa tertentu saja---
80
81
82
android:exported="true" />
Agar Content Provider dapat digunakan pada aplikasi eksternal, kita perlu menambahkan atribut android:exported="true".
83
} }
84
Tugas
1. Buatlah sebuah Content Provider yang dapat menyimpan data siswa. 2. Lakukan akses terhadap Content Provider tersebut dari aplikasi internal. 3. Bagaimana kalau akses dilakukan dari aplikasi eksternal?
85
Pembuatan Service
Untuk membuat service anda perlu membuat suatu class yang merupakan subclass dari Service, dan melakukan Override terhadap beberapa metoda yaitu onBind, onCreate, onStart dan onDestroy.
public class MyService extends Service { private static final String TAG = "MyService"; MediaPlayer player; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show(); Log.d(TAG, "onCreate");
86
Mendaftarkan Service
Sebagaimana Activity, Receiver, maupun Content Provider, Service juga harus didaftarkan kedalam AndroidManifest.xml untuk membuatnya menjadi efektif.
<service android:name=".MyService" <intent-filter android:label="com.hendra.testservice.MyService"> </intent-filter> </service>
Menjalankan Service
Untuk menjalankan service yang berada pada aplikasi yang sama kita dapat menggunakan startService dengan mengirim Intent secara explicit.
public class TestServiceActivity extends Activity { private static final String TAG = "TestServices"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void buttonStartOnClick(View v) { Log.d(TAG, "onClick: starting service"); startService(new Intent(this, MyService.class)); } public void buttonStopOnClick(View v) {
87
Suatu service yang dijalankan dengan perintah startService akan tetap berjalan sampai terjadi pemanggilan terhadap stopService(), atau terjadi pemanggilan perintah stopSeft() pada internal service tersebut.
Latihan
1. Buatlah suatu service yang dapat memainkan suatu lagu MP3
88
Membuat Lokalisasi
Sebagaimana yang telah kita bahas bahwa Android menyimpan berbagai sumber daya tulisan pada directory /res, dan Android secara default dapat memilih dan memuat sumber daya dari direktori yang berbeda berdasarkan konfigurasi dari locale pada peralatan. Sebagai contoh, misalnya anda ingin membuat sebuah aplikasi yang mendukung beberapa bahasa berdasarkan setting locale dari pemakai, maka pada saat anda membuat aplikasi tersebut anda perlu membuat resource default dan resource untuk untuk masingmasing bahasa menurut locale, sehingga ketika aplikasi dijalankan, sistim akan memilih resource menurut locale yang bersesuaian, jika tidak tersedia, maka akan menggunakan resource standard. Agar masing-masing resource tidak bercampur satu dengan yang lain, maka resource untuk masing-masing setting locale harus disimpan pada folder yang memiliki sufiks yang berbeda. File resource /res/values-enrUS/strings.xml Keterangan Isi file Resource untuk language English Region US
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Halo dunia, PersegiActivity!</string> <string name="app_name">Persegi</string> <string name="length">panjang</string> <string name="width">lebar</string> <string name="calculate">hitung</string> <string name="result">hasil</string> </resources> <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello world, PersegiActivity!</string> <string name="app_name">Rectangle</string> <string name="length">length</string> <string name="width">width</string> <string name="calculate">calculate</string> <string name="result">result</string>
/res/values-en/strings.xml
89
/res/values/strings.xml
Default resource
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello world, PersegiActivity!</string> <string name="app_name">Rectangle</string> <string name="length">length</string> <string name="width">width</string> <string name="calculate">calculate</string> <string name="result">result</string> </resources>
Pada tabel diatas terlihat bahwa masing-masing string resource memiliki nama yang sama dengan nilai yang berbeda menurut target bahasa dan regional, dan masing-masing file xml disimpan pada folder yang memiliki sufiks sesuai dengan target bahasa dan regional. Jika pada kode maupun properties layout dimuat suatu string R.string.length, maka Android akan mencari nilai yang bersesuaian untuk string tersebut pada saat runtime berdasarkan setting language dan regional pada perangkat. Contoh:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res /android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/length"></TextView> <EditText android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/editPanjang"> <requestFocus></requestFocus> </EditText> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/width"></TextView> <EditText android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/editLebar"></EditText>
90
Misalkan locale pada perangkat adalah 'en-US', maka android akan mencari nilai R.string.length berdasarkan aturan pencarian sebagai berikut: 1. res/values-en-rUS/strings.xml 2. res/values-en/strings.xml 3. res/values/strings.xml Jika pencarian akan berhenti sesuai dengan hasil pencarian yang ditemukan pertama kalinya berdasarkan urutan diatas. Lokalisasi juga dapat dilakukan pada resource lainnya dengan menggunakan aturan penamaan yang sama pada sufiks folder yang mengikuti standard kode ISO. Contoh: Flag image Italian French French (Canada) English (Canada) Russian US English Default (Indonesia) Target folder drawable-it-rIT/flag.png drawable-fr-rFR/flag.png drawable-fr-rCA/flag.png drawable-en-rCA/flag.png drawable-ru-rRU/flag.png drawable-en-rUS/flag.png drawable/flag.png
Kesimpulan
Agar aplikasi yang anda buat dapat mendukung banyak bahasa berdasarkan setting language dan regional, berikut ini adalah hal yang perlu anda perhatikan: 1. Jangan melakukan hard-code pada string ataupun konstanta string; sebagai gantinya gunakan definisi string tersebut pada resource string.xml dan genakan Hendra, MT. & Hartono, M.Kom. 91
Pemrograman Piranti Bergerak referensi R.string. 2. Hal yang sama juga berlaku untuk image atau layout; gunakan R.drawable dan R.layout 3. Terjemahkan masing-masign nilai pada file string.xml dan tempatkan string.xml hasil terjemahan ke folder yang sesuai.
92
Daftar Pustaka
1. Android Developer, http://developer.android.com
93
Lampiran :
Pada awalnya perlu dipersiapkan suatu class MyOpenHelper yang merupakan subclass dari SQLiteOpenHelper. Pada class ini didefinisikan struktur dari tabel Siswa.
Database OpenHelper
/src/com.hendra.testdb/MyOpenHelper.java
package com.hendra.testdb; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class MyOpenHelper extends SQLiteOpenHelper { static final String DB_NAME = "MyDb"; static final Integer DB_VERSION = 1; public MyOpenHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE Siswa (nim TEXT PRIMARY KEY," + "nama TEXT, nilai char(1))"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w("Upgrade", "Proses akan drop dan buat ulang tabel."); db.execSQL("DROP TABLE IF EXISTS Siswa"); onCreate(db); } }
94
AddSiswa
Buatlah layout yang dapat menampilan tampilan berikut ini yang terdiri dari TextView (Nim, Nama, Nilai), EditText (editNim, editNama, editNilai), dan button (Simpan), set button Simpan untuk mengaktifkan simpanOnClick(View v).
/res/layout/addsiswa.xml
/src/com.hendra.testdb/AddSiswa.java package com.hendra.testdb; import android.app.Activity; import android.content.ContentValues; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class AddSiswa extends Activity { private SQLiteDatabase db; @Override
95
96
EditSiswa
/res/layout/editsiswa.xml
/src/com.hendra.testdb/EditSiswa.xml package com.hendra.testdb; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class EditSiswa extends Activity { private SQLiteDatabase db; String editingNim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.editsiswa); MyOpenHelper myOpenHelper = new MyOpenHelper(
97
98
99
DeleteSiswa
/res/layout/deletesiswa.xml
/src/com.hendra.testdb/EditSiswa.java package com.hendra.testdb; import android.app.Activity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class DeleteSiswa extends Activity { private MyOpenHelper myOpenHelper; private SQLiteDatabase db; private String editingNim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.deletesiswa); myOpenHelper = new MyOpenHelper(this.getApplicationContext()); db = myOpenHelper.getWritableDatabase();
100
101
ListSiswa2Baris
/res/layout/list_siswa_two_line_row.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:textSize="16px" android:textStyle="bold" android:layout_height="wrap_content" android:text="Text1" android:layout_width="match_parent" android:id="@+id/baris1"/> <TextView android:textSize="12px" android:textStyle="italic" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="Text2" android:id="@+id/baris2"/> </LinearLayout>
102
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> /src/com.hendra.testdb/ListSiswa2Baris.java package com.hendra.testdb; import java.util.ArrayList; import java.util.HashMap; import com.hendra.testdb.MyOpenHelper; import com.hendra.testdb.R; import android.app.ListActivity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast;
103
104
105
<?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:id="@+id/linearLayout1" android:weightSum="1" android:paddingBottom="3px" android:paddingTop="3px"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:layout_weight="0.21" android:id="@+id/kolom1"></TextView> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:layout_weight="0.72" android:id="@+id/kolom2"></TextView> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/kolom3"></TextView> </LinearLayout> /src/com.hendra.testdb/ListSiswa3Kolom.java package com.hendra.testdb; import java.util.ArrayList; import java.util.HashMap; import android.app.ListActivity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;
106
Cursor cursor = db.query(false, "Siswa", new String[] { "nim", "nama", "nilai" }, null, null, null, null, null, null); while (cursor.moveToNext()) { HashMap<String,String> item = new HashMap<String,String>(); item.put( "nim",cursor.getString(0)); item.put( "nama",cursor.getString(1)); item.put( "nilai",cursor.getString(2)); list.add( item ); } SimpleAdapter notes = new SimpleAdapter( this, list, R.layout.listsiswa_tiga_kolom, new String[] { "nim","nama","nilai" }, new int[] { R.id.kolom1, R.id.kolom2, R.id.kolom3 }); setListAdapter( notes );
107
String selectedNim = hashMap.get("nim"); tampilToast("Anda memilih: " + selectedNim); } private void tampilToast(String pesan) { int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(getApplicationContext(), pesan, duration); toast.show(); } }
108
/src/com.hendra.testdb/Menu.java package com.hendra.testdb; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class Menu extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void tambahOnClick(View v) { Intent addSiswa = new Intent(this.getApplicationContext(), AddSiswa.class); startActivity(addSiswa); } public void perbaikiOnClick(View v) { Intent intent = new Intent(this.getApplicationContext(), EditSiswa.class);
109
110