Android 4.2 API

Level API: 17

Android 4.2 (JELLY_BEAN_MR1) adalah update dari rilis Jelly Bean yang menawarkan berbagai fitur baru bagi pengguna dan developer aplikasi. Dokumen ini memberikan pengantar API baru yang paling penting dan berguna bagi developer.

Sebagai developer aplikasi, Anda harus mendownload image sistem Android 4.2 dan platform SDK dari SDK Manager sesegera mungkin. Jika tidak memiliki perangkat yang menjalankan Android 4.2 untuk menguji aplikasi, gunakan image sistem Android 4.2 untuk menguji aplikasi Anda di Android emulator. Kemudian bangun aplikasi Anda pada platform Android 4.2 untuk mulai menggunakan API terbaru.

Untuk lebih mengoptimalkan aplikasi untuk perangkat yang menjalankan Android 4.2, Anda harus menyetel targetSdkVersion ke "17", menginstalnya di image sistem Android 4.2, mengujinya, lalu memublikasikan update dengan perubahan ini.

Anda dapat menggunakan API di Android 4.2 sekaligus mendukung versi lama dengan menambahkan kondisi ke kode yang memeriksa API level sistem sebelum mengeksekusi API yang tidak didukung oleh minSdkVersion Anda. Untuk mempelajari lebih lanjut cara mempertahankan kompatibilitas mundur, baca Membuat UI yang Kompatibel dengan Mundur.

Informasi selengkapnya tentang cara kerja level API tersedia di bagian Apa yang dimaksud dengan API Level?

Perubahan Perilaku yang Penting

Jika sebelumnya Anda telah memublikasikan aplikasi untuk Android, perhatikan perubahan berikut yang mungkin memengaruhi perilaku aplikasi:

  • Penyedia konten tidak lagi diekspor secara default. Artinya, nilai default untuk atribut android:exported sekarang adalah “false". Jika aplikasi lain harus dapat mengakses penyedia konten, Anda kini harus menetapkan android:exported="true" secara eksplisit.

    Perubahan ini hanya berlaku jika Anda menetapkan android:targetSdkVersion atau android:minSdkVersion ke versi 17 atau yang lebih tinggi. Jika tidak, nilai default-nya tetap “true" bahkan saat dijalankan di Android 4.2 dan yang lebih tinggi.

  • Dibandingkan dengan Android versi sebelumnya, hasil lokasi pengguna mungkin kurang akurat jika aplikasi Anda meminta izin ACCESS_COARSE_LOCATION tetapi tidak meminta izin ACCESS_FINE_LOCATION.

    Untuk memenuhi ekspektasi privasi pengguna saat aplikasi meminta izin untuk lokasi sementara (dan bukan lokasi akurat), sistem tidak akan memberikan perkiraan lokasi pengguna yang lebih akurat daripada blok kota.

  • Beberapa setelan perangkat yang ditentukan oleh Settings.System kini bersifat hanya baca. Jika aplikasi Anda mencoba menulis perubahan ke setelan yang ditentukan di Settings.System yang telah dipindahkan ke Settings.Global, operasi tulis akan gagal di latar belakang saat berjalan di Android 4.2 dan yang lebih tinggi.

    Meskipun nilai untuk android:targetSdkVersion dan android:minSdkVersion lebih rendah dari 17, aplikasi tidak dapat mengubah setelan yang telah berpindah ke Settings.Global saat berjalan di Android 4.2 dan yang lebih tinggi.

  • Jika aplikasi Anda menggunakan WebView, Android 4.2 menambahkan lapisan keamanan tambahan sehingga Anda dapat mengikat JavaScript ke kode Android dengan lebih aman. Jika menetapkan targetSdkVersion ke versi 17 atau yang lebih tinggi, kini Anda harus menambahkan anotasi @JavascriptInterface ke metode apa pun yang ingin disediakan untuk JavaScript Anda (metode tersebut juga harus bersifat publik). Jika Anda tidak memberikan anotasi, metode ini tidak dapat diakses oleh halaman web di WebView saat berjalan di Android 4.2 atau yang lebih tinggi. Jika Anda menetapkan targetSdkVersion ke 16 atau yang lebih rendah, anotasi tidak diperlukan, tetapi sebaiknya update versi target Anda dan tambahkan anotasi untuk keamanan tambahan.

    Baca selengkapnya tentang mengikat kode JavaScript ke kode Android.

