Level API: 17
Android 4.2 (JELLY_BEAN_MR1
)
adalah update dari rilis Jelly Bean yang menawarkan fitur baru bagi pengguna dan developer
aplikasi. Dokumen ini menyediakan 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 Anda 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 pada 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 akan memeriksa API level sistem sebelum menjalankan
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 API level tersedia di 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, sekarang Anda harus menetapkanandroid:exported="true"
secara eksplisit.Perubahan ini hanya berlaku jika Anda menetapkan
android:targetSdkVersion
atauandroid:minSdkVersion
ke versi 17 atau yang lebih tinggi. Jika tidak, nilai default masih“true"
bahkan saat dijalankan di Android 4.2 dan yang lebih tinggi. - Dibandingkan dengan versi Android sebelumnya, hasil lokasi pengguna mungkin kurang akurat
jika aplikasi Anda meminta izin
ACCESS_COARSE_LOCATION
tetapi tidak meminta izinACCESS_FINE_LOCATION
.Untuk memenuhi ekspektasi privasi pengguna saat aplikasi meminta izin untuk lokasi sementara (dan bukan lokasi terperinci), sistem tidak akan memberikan perkiraan lokasi pengguna yang lebih akurat daripada satu blok kota.
- Beberapa setelan perangkat yang ditentukan oleh
Settings.System
sekarang bersifat hanya baca. Jika aplikasi Anda mencoba menulis perubahan ke setelan yang ditentukan diSettings.System
dan telah dipindahkan keSettings.Global
, operasi tulis akan otomatis gagal saat berjalan di Android 4.2 dan yang lebih tinggi.Meskipun nilai untuk
android:targetSdkVersion
danandroid:minSdkVersion
lebih rendah dari 17, aplikasi Anda tidak dapat mengubah setelan yang telah dipindahkan keSettings.Global
saat berjalan di Android 4.2 dan yang lebih tinggi. - Jika aplikasi Anda menggunakan
WebView
, Android 4.2 akan menambahkan lapisan keamanan tambahan sehingga Anda dapat mengikat JavaScript ke kode Android dengan lebih aman. Jika menetapkantargetSdkVersion
ke versi 17 atau lebih tinggi, sekarang Anda harus menambahkan anotasi@JavascriptInterface
ke metode apa pun yang ingin disediakan untuk JavaScript Anda (metode tersebut juga harus publik). Jika Anda tidak memberikan anotasi, metode ini tidak dapat diakses oleh halaman web diWebView
saat berjalan di Android 4.2 atau yang lebih tinggi. Jika Anda menetapkantargetSdkVersion
ke 16 atau lebih rendah, anotasi tidak diperlukan, tetapi sebaiknya Anda mengupdate versi target dan menambahkan anotasi untuk keamanan tambahan.Baca selengkapnya tentang mengikat kode JavaScript ke kode Android.
Daydream
Daydream adalah mode screensaver interaktif baru untuk perangkat Android. Metode ini otomatis aktif saat perangkat dimasukkan ke dok atau saat perangkat tidak ada aktivitas dengan dicolokkan ke pengisi daya (bukan menonaktifkan layar). Daydream menampilkan satu mimpi dalam satu waktu, yang mungkin berupa tampilan pasif yang murni yang menutup saat disentuh, atau 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 impian untuk Daydream dengan menerapkan subclass DreamService
. DreamService
API
dirancang agar mirip dengan Activity
. Untuk menentukan UI bagi
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 diluncurkan secara otomatis oleh sistem.
Jika impian Anda bersifat interaktif, Anda dapat memulai aktivitas dari mimpi untuk mengirim pengguna ke
UI lengkap aplikasi agar mendapatkan detail atau kontrol yang lebih besar. Anda dapat menggunakan finish()
untuk mengakhiri impian agar pengguna dapat melihat
Aktivitas baru.
Agar daydream Anda tersedia bagi 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 tersebut bersifat interaktif, pengguna dapat menggunakan tombol Kembali atau Beranda untuk keluar dari impian tersebut, atau Anda dapat memanggilfinish()
untuk menghentikannya.- Jika menginginkan tampilan yang sepenuhnya imersif, Anda dapat memanggil
setFullscreen()
untuk menyembunyikan status bar. - Sebelum Daydream dimulai, layar akan meredup untuk memberi tahu pengguna bahwa waktu tunggu tidak ada aktivitas
mendekati. Memanggil
setScreenBright(true)
memungkinkan Anda menyetel tampilan dalam kecerahan biasanya.
Untuk mengetahui 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 Anda dapat menampilkan UI unik di
tampilan sekunder.
Untuk mendeteksi tampilan sekunder tempat Anda dapat menampilkan Presentation
,
gunakan API DisplayManager
atau
MediaRouter
. Meskipun API DisplayManager
memungkinkan Anda menghitung
beberapa tampilan yang mungkin terhubung sekaligus, biasanya Anda harus menggunakan MediaRouter
untuk mengakses tampilan default sistem untuk
presentasi dengan cepat.
Guna mendapatkan tampilan default untuk 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 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 saat tampilan baru telah terhubung, buat instance MediaRouter.SimpleCallback
tempat Anda mengimplementasikan metode callback onRoutePresentationDisplayChanged()
, yang akan dipanggil sistem saat tampilan presentasi baru
terhubung. Lalu, 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 mungkin 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. Cara ini menyediakan
resource yang sesuai dari aplikasi Anda dan paling sesuai untuk
ukuran dan kepadatan layar tampilan 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 ini 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
. Cara kerjanya sama seperti android:initialLayout
, karena menyediakan
tata letak yang dapat langsung muncul hingga widget aplikasi Anda diinisialisasi dan dapat mengupdate
tata letak.
Untuk mengetahui informasi selengkapnya tentang cara membuat widget aplikasi untuk layar kunci, termasuk cara menyesuaikan ukuran widget aplikasi dengan benar saat berada di layar kunci, lihat panduan Widget Aplikasi.
Beberapa Pengguna
Android kini memungkinkan beberapa ruang pengguna di perangkat yang dapat digunakan bersama, seperti tablet. Setiap pengguna di perangkat memiliki kumpulan akun, aplikasi, setelan sistem, file, dan data lainnya yang terkait dengan pengguna.
Sebagai developer aplikasi, Anda tidak perlu melakukan apa pun agar aplikasi dapat berfungsi dengan baik bersama 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 Anda untuk pengguna lain. Sistem melacak data pengguna mana yang termasuk dalam proses pengguna saat aplikasi Anda berjalan, dan memberi aplikasi 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 bahwa aplikasi Anda berperilaku dengan benar dalam lingkungan multi-pengguna, jangan merujuk ke direktori aplikasi internal atau lokasi penyimpanan eksternal Anda yang menggunakan jalur hard code, dan selalu gunakan API yang sesuai:
- Untuk akses ke penyimpanan internal, gunakan
getFilesDir()
,getCacheDir()
, atauopenFileOutput()
. - Untuk akses ke penyimpanan eksternal, gunakan
getExternalFilesDir()
ataugetExternalStoragePublicDirectory()
.
Terlepas dari API yang Anda gunakan untuk menyimpan data untuk pengguna tertentu, data tidak akan diakses saat dijalankan sebagai pengguna yang berbeda. Dari sudut pandang aplikasi, setiap pengguna berjalan di perangkat yang sepenuhnya terpisah.
Mengidentifikasi pengguna di lingkungan multi-pengguna
Jika aplikasi Anda ingin mengidentifikasi pengguna unik seperti untuk mengumpulkan analisis atau membuat asosiasi
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 tersebut 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 diperbarui 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 seluruh
ruang pengguna di perangkat.
Beberapa setelan yang ada dipindahkan ke sini dari Settings.System
atau Settings.Secure
. Jika aplikasi Anda
saat ini membuat perubahan pada setelan yang sebelumnya ditentukan di Settings.System
(seperti AIRPLANE_MODE_ON
), Anda kemungkinan 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, upaya 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 dengan baik 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 setel “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 serta tombol tindakan di sebelah kiri, dan tata letak apa pun yang Anda buat dengan
class View
yang disediakan framework juga akan dibalik.
Jika Anda perlu mengoptimalkan tampilan aplikasi lebih lanjut saat ditampilkan dengan tata letak RTL, ada dua tingkat pengoptimalan dasar:
- Mengonversi properti tata letak berorientasi kiri dan kanan menjadi properti tata letak berorientasi
awal dan akhir.
Misalnya, gunakan
android:layout_marginStart
sebagai penggantiandroid:layout_marginLeft
danandroid:layout_marginEnd
sebagai penggantiandroid:layout_marginRight
.Class
RelativeLayout
juga menyediakan atribut tata letak yang sesuai untuk mengganti posisi kiri/kanan, sepertiandroid:layout_alignParentStart
untuk menggantiandroid:layout_alignParentLeft
danandroid:layout_toStartOf
, bukanandroid:layout_toLeftOf
. - Atau, untuk memberikan pengoptimalan tata letak RTL yang sepenuhnya, 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 dires/layout/
dan tata letak yang dioptimalkan RTL dires/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 di
class View
sehingga Anda dapat menerapkan perilaku yang tepat untuk tampilan
kustom dan di Configuration
untuk membuat kueri arah tata letak saat ini.
Catatan: Jika Anda menggunakan SQlite dan memiliki tabel atau nama kolom yang
“hanya angka",
berhati-hatilah: menggunakan String.format(String, Object...)
dapat menyebabkan error saat angka
telah dikonversi ke padanan bahasa Arab jika perangkat Anda telah disetel ke lokalitas 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
saat Anda ingin menempatkan komponen UI yang dinamis dan dapat digunakan kembali ke dalam komponen UI yang
dinamis dan dapat digunakan kembali. Misalnya, jika menggunakan ViewPager
untuk
membuat fragmen yang menggeser ke kiri dan kanan serta menggunakan sebagian besar ruang layar, Anda kini dapat
menyisipkan fragmen ke setiap halaman fragmen.
Untuk menyusun bertingkat fragmen, cukup panggil getChildFragmentManager()
pada
Fragment
tempat Anda ingin menambahkan fragmen. Tindakan ini akan menampilkan FragmentManager
yang dapat Anda gunakan seperti yang biasa Anda lakukan dari aktivitas level atas
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:
Blends
Blur
Color matrix
3x3 convolve
5x5 convolve
Per-channel lookup table
Converting an Android YUV buffer to RGB
Untuk menggunakan intrinsik skrip, panggil metode
create()
statis dari setiap instrinsik untuk membuat instance skrip. Kemudian, panggil metodeset()
yang tersedia dari setiap intrinsik skrip untuk menetapkan input dan opsi yang diperlukan. Terakhir, panggil metodeforEach()
untuk menjalankan skrip.- Grup Skrip
-
ScriptGroup
memungkinkan Anda untuk membuat rantai skrip Renderscript yang terkait dan menjalankannya dengan satu panggilan.Gunakan
ScriptGroup.Builder
untuk menambahkan semua skrip ke grup dengan memanggiladdKernel()
. Setelah menambahkan semua skrip, buat koneksi antara skrip dengan memanggiladdConnection()
. Setelah selesai menambahkan koneksi, panggilcreate()
untuk membuat grup skrip. Sebelum menjalankan grup skrip, tentukanAllocation
input dan skrip awal yang akan dijalankan dengan metodesetInput(Script.KernelID, Allocation)
, dan berikan outputAllocation
tempat hasil akan ditulis dan skrip akhir untuk dijalankan dengansetOutput()
. Terakhir, panggilexecute()
untuk menjalankan grup skrip. - Skrip filter
-
Filterscript menentukan batasan pada Renderscript API yang ada yang memungkinkan kode yang dihasilkan berjalan pada berbagai prosesor (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 bahwa skrip Anda tidak memerlukan presisi floating point IEEE 754-2008 yang ketat. Presisi ini memungkinkan flush-to-zero 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 fungsiroot()
.
Catatan: Meskipun dukungan Filterscript tersedia di platform, dukungan developer akan tersedia di Rilis SDK Tools 21.0.1.
Untuk melihat tampilan mendetail semua perubahan API di Android 4.2, lihat Laporan Perbedaan API.