Daydream

Daydream adalah mode screensaver interaktif baru untuk perangkat Android. Fitur ini diaktifkan secara otomatis saat perangkat dimasukkan ke dok atau saat perangkat dalam keadaan tidak ada aktivitas saat dicolokkan ke pengisi daya (bukan menonaktifkan layar). Daydream menampilkan mimpi satu per satu, yang mungkin berupa tampilan pasif yang sepenuhnya menutup saat disentuh, atau yang mungkin bersifat interaktif dan responsif terhadap rangkaian lengkap peristiwa input. Impian Anda berjalan dalam proses aplikasi dan memiliki akses penuh ke toolkit UI Android, termasuk tampilan, tata letak, dan animasi, sehingga lebih fleksibel dan kuat daripada wallpaper animasi atau widget aplikasi.

Anda dapat membuat mimpi untuk Daydream dengan menerapkan subclass DreamService. DreamService API dirancang agar mirip dengan Activity. Untuk menentukan UI mimpi Anda, teruskan ID resource tata letak atau View ke setContentView() kapan saja setelah Anda memiliki jendela, seperti dari callback onAttachedToWindow().

Class DreamService menyediakan metode callback siklus proses penting lainnya selain API Service dasar, seperti onDreamingStarted(), onDreamingStopped(), dan onDetachedFromWindow(). Anda tidak dapat memulai DreamService dari aplikasi karena aplikasi akan otomatis diluncurkan oleh sistem.

Jika mimpi Anda bersifat interaktif, Anda dapat memulai aktivitas dari mimpi tersebut untuk mengarahkan pengguna ke UI lengkap aplikasi guna mendapatkan detail atau kontrol lebih lanjut. Anda dapat menggunakan finish() untuk mengakhiri Dream sehingga pengguna dapat melihat Aktivitas baru.

Agar daydream tersedia untuk sistem, deklarasikan DreamService dengan elemen <service> dalam file manifes Anda. Kemudian, Anda harus menyertakan filter intent dengan tindakan "android.service.dreams.DreamService". Contoh:

<service android:name=".MyDream" android:exported="true"
    android:icon="@drawable/dream_icon" android:label="@string/dream_label" >
    <intent-filter>
        <action android:name="android.service.dreams.DreamService" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

Ada beberapa metode berguna lainnya di DreamService yang perlu diperhatikan:

  • setInteractive(boolean) mengontrol apakah mimpi akan menerima peristiwa input atau langsung keluar setelah input pengguna. Jika impian bersifat interaktif, pengguna dapat menggunakan tombol Kembali atau Beranda untuk keluar dari mimpi atau Anda dapat memanggil finish() untuk menghentikan mimpi.
  • Jika menginginkan tampilan yang sepenuhnya imersif, Anda dapat memanggil setFullscreen() untuk menyembunyikan status bar.
  • Sebelum Daydream dimulai, layar akan diredupkan untuk memberi tahu pengguna bahwa waktu tunggu tidak ada aktivitas mendekati. Dengan memanggil setScreenBright(true), Anda dapat menyetel tampilan pada kecerahan biasanya.

Untuk informasi selengkapnya, lihat dokumentasi DreamService.

Layar Sekunder

Android kini memungkinkan aplikasi Anda menampilkan konten unik di layar tambahan yang terhubung ke perangkat pengguna melalui koneksi berkabel atau Wi-Fi. Untuk membuat konten unik untuk tampilan sekunder, perluas class Presentation dan implementasikan callback onCreate(). Dalam onCreate(), tentukan UI untuk tampilan sekunder dengan memanggil setContentView(). Sebagai ekstensi dari class Dialog, class Presentation menyediakan region tempat aplikasi dapat menampilkan UI unik pada tampilan sekunder.

Untuk mendeteksi tampilan sekunder tempat Anda dapat menampilkan Presentation, gunakan DisplayManager atau MediaRouter API. Meskipun API DisplayManager memungkinkan Anda menghitung beberapa tampilan yang mungkin terhubung sekaligus, Anda biasanya harus menggunakan MediaRouter untuk mengakses dengan cepat tampilan default sistem untuk presentasi.

Untuk mendapatkan tampilan default presentasi Anda, panggil MediaRouter.getSelectedRoute() dan teruskan ROUTE_TYPE_LIVE_VIDEO. Tindakan ini akan menampilkan objek MediaRouter.RouteInfo yang menjelaskan rute yang saat ini dipilih oleh sistem untuk presentasi video. Jika MediaRouter.RouteInfo bukan null, panggil getPresentationDisplay() untuk mendapatkan Display yang mewakili tampilan yang terhubung.

Selanjutnya, Anda dapat menampilkan presentasi dengan meneruskan objek Display ke konstruktor untuk class Presentation Anda. Presentasi Anda sekarang akan muncul di tampilan sekunder.

Untuk mendeteksi pada runtime ketika tampilan baru telah terhubung, buat instance MediaRouter.SimpleCallback tempat Anda mengimplementasikan metode callback onRoutePresentationDisplayChanged(), yang akan dipanggil sistem saat tampilan presentasi baru terhubung. Kemudian, daftarkan MediaRouter.SimpleCallback dengan meneruskannya ke MediaRouter.addCallback() bersama dengan jenis rute ROUTE_TYPE_LIVE_VIDEO. Saat Anda menerima panggilan ke onRoutePresentationDisplayChanged(), cukup panggil MediaRouter.getSelectedRoute() seperti yang disebutkan di atas.

Guna lebih mengoptimalkan UI di Presentation untuk layar sekunder, Anda dapat menerapkan tema yang berbeda dengan menentukan atribut android:presentationTheme dalam <style> yang telah diterapkan ke aplikasi atau aktivitas Anda.

Perlu diingat bahwa layar yang terhubung ke perangkat pengguna sering kali memiliki ukuran layar yang lebih besar dan kemungkinan kepadatan layar yang berbeda. Karena karakteristik layar dapat berbeda, Anda harus menyediakan resource yang dioptimalkan secara khusus untuk tampilan yang lebih besar tersebut. Jika Anda perlu meminta resource tambahan dari Presentation, panggil getContext().getResources() untuk mendapatkan objek Resources yang sesuai dengan tampilan. Tindakan ini menyediakan resource yang sesuai dari aplikasi Anda dan paling sesuai untuk ukuran dan kepadatan layar sekunder.

Untuk mengetahui informasi selengkapnya dan beberapa contoh kode, lihat dokumentasi class Presentation.

Widget Layar Kunci

Android kini memungkinkan pengguna menambahkan widget aplikasi ke layar kunci. Agar Widget Aplikasi tersedia untuk digunakan di layar kunci, tambahkan atribut android:widgetCategory ke file XML yang menentukan AppWidgetProviderInfo. Atribut ini mendukung dua nilai: home_screen dan keyguard. Secara default, atribut ditetapkan ke home_screen sehingga pengguna dapat menambahkan widget aplikasi Anda ke Layar utama. Jika Anda ingin widget aplikasi juga tersedia di layar kunci, tambahkan nilai keyguard:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:widgetCategory="keyguard|home_screen">
</appwidget-provider>

Anda juga harus menentukan tata letak awal untuk widget aplikasi saat berada di layar kunci dengan atribut android:initialKeyguardLayout. Ini berfungsi dengan cara yang sama seperti android:initialLayout, karena menyediakan tata letak yang dapat langsung muncul hingga widget aplikasi Anda diinisialisasi dan dapat memperbarui tata letak.

Untuk mengetahui informasi selengkapnya tentang membuat widget aplikasi untuk layar kunci, termasuk menentukan ukuran widget aplikasi dengan benar saat berada di layar kunci, lihat panduan Widget Aplikasi.

Beberapa Pengguna

Android kini mengizinkan beberapa ruang pengguna di perangkat yang dapat dibagikan seperti tablet. Setiap pengguna di perangkat memiliki kumpulan akun, aplikasi, setelan sistem, file mereka sendiri, dan data lainnya yang terkait dengan pengguna.

Sebagai developer aplikasi, tidak ada hal lain yang perlu Anda lakukan agar aplikasi Anda dapat berfungsi dengan baik dengan beberapa pengguna di satu perangkat. Terlepas dari jumlah pengguna yang mungkin ada di perangkat, data yang disimpan aplikasi Anda untuk pengguna tertentu tetap terpisah dari data yang disimpan aplikasi untuk pengguna lain. Sistem melacak data pengguna mana yang termasuk dalam proses pengguna tempat aplikasi Anda berjalan, dan memberi aplikasi Anda akses hanya ke data pengguna tersebut, dan tidak mengizinkan akses ke data pengguna lainnya.

Menyimpan data di lingkungan multi-pengguna

Setiap kali aplikasi Anda menyimpan preferensi pengguna, membuat database, atau menulis file ke ruang penyimpanan internal atau eksternal pengguna, data tersebut hanya dapat diakses saat dijalankan sebagai pengguna tersebut.

Untuk memastikan aplikasi Anda berperilaku dengan baik di lingkungan multi-pengguna, jangan merujuk ke direktori aplikasi internal atau lokasi penyimpanan eksternal Anda menggunakan jalur hard code dan sebagai gantinya selalu gunakan API yang sesuai:

Apa pun API yang Anda gunakan untuk menyimpan data untuk pengguna tertentu, data tersebut tidak akan dapat diakses saat dijalankan sebagai pengguna yang berbeda. Dari sudut pandang aplikasi, setiap pengguna berjalan di perangkat yang benar-benar terpisah.

Mengidentifikasi pengguna dalam lingkungan multi-pengguna

Jika aplikasi Anda ingin mengidentifikasi pengguna unik seperti untuk mengumpulkan analisis atau membuat pengaitan akun lainnya, Anda harus mengikuti praktik yang direkomendasikan untuk mengidentifikasi penginstalan unik. Dengan membuat UUID baru saat aplikasi dimulai untuk pertama kalinya, Anda pasti akan mendapatkan ID unik untuk melacak setiap pengguna, berapa pun jumlah pengguna yang menginstal aplikasi Anda di satu perangkat. Atau, Anda dapat menyimpan token lokal yang diambil dari server atau menggunakan ID pendaftaran yang diberikan oleh Google Cloud Messaging.

Berhati-hatilah, jika aplikasi Anda meminta salah satu ID perangkat hardware (seperti alamat MAC Wi-Fi atau nomor SERIAL), ID ini akan memberikan nilai yang sama untuk setiap pengguna karena ID ini terikat dengan hardware, bukan pengguna. Selain masalah lain yang diperkenalkan oleh ID ini, seperti yang dibahas dalam postingan blog Mengidentifikasi Penginstalan Aplikasi.

Setelan Global Baru

Setelan sistem telah diupdate untuk mendukung beberapa pengguna dengan tambahan Settings.Global. Kumpulan setelan ini mirip dengan setelan Settings.Secure karena bersifat hanya baca, tetapi berlaku secara global di semua ruang pengguna di perangkat.

Beberapa setelan yang sudah ada dipindahkan ke sini dari Settings.System atau Settings.Secure. Jika saat ini aplikasi Anda melakukan perubahan pada setelan yang sebelumnya ditentukan di Settings.System (seperti AIRPLANE_MODE_ON), Anda akan melihat bahwa tindakan tersebut tidak akan berfungsi lagi pada perangkat yang menjalankan Android 4.2 atau yang lebih tinggi jika setelan tersebut dipindahkan ke Settings.Global. Anda dapat terus membaca setelan yang ada di Settings.Global, tetapi karena setelan ini tidak lagi dianggap aman bagi aplikasi untuk diubah, mencoba melakukannya akan gagal tanpa ada peringatan dan sistem akan menulis peringatan ke log sistem saat menjalankan aplikasi Anda di Android 4.2 atau yang lebih baru.

Dukungan Tata Letak RTL

Android kini menawarkan beberapa API yang memungkinkan Anda mem-build antarmuka pengguna yang mengubah orientasi tata letak secara halus untuk mendukung bahasa yang menggunakan UI kanan-ke-kiri (RTL) dan arah baca, seperti bahasa Arab dan Ibrani.

Untuk mulai mendukung tata letak RTL di aplikasi Anda, setel atribut android:supportsRtl ke elemen <application> dalam file manifes dan tetapkan “true". Setelah Anda mengaktifkannya, sistem akan mengaktifkan berbagai API RTL untuk menampilkan aplikasi dengan tata letak RTL. Misalnya, panel tindakan akan menampilkan ikon dan judul di sisi kanan dan tombol tindakan di sebelah kiri, serta tata letak apa pun yang Anda buat dengan class View yang disediakan framework juga akan terbalik.

Jika perlu mengoptimalkan lebih lanjut tampilan aplikasi saat ditampilkan dengan tata letak RTL, ada dua tingkat dasar pengoptimalan:

  1. Mengonversi properti tata letak berorientasi kiri dan kanan menjadi properti tata letak berorientasi awal dan akhir.

    Misalnya, gunakan android:layout_marginStart sebagai pengganti android:layout_marginLeft dan android:layout_marginEnd sebagai pengganti android:layout_marginRight.

    Class RelativeLayout juga menyediakan atribut tata letak yang sesuai untuk mengganti posisi kiri/kanan, seperti android:layout_alignParentStart untuk mengganti android:layout_alignParentLeft dan android:layout_toStartOf, bukan android:layout_toLeftOf.

  2. Atau, untuk memberikan pengoptimalan penuh bagi tata letak RTL, Anda dapat menyediakan file tata letak yang sepenuhnya terpisah menggunakan penentu resource ldrtl (ldrtl adalah singkatan dari layout-direction-right-to-left}). Misalnya, Anda dapat menyimpan file tata letak default di res/layout/ dan tata letak RTL yang dioptimalkan di res/layout-ldrtl/.

    Penentu ldrtl sangat cocok untuk resource drawable, sehingga Anda dapat memberikan grafik yang berorientasi ke arah yang sesuai dengan arah pembacaan.

Berbagai API lain tersedia di seluruh framework untuk mendukung tata letak RTL, seperti dalam class View agar Anda dapat menerapkan perilaku yang tepat untuk tampilan kustom dan dalam Configuration untuk membuat kueri arah tata letak saat ini.

Catatan: Jika Anda menggunakan SQlite dan memiliki nama tabel atau kolom yang “hanya angka”, berhati-hatilah: penggunaan String.format(String, Object...) dapat menyebabkan error saat angka telah dikonversi ke padanan bahasa Arab jika perangkat telah disetel ke bahasa Arab. Anda harus menggunakan String.format(Locale,String,Object...) untuk memastikan angka dipertahankan sebagai ASCII. Selain itu, gunakan String.format("%d", int), bukan menggunakan String.valueOf(int) untuk memformat angka.

Fragmen Bertingkat

Sekarang Anda dapat menyematkan fragmen di dalam fragmen. Hal ini berguna untuk berbagai situasi ketika Anda ingin menempatkan komponen UI yang dinamis dan dapat digunakan kembali ke dalam komponen UI yang dinamis dan dapat digunakan kembali. Misalnya, jika Anda menggunakan ViewPager untuk membuat fragmen yang menggeser ke kiri dan kanan serta menggunakan sebagian besar ruang layar, kini Anda dapat menyisipkan fragmen ke setiap halaman fragmen.

Untuk menyarangkan fragmen, cukup panggil getChildFragmentManager() pada Fragment tempat Anda ingin menambahkan fragmen. Tindakan ini akan menampilkan FragmentManager yang dapat Anda gunakan seperti biasanya dari aktivitas level teratas untuk membuat transaksi fragmen. Misalnya, berikut adalah beberapa kode yang menambahkan fragmen dari dalam class Fragment yang ada:

Kotlin

val videoFragment = VideoPlayerFragment()
childFragmentManager.beginTransaction().apply {
    add(R.id.video_fragment, videoFragment)
    commit()
}

Java

Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();

Dari dalam fragmen bertingkat, Anda bisa mendapatkan referensi ke fragmen induk dengan memanggil getParentFragment().

Android Support Library kini juga mendukung fragmen bertingkat, sehingga Anda dapat menerapkan desain fragmen bertingkat pada Android 1.6 dan yang lebih tinggi.

Catatan: Anda tidak dapat meng-inflate tata letak menjadi fragmen jika tata letak tersebut menyertakan <fragment>. Fragmen bertingkat hanya didukung jika ditambahkan ke fragmen secara dinamis.

Renderscript

Fungsi komputasi Renderscript telah ditingkatkan dengan fitur berikut:

Intrinsik skrip

Anda dapat menggunakan intrinsik skrip bawaan Renderscript yang mengimplementasikan operasi umum untuk Anda seperti:

Untuk menggunakan intrinsik skrip, panggil metode create() statis setiap instrinsik untuk membuat instance skrip. Selanjutnya, panggil metode set() yang tersedia dari setiap intrinsik skrip untuk menetapkan input dan opsi yang diperlukan. Terakhir, panggil metode forEach() untuk menjalankan skrip.

Grup Skrip

ScriptGroup memungkinkan Anda menggabungkan skrip Renderscript yang terkait dan menjalankannya dengan satu panggilan.

Gunakan ScriptGroup.Builder untuk menambahkan semua skrip ke grup dengan memanggil addKernel(). Setelah menambahkan semua skrip, buat koneksi antar-skrip dengan memanggil addConnection(). Setelah selesai menambahkan koneksi, panggil create() untuk membuat grup skrip. Sebelum menjalankan grup skrip, tentukan Allocation input dan skrip awal yang akan dijalankan dengan metode setInput(Script.KernelID, Allocation), dan berikan output Allocation tempat hasilnya akan ditulis dan skrip akhir untuk dijalankan dengan setOutput(). Terakhir, panggil execute() untuk menjalankan grup skrip.

Skrip filter

Filterscript menentukan batasan pada Renderscript API yang ada, yang memungkinkan kode yang dihasilkan berjalan pada berbagai prosesor yang lebih luas (CPU, GPU, dan DSP). Untuk membuat file Filterscript, buat file .fs, bukan file .rs, dan tentukan #pragma rs_fp_relaxed untuk memberi tahu runtime Renderscript yang tidak memerlukan presisi floating point IEEE 754-2008 yang ketat. Presisi ini memungkinkan flush-ke-nol untuk denorm dan round-towards-zero. Selain itu, skrip Filterscript Anda tidak boleh menggunakan jenis bawaan 32 bit dan harus menentukan fungsi root kustom dengan menggunakan atribut __attribute__((kernel)) karena Filterscript tidak mendukung pointer, yang ditentukan oleh tanda tangan default fungsi root().

Catatan: Meskipun dukungan Filterscript ada di platform, dukungan developer akan tersedia di Rilis SDK Tools 21.0.1.

Untuk melihat tampilan mendetail dari semua perubahan API di Android 4.2, lihat Laporan Perbedaan API.