Android 4.3 API

Level API: 18

Android 4.3 (JELLY_BEAN_MR2) adalah update dari rilis Jelly Bean yang menawarkan fitur baru bagi pengguna dan developer aplikasi. Dokumen ini menyediakan pengantar API baru yang paling penting.

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

Memperbarui target API level Anda

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

Anda dapat menggunakan API di Android 4.3 sekaligus mendukung versi lama dengan menambahkan kondisi ke kode yang akan memeriksa level API sistem sebelum mengeksekusi API yang tidak didukung oleh minSdkVersion Anda. Untuk mempelajari lebih lanjut cara mempertahankan kompatibilitas mundur, baca Mendukung Versi Platform yang Berbeda.

Berbagai API juga tersedia di Support Library Android yang memungkinkan Anda menerapkan fitur baru pada versi platform yang lebih lama.

Untuk mengetahui informasi selengkapnya tentang cara kerja API level, baca Apa itu API Level?

Perubahan Perilaku yang Penting

Jika sebelumnya Anda telah memublikasikan aplikasi untuk Android, perlu diketahui bahwa aplikasi Anda mungkin terpengaruh oleh perubahan dalam Android 4.3.

Jika aplikasi Anda menggunakan intent implisit...

Aplikasi Anda mungkin mengalami gangguan di lingkungan profil yang dibatasi.

Pengguna di lingkungan profil yang dibatasi mungkin tidak memiliki semua aplikasi Android standar yang tersedia. Misalnya, untuk profil yang dibatasi, browser web dan aplikasi kamera mungkin telah dinonaktifkan. Jadi, aplikasi Anda tidak boleh membuat asumsi tentang aplikasi mana yang tersedia, karena jika Anda memanggil startActivity() tanpa memverifikasi apakah aplikasi tersedia untuk menangani Intent, aplikasi Anda mungkin akan error di profil yang dibatasi.

Saat menggunakan intent implisit, Anda harus selalu memverifikasi bahwa aplikasi tersedia untuk menangani intent tersebut dengan memanggil resolveActivity() atau queryIntentActivities(). Contoh:

Kotlin

val intent = Intent(Intent.ACTION_SEND)
...
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show()
}

Java

Intent intent = new Intent(Intent.ACTION_SEND);
...
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    Toast.makeText(context, R.string.app_not_available, Toast.LENGTH_LONG).show();
}

Jika aplikasi Anda bergantung pada akun...

Aplikasi Anda mungkin mengalami gangguan di lingkungan profil yang dibatasi.

Pengguna dalam lingkungan profil yang dibatasi tidak memiliki akses ke akun pengguna secara default. Jika aplikasi Anda bergantung pada Account, aplikasi mungkin mengalami error atau berperilaku secara tidak terduga saat digunakan di profil yang dibatasi.

Jika Anda ingin mencegah profil yang dibatasi agar tidak menggunakan aplikasi sepenuhnya karena aplikasi Anda bergantung pada informasi akun yang sensitif, tentukan atribut android:requiredAccountType dalam elemen <application> manifes Anda.

Jika ingin mengizinkan profil yang dibatasi untuk terus menggunakan aplikasi Anda meskipun pengguna tersebut tidak dapat membuat akunnya sendiri, Anda dapat menonaktifkan fitur aplikasi yang memerlukan akun atau mengizinkan profil yang dibatasi untuk mengakses akun yang dibuat oleh pengguna utama. Untuk informasi selengkapnya, lihat bagian di bawah tentang Mendukung akun dalam profil yang dibatasi.

Jika aplikasi Anda menggunakan VideoView...

Video Anda mungkin terlihat lebih kecil pada Android 4.3.

Pada Android versi sebelumnya, widget VideoView salah menghitung nilai "wrap_content" untuk layout_height dan layout_width agar sama dengan "match_parent". Jadi, saat menggunakan "wrap_content" untuk tinggi atau lebar mungkin sebelumnya telah menyediakan tata letak video yang Anda inginkan, tindakan ini dapat menghasilkan video yang jauh lebih kecil di Android 4.3 dan yang lebih tinggi. Untuk memperbaiki masalah ini, ganti "wrap_content" dengan "match_parent" dan pastikan video Anda muncul seperti yang diharapkan di Android 4.3 serta di versi yang lebih lama.

Profil yang Dibatasi

Di tablet Android, pengguna kini dapat membuat profil yang dibatasi berdasarkan pengguna utama. Saat membuat profil yang dibatasi, mereka dapat mengaktifkan pembatasan seperti aplikasi mana yang tersedia untuk profil tersebut. Kumpulan API baru di Android 4.3 juga memungkinkan Anda membuat setelan pembatasan yang lebih mendetail untuk aplikasi yang Anda kembangkan. Misalnya, dengan menggunakan API baru, Anda dapat mengizinkan pengguna mengontrol jenis konten yang tersedia dalam aplikasi saat berjalan di lingkungan profil yang dibatasi.

UI yang dapat digunakan pengguna untuk mengontrol batasan yang Anda buat dikelola oleh aplikasi Setelan sistem. Agar setelan batasan aplikasi ditampilkan kepada pengguna, Anda harus mendeklarasikan batasan yang disediakan aplikasi dengan membuat BroadcastReceiver yang menerima intent ACTION_GET_RESTRICTION_ENTRIES. Sistem akan memanggil intent ini guna mengkueri semua aplikasi untuk mengetahui batasan yang tersedia, lalu membuat UI agar pengguna utama dapat mengelola pembatasan untuk setiap profil yang dibatasi.

Dalam metode onReceive() BroadcastReceiver, Anda harus membuat RestrictionEntry untuk setiap batasan yang disediakan aplikasi Anda. Setiap RestrictionEntry menentukan judul dan deskripsi batasan, serta salah satu jenis data berikut:

  • TYPE_BOOLEAN untuk batasan yang benar atau salah.
  • TYPE_CHOICE untuk pembatasan yang memiliki beberapa pilihan yang sama-sama bersifat eksklusif (pilihan tombol pilihan).
  • TYPE_MULTI_SELECT untuk batasan yang memiliki beberapa pilihan yang tidak saling eksklusif (pilihan kotak centang).

Lalu, tempatkan semua objek RestrictionEntry ke dalam ArrayList dan masukkan ke hasil penerima siaran sebagai nilai untuk tambahan EXTRA_RESTRICTIONS_LIST.

Sistem akan membuat UI untuk pembatasan aplikasi Anda di aplikasi Setelan, dan menyimpan setiap batasan dengan kunci unik yang Anda berikan untuk setiap objek RestrictionEntry. Saat pengguna membuka aplikasi, Anda dapat membuat kueri untuk setiap batasan saat ini dengan memanggil getApplicationRestrictions(). Tindakan ini akan menampilkan Bundle yang berisi key-value pair untuk setiap batasan yang Anda tentukan dengan objek RestrictionEntry.

Jika ingin memberikan batasan yang lebih spesifik yang tidak dapat ditangani oleh nilai boolean, pilihan tunggal, dan pilihan ganda, Anda dapat membuat aktivitas tempat pengguna dapat menentukan batasan dan mengizinkan pengguna untuk membuka aktivitas tersebut dari setelan batasan. Di penerima siaran, sertakan tambahan EXTRA_RESTRICTIONS_INTENT dalam Bundle hasil. Tambahan ini harus menentukan Intent yang menunjukkan class Activity akan diluncurkan (gunakan metode putParcelable() untuk meneruskan EXTRA_RESTRICTIONS_INTENT dengan intent). Saat pengguna utama memasukkan aktivitas Anda untuk menetapkan batasan kustom, aktivitas Anda kemudian harus menampilkan hasil yang berisi nilai batasan dalam tambahan menggunakan kunci EXTRA_RESTRICTIONS_LIST atau EXTRA_RESTRICTIONS_BUNDLE, bergantung pada apakah Anda menentukan objek RestrictionEntry atau key-value pair.

Akun pendukung di profil yang dibatasi

Setiap akun yang ditambahkan ke pengguna utama tersedia untuk profil yang dibatasi, tetapi akun tersebut tidak dapat diakses dari AccountManager API secara default. Jika Anda mencoba menambahkan akun dengan AccountManager saat menggunakan profil yang dibatasi, Anda akan mendapatkan hasil kegagalan. Karena batasan ini, Anda memiliki tiga opsi berikut:

  • Izinkan akses ke akun pemilik dari profil yang dibatasi.

    Untuk mendapatkan akses ke akun dari profil yang dibatasi, Anda harus menambahkan atribut android:restrictedAccountType ke tag <application>:

    <application ...
        android:restrictedAccountType="com.example.account.type" >
    

    Perhatian: Dengan mengaktifkan atribut ini, aplikasi Anda akan dapat mengakses akun pengguna utama dari profil yang dibatasi. Jadi, sebaiknya Anda mengizinkan hal ini hanya jika informasi yang ditampilkan oleh aplikasi Anda tidak mengungkapkan informasi identitas pribadi (PII) yang dianggap sensitif. Setelan sistem akan memberi tahu pengguna utama bahwa aplikasi Anda memberikan profil yang dibatasi ke akun mereka, sehingga harus jelas bagi pengguna bahwa akses akun penting untuk fungsi aplikasi Anda. Jika memungkinkan, Anda juga harus memberikan kontrol batasan yang memadai bagi pengguna utama yang menentukan seberapa banyak akses akun yang diizinkan di aplikasi Anda.

  • Menonaktifkan fungsi tertentu saat tidak dapat mengubah akun.

    Jika ingin menggunakan akun, tetapi tidak benar-benar memerlukannya untuk fungsi utama aplikasi, Anda dapat memeriksa ketersediaan akun dan menonaktifkan fitur saat tidak tersedia. Anda harus terlebih dahulu memeriksa apakah sudah ada akun yang tersedia. Jika tidak, kueri apakah akun baru dapat dibuat dengan memanggil getUserRestrictions() dan periksa tambahan DISALLOW_MODIFY_ACCOUNTS dalam hasil. Jika berupa true, Anda harus menonaktifkan fungsi apa pun aplikasi yang memerlukan akses ke akun. Contoh:

    Kotlin

    val um = context.getSystemService(Context.USER_SERVICE) as UserManager
    val restrictions: Bundle = um.userRestrictions
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    Java

    UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
    Bundle restrictions = um.getUserRestrictions();
    if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
        // cannot add accounts, disable some functionality
    }
    

    Catatan: Dalam skenario ini, Anda tidak boleh mendeklarasikan atribut baru apa pun dalam file manifes.

  • Menonaktifkan aplikasi saat tidak dapat mengakses akun pribadi.

    Jika penting bahwa aplikasi Anda tidak tersedia untuk profil yang dibatasi karena aplikasi Anda bergantung pada informasi pribadi yang sensitif di akun (dan karena profil yang dibatasi saat ini tidak dapat menambahkan akun baru), tambahkan atribut android:requiredAccountType ke tag <application>:

    <application ...
        android:requiredAccountType="com.example.account.type" >
    

    Misalnya, aplikasi Gmail menggunakan atribut ini untuk menonaktifkan dirinya sendiri untuk profil yang dibatasi, karena email pribadi pemilik tidak boleh tersedia untuk profil yang dibatasi.

  • Nirkabel dan Konektivitas

    Bluetooth Hemat Energi (Smart Ready)

    Android kini mendukung Bluetooth Hemat Energi (LE) dengan API baru di android.bluetooth. Dengan API baru ini, Anda dapat mem-build aplikasi Android yang berkomunikasi dengan periferal Bluetooth Hemat Energi seperti monitor detak jantung dan pedometer.

    Karena Bluetooth LE adalah fitur hardware yang tidak tersedia di semua perangkat yang menjalankan Android, Anda harus mendeklarasikan elemen <uses-feature> untuk "android.hardware.bluetooth_le" dalam file manifes:

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
    

    Jika Anda sudah terbiasa dengan API Bluetooth Klasik Android, perhatikan bahwa penggunaan Bluetooth LE API memiliki beberapa perbedaan. Yang terpenting adalah kini ada class BluetoothManager yang harus Anda gunakan untuk beberapa operasi tingkat tinggi seperti mendapatkan BluetoothAdapter, mendapatkan daftar perangkat yang terhubung, dan memeriksa status perangkat. Misalnya, berikut ini cara Anda sekarang mendapatkan BluetoothAdapter:

    Kotlin

    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothAdapter = bluetoothManager.adapter
    

    Java

    final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();
    

    Untuk menemukan periferal Bluetooth LE, panggil startLeScan() pada BluetoothAdapter, dengan meneruskan implementasi antarmuka BluetoothAdapter.LeScanCallback. Jika adaptor Bluetooth mendeteksi periferal Bluetooth LE, penerapan BluetoothAdapter.LeScanCallback akan menerima panggilan ke metode onLeScan(). Metode ini memberi Anda objek BluetoothDevice yang mewakili perangkat yang terdeteksi, nilai RSSI untuk perangkat, dan array byte yang berisi data iklan perangkat.

    Jika hanya ingin memindai jenis periferal tertentu, Anda dapat memanggil startLeScan() dan menyertakan array objek UUID yang menentukan layanan GATT yang didukung aplikasi Anda.

    Catatan: Anda hanya dapat memindai perangkat Bluetooth LE atau memindai perangkat Bluetooth Klasik menggunakan API sebelumnya. Anda tidak dapat memindai perangkat LE dan Bluetooth Klasik sekaligus.

    Kemudian, untuk terhubung ke periferal Bluetooth LE, panggil connectGatt() pada objek BluetoothDevice yang sesuai, dengan meneruskan implementasi BluetoothGattCallback. Implementasi BluetoothGattCallback akan menerima callback terkait status konektivitas dengan perangkat dan peristiwa lainnya. Selama callback onConnectionStateChange(), Anda dapat mulai berkomunikasi dengan perangkat jika metode meneruskan STATE_CONNECTED sebagai status baru.

    Untuk mengakses fitur Bluetooth di perangkat, aplikasi Anda juga harus meminta izin pengguna Bluetooth tertentu. Untuk informasi selengkapnya, lihat panduan Bluetooth Low Energy API.

    Mode hanya pemindaian Wi-Fi

    Ketika mencoba mengidentifikasi lokasi pengguna, Android dapat menggunakan Wi-Fi untuk membantu menentukan lokasi dengan memindai titik akses di sekitar. Namun, pengguna sering menonaktifkan Wi-Fi untuk menghemat baterai, sehingga menghasilkan data lokasi yang kurang akurat. Android kini menyertakan mode pemindaian saja yang memungkinkan Wi-Fi perangkat memindai titik akses untuk membantu mendapatkan lokasi tanpa terhubung ke titik akses, sehingga sangat mengurangi penggunaan baterai.

    Jika ingin mendapatkan lokasi pengguna tetapi Wi-Fi saat ini nonaktif, Anda dapat meminta pengguna mengaktifkan mode hanya pemindaian Wi-Fi dengan memanggil startActivity() dengan tindakan ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE.

    Konfigurasi Wi-Fi

    WifiEnterpriseConfig API baru memungkinkan layanan berorientasi perusahaan untuk mengotomatiskan konfigurasi Wi-Fi bagi perangkat terkelola.

    Respons cepat untuk panggilan masuk

    Sejak Android 4.0, fitur bernama "Respons cepat" memungkinkan pengguna merespons panggilan masuk dengan pesan teks langsung tanpa perlu mengangkat panggilan atau membuka kunci perangkat. Hingga saat ini, pesan cepat ini selalu ditangani oleh aplikasi Messaging default. Kini, aplikasi apa pun dapat mendeklarasikan kemampuannya untuk menangani pesan ini dengan membuat Service dengan filter intent untuk ACTION_RESPOND_VIA_MESSAGE.

    Saat pengguna merespons panggilan masuk dengan respons cepat, aplikasi Telepon akan mengirimkan intent ACTION_RESPOND_VIA_MESSAGE dengan URI yang menjelaskan penerima (pemanggil) dan tambahan EXTRA_TEXT dengan pesan yang ingin dikirim pengguna. Saat menerima intent, layanan Anda akan mengirimkan pesan dan segera berhenti sendiri (aplikasi Anda tidak boleh menampilkan aktivitas).

    Untuk menerima intent ini, Anda harus mendeklarasikan izin SEND_RESPOND_VIA_MESSAGE.

    Multimedia

    Peningkatan MediaExtractor dan MediaCodec

    Android kini mempermudah Anda menulis pemutar Dynamic Adaptive Streaming over HTTP (DASH) sesuai dengan standar ISO/IEC 23009-1, dengan menggunakan API yang ada di MediaCodec dan MediaExtractor. Framework yang mendasari API ini telah diupdate untuk mendukung penguraian file MP4 yang terfragmentasi, tetapi aplikasi Anda masih bertanggung jawab untuk mengurai metadata MPD dan meneruskan setiap streaming ke MediaExtractor.

    Jika Anda ingin menggunakan DASH dengan konten terenkripsi, perhatikan bahwa metode getSampleCryptoInfo() menampilkan metadata MediaCodec.CryptoInfo yang menjelaskan struktur setiap contoh media yang dienkripsi. Selain itu, metode getPsshInfo() telah ditambahkan ke MediaExtractor sehingga Anda dapat mengakses metadata PSSH untuk media DASH. Metode ini menampilkan peta objek UUID ke byte, dengan UUID yang menentukan skema kripto, dan byte adalah data yang khusus untuk skema tersebut.

    DRM Media

    Class MediaDrm yang baru menyediakan solusi modular untuk manajemen hak digital (DRM) pada konten media Anda dengan memisahkan masalah DRM dari pemutaran media. Misalnya, pemisahan API ini memungkinkan Anda memutar kembali konten terenkripsi Widevine tanpa harus menggunakan format media Widevine. Solusi DRM ini juga mendukung Enkripsi Umum DASH sehingga Anda dapat menggunakan berbagai skema DRM dengan konten streaming.

    Anda dapat menggunakan MediaDrm untuk memperoleh pesan permintaan kunci buram dan memproses pesan respons kunci dari server untuk akuisisi dan penyediaan lisensi. Aplikasi Anda bertanggung jawab untuk menangani komunikasi jaringan dengan server; class MediaDrm hanya memberikan kemampuan untuk membuat dan memproses pesan.

    MediaDrm API dimaksudkan untuk digunakan bersama dengan MediaCodec API yang diperkenalkan di Android 4.1 (API level 16), termasuk MediaCodec untuk mengenkode dan mendekode konten Anda, MediaCrypto untuk menangani konten terenkripsi, dan MediaExtractor untuk mengekstrak dan melakukan demuxing konten.

    Anda harus membuat objek MediaExtractor dan MediaCodec terlebih dahulu. Kemudian, Anda dapat mengakses UUID yang mengidentifikasi skema DRM , biasanya dari metadata dalam konten, dan menggunakannya untuk membuat instance objek MediaDrm dengan konstruktornya.

    Encoding video dari Surface

    Android 4.1 (API level 16) menambahkan class MediaCodec untuk encoding dan decoding konten media tingkat rendah. Saat mengenkode video, Android 4.1 mengharuskan Anda menyediakan media dengan array ByteBuffer, tetapi Android 4.3 sekarang memungkinkan Anda menggunakan Surface sebagai input ke encoder. Misalnya, hal ini memungkinkan Anda mengenkode input dari file video yang ada atau menggunakan frame yang dihasilkan dari OpenGL ES.

    Untuk menggunakan Surface sebagai input ke encoder, panggil configure() untuk MediaCodec terlebih dahulu. Lalu, panggil createInputSurface() untuk menerima Surface tempat Anda dapat melakukan streaming media.

    Misalnya, Anda dapat menggunakan Surface yang diberikan sebagai jendela untuk konteks OpenGL dengan meneruskannya ke eglCreateWindowSurface(). Kemudian, saat merender platform, panggil eglSwapBuffers() untuk meneruskan frame ke MediaCodec.

    Untuk memulai encoding, panggil start() di MediaCodec. Setelah selesai, panggil signalEndOfInputStream() untuk menghentikan encoding, dan panggil release() pada Surface.

    Muxing media

    Class MediaMuxer yang baru memungkinkan multipleksing antara satu streaming audio dan satu streaming video. API ini berfungsi sebagai pasangan untuk class MediaExtractor yang ditambahkan di Android 4.2 untuk media de-multiplexing (demuxing).

    Format output yang didukung ditentukan dalam MediaMuxer.OutputFormat. Saat ini, MP4 adalah satu-satunya format output yang didukung dan MediaMuxer saat ini hanya mendukung satu streaming audio dan/atau satu streaming video dalam satu waktu.

    MediaMuxer sebagian besar dirancang untuk berfungsi dengan MediaCodec sehingga Anda dapat melakukan pemrosesan video melalui MediaCodec, lalu menyimpan output ke file MP4 melalui MediaMuxer. Anda juga dapat menggunakan MediaMuxer yang dikombinasikan dengan MediaExtractor untuk melakukan pengeditan media tanpa perlu mengenkode atau mendekode.

    Progres dan scrubbing pemutaran untuk RemoteControlClient

    Di Android 4.0 (API level 14), RemoteControlClient ditambahkan untuk mengaktifkan kontrol pemutaran media dari klien remote kontrol seperti kontrol yang tersedia di layar kunci. Android 4.3 kini menyediakan kemampuan bagi pengontrol tersebut untuk menampilkan posisi pemutaran dan kontrol untuk menggosok pemutaran. Jika telah mengaktifkan remote control untuk aplikasi media dengan RemoteControlClient API, Anda dapat mengizinkan pengosongan pemutaran dengan mengimplementasikan dua antarmuka baru.

    Pertama, Anda harus mengaktifkan flag FLAG_KEY_MEDIA_POSITION_UPDATE dengan meneruskannya ke setTransportControlsFlags().

    Kemudian, terapkan dua antarmuka baru berikut:

    RemoteControlClient.OnGetPlaybackPositionListener
    Ini termasuk callback onGetPlaybackPosition(), yang meminta posisi media saat ini ketika remote control perlu memperbarui progres di UI-nya.
    RemoteControlClient.OnPlaybackPositionUpdateListener
    Ini termasuk callback onPlaybackPositionUpdate(), yang memberi tahu aplikasi Anda kode waktu baru untuk media saat pengguna menggeser pemutaran dengan UI remote control.

    Setelah Anda memperbarui pemutaran dengan posisi yang baru, panggil setPlaybackState() untuk menunjukkan status, posisi, dan kecepatan pemutaran yang baru.

    Setelah menentukan antarmuka ini, Anda dapat menetapkannya untuk RemoteControlClient dengan memanggil setOnGetPlaybackPositionListener() dan setPlaybackPositionUpdateListener().

    Grafis

    Dukungan untuk OpenGL ES 3.0

    Android 4.3 menambahkan antarmuka Java dan dukungan native untuk OpenGL ES 3.0. Fungsi baru utama yang disediakan di OpenGL ES 3.0 mencakup:

    • Akselerasi efek visual lanjutan
    • Kompresi tekstur ETC2/EAC berkualitas tinggi sebagai fitur standar
    • Versi baru bahasa shading GLSL ES dengan dukungan bilangan bulat dan floating point 32 bit
    • Rendering tekstur lanjutan
    • Standardisasi ukuran tekstur dan format buffer render yang lebih luas

    Antarmuka Java untuk OpenGL ES 3.0 di Android dilengkapi dengan GLES30. Saat menggunakan OpenGL ES 3.0, pastikan Anda mendeklarasikannya dalam file manifes dengan tag <uses-feature> dan atribut android:glEsVersion. Contoh:

    <manifest>
        <uses-feature android:glEsVersion="0x00030000" />
        ...
    </manifest>
    

    Jangan lupa untuk menentukan konteks OpenGL ES dengan memanggil setEGLContextClientVersion(), dengan meneruskan 3 sebagai versi.

    Untuk informasi penggunaan OpenGL ES lebih lanjut, termasuk cara memeriksa versi OpenGL ES yang didukung perangkat saat runtime, lihat panduan OpenGL ES API.

    Mipmapping untuk drawable

    Menggunakan mipmap sebagai sumber untuk bitmap atau drawable adalah cara sederhana untuk memberikan gambar berkualitas dan berbagai skala gambar, yang dapat sangat berguna jika Anda ingin gambar diskalakan selama animasi.

    Android 4.2 (API level 17) menambahkan dukungan untuk mipmap di class Bitmap—Android menukar gambar mip di Bitmap setelah Anda menyediakan sumber mipmap dan telah mengaktifkan setHasMipMap(). Kini di Android 4.3, Anda juga dapat mengaktifkan mipmap untuk objek BitmapDrawable, dengan menyediakan aset mipmap dan menyetel atribut android:mipMap dalam file resource bitmap atau dengan memanggil hasMipMap().

    Antarmuka Pengguna

    Overlay tampilan

    Class ViewOverlay yang baru menyediakan lapisan transparan di atas View tempat Anda dapat menambahkan konten visual dan tidak memengaruhi hierarki tata letak. Anda bisa mendapatkan ViewOverlay untuk View mana pun dengan memanggil getOverlay(). Overlay selalu memiliki ukuran dan posisi yang sama dengan tampilan host (tampilan tempatnya dibuat), memungkinkan Anda menambahkan konten yang muncul di depan tampilan host, tetapi tidak dapat memperluas batas tampilan host tersebut.

    Penggunaan ViewOverlay sangat berguna saat Anda ingin membuat animasi seperti menggeser tampilan di luar penampungnya atau memindahkan item di sekitar layar tanpa memengaruhi hierarki tampilan. Namun, karena area overlay yang dapat digunakan dibatasi pada area yang sama dengan tampilan host, jika ingin menganimasikan tampilan yang bergerak ke luar posisinya dalam tata letak, Anda harus menggunakan overlay dari tampilan induk yang memiliki batas tata letak yang diinginkan.

    Bila membuat overlay untuk tampilan widget seperti Button, Anda dapat menambahkan objek Drawable ke overlay dengan memanggil add(Drawable). Jika Anda memanggil getOverlay() untuk tampilan tata letak, seperti RelativeLayout, objek yang ditampilkan adalah ViewGroupOverlay. Class ViewGroupOverlay adalah subclass dari ViewOverlay yang juga memungkinkan Anda menambahkan objek View dengan memanggil add(View).

    Catatan: Semua drawable dan tampilan yang Anda tambahkan ke overlay hanya bersifat visual. Kamera tidak dapat menerima fokus atau peristiwa input.

    Misalnya, kode berikut menganimasikan tampilan yang bergeser ke kanan dengan menempatkan tampilan di overlay tampilan induk, lalu menjalankan animasi terjemahan pada tampilan tersebut:

    Kotlin

    val view: View? = findViewById(R.id.view_to_remove)
    val container: ViewGroup? = view?.parent as ViewGroup
    
    container?.apply {
        overlay.add(view)
        ObjectAnimator.ofFloat(view, "translationX", right.toFloat())
                .start()
    }
    

    Java

    View view = findViewById(R.id.view_to_remove);
    ViewGroup container = (ViewGroup) view.getParent();
    container.getOverlay().add(view);
    ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationX", container.getRight());
    anim.start();
    

    Tata letak batas optik

    Untuk tampilan yang berisi gambar latar nine-patch, kini Anda bisa menentukan bahwa tampilan tersebut harus diratakan dengan tampilan di sekitarnya berdasarkan batas "optik" gambar latar, bukan batas "klip" tampilan.

    Misalnya, gambar 1 dan 2 masing-masing menunjukkan tata letak yang sama, tetapi versi pada gambar 1 menggunakan batas klip (perilaku default), sedangkan gambar 2 menggunakan batas optik. Karena gambar nine-patch yang digunakan untuk tombol dan bingkai foto menyertakan padding di sekitar tepinya, gambar tersebut tidak tampak sejajar satu sama lain atau dengan teks saat menggunakan batas klip.

    Catatan: Screenshot di gambar 1 dan 2 mengaktifkan setelan developer "Tampilkan batas tata letak". Untuk setiap tampilan, garis merah menunjukkan batas optik, garis biru menunjukkan batas klip, dan merah muda menunjukkan margin.

    Gambar 1. Tata letak menggunakan batas klip (default).

    Gambar 2. Tata letak menggunakan batas optik.

    Untuk menyelaraskan tampilan berdasarkan batas optiknya, setel atribut android:layoutMode ke "opticalBounds" di salah satu tata letak induk. Contoh:

    <LinearLayout android:layoutMode="opticalBounds" ... >
    

    Gambar 3. Tampilan nine-patch tombol Holo yang diperbesar dengan batas optik.

    Agar berfungsi, gambar nine-patch yang diterapkan pada latar belakang tampilan harus menentukan batas optik menggunakan garis merah di sepanjang bagian bawah dan kanan file nine-patch (seperti yang ditunjukkan pada gambar 3). Garis merah menunjukkan area yang harus dikurangi dari batas klip, sehingga menyisakan batas optik gambar.

    Jika Anda mengaktifkan batas optik untuk ViewGroup dalam tata letak, semua tampilan turunan akan mewarisi mode tata letak batas optik, kecuali jika Anda menggantinya untuk sebuah grup dengan menetapkan android:layoutMode ke "clipBounds". Semua elemen tata letak juga mengikuti batas optik tampilan turunannya, menyesuaikan batasnya sendiri berdasarkan batas optik tampilan di dalamnya. Namun, elemen tata letak (subclass ViewGroup) saat ini tidak mendukung batas optik untuk gambar nine-patch yang diterapkan ke latar belakangnya sendiri.

    Jika Anda membuat tampilan kustom dengan membuat subclass View, ViewGroup, atau subclass-nya, tampilan Anda akan mewarisi perilaku terikat optik ini.

    Catatan: Semua widget yang didukung oleh tema Holo telah diupdate dengan batas optik, termasuk Button, Spinner, EditText, dan lainnya. Jadi, Anda dapat langsung memanfaatkan dengan menetapkan atribut android:layoutMode ke "opticalBounds" jika aplikasi Anda menerapkan tema Holo (Theme.Holo, Theme.Holo.Light, dll.).

    Untuk menentukan batas optik bagi gambar nine-patch Anda sendiri dengan alat Draw 9-patch, tahan Control saat mengklik piksel batas.

    Animasi untuk nilai Rect

    Anda sekarang dapat menganimasikan antara dua nilai Rect dengan RectEvaluator baru. Class baru ini adalah implementasi dari TypeEvaluator yang dapat Anda teruskan ke ValueAnimator.setEvaluator().

    Pemasangan jendela dan pemroses fokus

    Sebelumnya, jika Anda ingin memproses kapan tampilan terpasang/melepaskan ke jendela atau saat fokusnya berubah, Anda perlu mengganti class View untuk mengimplementasikan onAttachedToWindow() dan onDetachedFromWindow(), atau onWindowFocusChanged().

    Sekarang, untuk menerima peristiwa lampiran dan pelepasan, Anda dapat mengimplementasikan ViewTreeObserver.OnWindowAttachListener dan menetapkannya pada tampilan dengan addOnWindowAttachListener(). Dan untuk menerima peristiwa fokus, Anda dapat mengimplementasikan ViewTreeObserver.OnWindowFocusChangeListener dan menetapkannya pada tampilan dengan addOnWindowFocusChangeListener().

    Dukungan pemindaian berlebih TV

    Untuk memastikan aplikasi Anda mengisi seluruh layar di setiap televisi, kini Anda dapat mengaktifkan overscan untuk tata letak aplikasi. Mode overscan ditentukan oleh flag FLAG_LAYOUT_IN_OVERSCAN, yang dapat Anda aktifkan dengan tema platform seperti Theme_DeviceDefault_NoActionBar_Overscan atau dengan mengaktifkan gaya windowOverscan dalam tema kustom.

    Orientasi layar

    Atribut screenOrientation tag <activity> kini mendukung nilai tambahan untuk mengikuti preferensi pengguna terhadap rotasi otomatis:

    "userLandscape"
    Berperilaku sama seperti "sensorLandscape", kecuali jika pengguna menonaktifkan putar otomatis, aplikasi akan terkunci dalam orientasi lanskap normal dan tidak akan terbalik.
    "userPortrait"
    Berperilaku sama seperti "sensorPortrait", kecuali jika pengguna menonaktifkan putar otomatis, layar akan terkunci dalam orientasi potret normal dan tidak akan dibalik.
    "fullUser"
    Berperilaku sama seperti "fullSensor" dan memungkinkan rotasi ke keempat arah, kecuali jika pengguna menonaktifkan putar otomatis, maka akan terkunci dalam orientasi pilihan pengguna.

    Selain itu, Anda kini juga dapat mendeklarasikan "locked" untuk mengunci orientasi aplikasi ke orientasi layar saat ini.

    Animasi rotasi

    Kolom rotationAnimation baru di WindowManager memungkinkan Anda memilih antara salah satu dari tiga animasi yang ingin digunakan saat sistem beralih orientasi layar. Tiga animasi tersebut adalah:

    Catatan: Animasi ini hanya tersedia jika Anda telah menetapkan aktivitas untuk menggunakan mode "layar penuh", yang dapat Anda aktifkan dengan tema seperti Theme.Holo.NoActionBar.Fullscreen.

    Misalnya, berikut adalah cara mengaktifkan animasi "crossfade":

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        val params: WindowManager.LayoutParams = window.attributes
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE
        window.attributes = params
        ...
    }
    

    Java

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
        getWindow().setAttributes(params);
        ...
    }
    

    Masukan Pengguna

    Tipe sensor baru

    Sensor TYPE_GAME_ROTATION_VECTOR baru memungkinkan Anda mendeteksi rotasi perangkat tanpa mengkhawatirkan gangguan magnetik. Tidak seperti sensor TYPE_ROTATION_VECTOR, TYPE_GAME_ROTATION_VECTOR tidak didasarkan pada utara magnetik.

    Sensor TYPE_GYROSCOPE_UNCALIBRATED dan TYPE_MAGNETIC_FIELD_UNCALIBRATED yang baru memberikan data sensor mentah tanpa pertimbangan untuk estimasi bias. Artinya, sensor TYPE_GYROSCOPE dan TYPE_MAGNETIC_FIELD yang ada menyediakan data sensor yang memperhitungkan perkiraan bias dari giroskop dan besi keras di perangkat. Sedangkan versi baru "tidak dikalibrasi" sensor ini memberikan data sensor mentah dan menawarkan estimasi nilai bias secara terpisah. Sensor ini memungkinkan Anda memberikan kalibrasi kustom sendiri untuk data sensor dengan meningkatkan estimasi bias dengan data eksternal.

    Pemroses Notifikasi

    Android 4.3 menambahkan class layanan baru, NotificationListenerService, yang memungkinkan aplikasi Anda menerima informasi tentang notifikasi baru saat diposting oleh sistem.

    Jika aplikasi Anda saat ini menggunakan API layanan aksesibilitas untuk mengakses notifikasi sistem, Anda harus memperbarui aplikasi untuk menggunakan API ini.

    Penyedia Kontak

    Kueri untuk "contactables"

    Kueri Penyedia Kontak yang baru, Contactables.CONTENT_URI, memberikan cara yang efisien untuk mendapatkan satu Cursor yang berisi semua alamat email dan nomor telepon milik semua kontak yang cocok dengan kueri yang ditentukan.

    Kueri untuk delta kontak

    API baru telah ditambahkan ke Penyedia Kontak yang memungkinkan Anda mengajukan kueri perubahan terbaru pada data kontak secara efisien. Sebelumnya, aplikasi Anda dapat diberi tahu ketika ada sesuatu dalam data kontak yang berubah, namun Anda tidak akan tahu persis apa yang berubah dan Anda perlu mengambil semua kontak lalu mengulanginya untuk menemukan perubahan tersebut.

    Untuk melacak perubahan pada penyisipan dan pembaruan, Anda kini dapat menyertakan parameter CONTACT_LAST_UPDATED_TIMESTAMP dengan pilihan Anda untuk hanya mengkueri kontak yang telah berubah sejak terakhir kali Anda membuat kueri kepada penyedia.

    Untuk melacak kontak yang telah dihapus, tabel baru ContactsContract.DeletedContacts menyediakan log kontak yang telah dihapus (tetapi setiap kontak yang dihapus disimpan dalam tabel ini untuk jangka waktu terbatas). Serupa dengan CONTACT_LAST_UPDATED_TIMESTAMP, Anda dapat menggunakan parameter pilihan baru, CONTACT_DELETED_TIMESTAMP untuk memeriksa kontak mana yang telah dihapus sejak terakhir kali Anda mengkueri penyedia. Tabel ini juga berisi konstanta DAYS_KEPT_MILLISECONDS yang berisi jumlah hari (dalam milidetik) saat log akan disimpan.

    Selain itu, Penyedia Kontak kini menyiarkan tindakan CONTACTS_DATABASE_CREATED ketika pengguna menghapus penyimpanan kontak melalui menu setelan sistem, yang secara efektif membuat ulang database Penyedia Kontak. Hal ini dimaksudkan untuk memberi tahu aplikasi bahwa aplikasi perlu menghapus semua informasi kontak yang telah disimpan dan memuatnya ulang dengan kueri baru.

    Untuk mengetahui kode contoh yang menggunakan API ini guna memeriksa perubahan pada kontak, lihat contoh ApiDemos yang tersedia di download Contoh SDK.

    Pelokalan

    Peningkatan dukungan untuk teks dua arah

    Android versi sebelumnya mendukung bahasa dan tata letak kanan-ke-kiri (RTL), tetapi terkadang tidak menangani teks arah campuran dengan benar. Jadi, Android 4.3 menambahkan BidiFormatter API yang membantu Anda memformat teks dengan benar menggunakan konten arah berlawanan tanpa merusak bagian mana pun.

    Misalnya, jika ingin membuat kalimat dengan variabel string, seperti "Apakah maksud Anda 15 Bay Street, Laurel, CA?", Anda biasanya meneruskan resource string yang dilokalkan dan variabel tersebut ke String.format():

    Kotlin

    val suggestion = String.format(resources.getString(R.string.did_you_mean), address)
    

    Java

    Resources res = getResources();
    String suggestion = String.format(res.getString(R.string.did_you_mean), address);
    

    Namun, jika lokalitas tersebut adalah bahasa Ibrani, string berformat akan keluar seperti ini:

    האם התכוונת ל 15 Bay Street, Laurel, CA?

    Jawaban Anda salah karena "15" seharusnya berada di sebelah "Bay Street". Solusinya adalah menggunakan BidiFormatter dan metode unicodeWrap()-nya. Misalnya, kode di atas menjadi:

    Kotlin

    val bidiFormatter = BidiFormatter.getInstance()
    val suggestion = String.format(
            resources.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address)
    )
    

    Java

    Resources res = getResources();
    BidiFormatter bidiFormatter = BidiFormatter.getInstance();
    String suggestion = String.format(res.getString(R.string.did_you_mean),
            bidiFormatter.unicodeWrap(address));
    

    Secara default, unicodeWrap() menggunakan heuristik estimasi arah kuat pertama, yang dapat keliru jika sinyal pertama untuk arah teks tidak mewakili arah yang sesuai untuk konten secara keseluruhan. Jika perlu, Anda dapat menentukan heuristik yang berbeda dengan meneruskan salah satu konstanta TextDirectionHeuristic dari TextDirectionHeuristics ke unicodeWrap().

    Catatan: API baru ini juga tersedia untuk Android versi sebelumnya melalui Support Library Android, dengan class BidiFormatter dan API terkait.

    Layanan Aksesibilitas

    Menangani peristiwa penting

    AccessibilityService kini dapat menerima callback untuk peristiwa input kunci dengan metode callback onKeyEvent(). Hal ini memungkinkan layanan aksesibilitas Anda menangani input untuk perangkat input berbasis tombol seperti keyboard dan menerjemahkan peristiwa tersebut menjadi tindakan khusus yang sebelumnya mungkin hanya dapat dilakukan dengan input sentuh atau tombol arah perangkat.

    Pilih teks dan salin/tempel

    AccessibilityNodeInfo kini menyediakan API yang memungkinkan AccessibilityService memilih, memotong, menyalin, dan menempelkan teks dalam node.

    Untuk menentukan pilihan teks yang akan dipotong atau disalin, layanan aksesibilitas Anda dapat menggunakan tindakan baru, ACTION_SET_SELECTION, yang meneruskan posisi awal dan akhir pemilihan dengan ACTION_ARGUMENT_SELECTION_START_INT dan ACTION_ARGUMENT_SELECTION_END_INT. Atau, Anda dapat memilih teks dengan memanipulasi posisi kursor menggunakan tindakan yang ada, ACTION_NEXT_AT_MOVEMENT_GRANULARITY (sebelumnya hanya untuk memindahkan posisi kursor), dan menambahkan argumen ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN.

    Anda kemudian dapat memotong atau menyalin dengan ACTION_CUT, ACTION_COPY, lalu menempelkannya nanti dengan ACTION_PASTE.

    Catatan: API baru ini juga tersedia untuk Android versi sebelumnya melalui Support Library Android, dengan class AccessibilityNodeInfoCompat.

    Mendeklarasikan fitur aksesibilitas

    Mulai Android 4.3, layanan aksesibilitas harus menyatakan kemampuan aksesibilitas dalam file metadatanya untuk menggunakan fitur aksesibilitas tertentu. Jika kemampuan tidak diminta dalam file metadata, fitur tersebut tidak akan beroperasi. Untuk mendeklarasikan kemampuan aksesibilitas layanan, Anda harus menggunakan atribut XML yang terkait dengan berbagai konstanta "kemampuan" dalam class AccessibilityServiceInfo.

    Misalnya, jika layanan tidak meminta kemampuan flagRequestFilterKeyEvents, layanan tidak akan menerima peristiwa tombol.

    Pengujian dan Proses Debug

    Pengujian UI otomatis

    Class UiAutomation baru menyediakan API yang memungkinkan Anda menyimulasikan tindakan pengguna untuk otomatisasi pengujian. Dengan menggunakan AccessibilityService API platform, API UiAutomation memungkinkan Anda memeriksa konten layar dan memasukkan keyboard arbitrer dan peristiwa sentuh.

    Untuk mendapatkan instance UiAutomation, panggil Instrumentation.getUiAutomation(). Agar dapat berfungsi, Anda harus menyediakan opsi -w dengan perintah instrument saat menjalankan InstrumentationTestCase dari adb shell.

    Dengan instance UiAutomation, Anda dapat mengeksekusi peristiwa arbitrer untuk menguji aplikasi dengan memanggil executeAndWaitForEvent(), meneruskan Runnable untuk dijalankan, periode waktu tunggu untuk operasi, dan implementasi antarmuka UiAutomation.AccessibilityEventFilter. Dalam implementasi UiAutomation.AccessibilityEventFilter, Anda akan menerima panggilan yang memungkinkan Anda memfilter peristiwa yang Anda minati dan menentukan keberhasilan atau kegagalan kasus pengujian tertentu.

    Untuk mengamati semua peristiwa selama pengujian, buat implementasi UiAutomation.OnAccessibilityEventListener dan teruskan ke setOnAccessibilityEventListener(). Antarmuka pemroses Anda kemudian menerima panggilan ke onAccessibilityEvent() setiap kali terjadi peristiwa, menerima objek AccessibilityEvent yang menjelaskan peristiwa tersebut.

    Ada berbagai operasi lain yang ditampilkan oleh UiAutomation API pada tingkat yang sangat rendah untuk mendorong pengembangan alat pengujian UI seperti uiautomator. Misalnya, UiAutomation juga dapat:

    • Memasukkan peristiwa input
    • Mengubah orientasi layar
    • Mengambil screenshot

    Dan yang paling penting untuk alat pengujian UI, UiAutomation API berfungsi di seluruh batas aplikasi, tidak seperti yang ada di Instrumentation.

    Peristiwa Systrace untuk aplikasi

    Android 4.3 menambahkan class Trace dengan dua metode statis, beginSection() dan endSection(), yang memungkinkan Anda menentukan blok kode yang akan disertakan dengan laporan systrace. Dengan membuat bagian kode yang dapat dilacak di aplikasi, log systrace memberi Anda analisis yang jauh lebih mendetail terkait lokasi terjadinya pelambatan dalam aplikasi.

    Untuk mengetahui informasi tentang penggunaan alat Systrace, baca Menganalisis Tampilan dan Performa dengan Systrace.

    Keamanan

    Penyimpanan kunci Android untuk kunci pribadi aplikasi

    Android kini menawarkan Penyedia Keamanan Java kustom di fasilitas KeyStore, yang disebut Android Key Store, yang memungkinkan Anda membuat dan menyimpan kunci pribadi yang hanya dapat dilihat dan digunakan oleh aplikasi Anda. Untuk memuat Android Key Store, teruskan "AndroidKeyStore" ke KeyStore.getInstance().

    Untuk mengelola kredensial pribadi aplikasi Anda di Android Key Store, buat kunci baru dengan KeyPairGenerator dengan KeyPairGeneratorSpec. Pertama-tama, dapatkan instance KeyPairGenerator dengan memanggil getInstance(). Lalu, panggil initialize(), dengan meneruskan instance KeyPairGeneratorSpec, yang dapat Anda gunakan KeyPairGeneratorSpec.Builder. Terakhir, dapatkan KeyPair dengan memanggil generateKeyPair().

    Penyimpanan kredensial hardware

    Android kini juga mendukung penyimpanan yang didukung hardware untuk kredensial KeyChain Anda, sehingga memberikan lebih banyak keamanan dengan membuat kunci tidak tersedia untuk diekstrak. Artinya, setelah kunci berada di penyimpanan kunci yang didukung hardware (Secure Element, TPM, atau TrustZone), kunci dapat digunakan untuk operasi kriptografi, tetapi materi kunci pribadi tidak dapat diekspor. Bahkan {i>kernel<i} OS tidak dapat mengakses materi kunci ini. Meskipun tidak semua perangkat Android mendukung penyimpanan hardware, Anda dapat memeriksa pada runtime apakah penyimpanan yang didukung hardware tersedia dengan memanggil KeyChain.IsBoundKeyAlgorithm().

    Deklarasi Manifes

    Fitur wajib yang bisa dideklarasikan

    Nilai berikut kini didukung dalam elemen <uses-feature> sehingga Anda dapat memastikan bahwa aplikasi hanya diinstal di perangkat yang menyediakan fitur yang dibutuhkan aplikasi Anda.

    FEATURE_APP_WIDGETS
    Mendeklarasikan bahwa aplikasi Anda menyediakan widget aplikasi dan hanya boleh diinstal di perangkat yang menyertakan Layar utama atau lokasi serupa tempat pengguna dapat menyematkan widget aplikasi. Contoh:
    <uses-feature android:name="android.software.app_widgets" android:required="true" />
    
    FEATURE_HOME_SCREEN
    Mendeklarasikan bahwa aplikasi Anda berperilaku sebagai pengganti Layar utama dan hanya boleh diinstal di perangkat yang mendukung aplikasi Layar utama pihak ketiga. Contoh:
    <uses-feature android:name="android.software.home_screen" android:required="true" />
    
    FEATURE_INPUT_METHODS
    Mendeklarasikan bahwa aplikasi Anda menyediakan metode input kustom (keyboard yang dibuat dengan InputMethodService) dan hanya boleh diinstal di perangkat yang mendukung metode input pihak ketiga. Contoh:
    <uses-feature android:name="android.software.input_methods" android:required="true" />
    
    FEATURE_BLUETOOTH_LE
    Mendeklarasikan bahwa aplikasi Anda menggunakan Bluetooth Low Energy API dan hanya boleh diinstal di perangkat yang mampu berkomunikasi dengan perangkat lain melalui Bluetooth Hemat Energi. Contoh:
    <uses-feature android:name="android.software.bluetooth_le" android:required="true" />
    

    Izin pengguna

    Nilai berikut kini didukung di <uses-permission> untuk mendeklarasikan izin yang diperlukan aplikasi Anda untuk mengakses API tertentu.

    BIND_NOTIFICATION_LISTENER_SERVICE
    Diperlukan untuk menggunakan NotificationListenerService API baru.
    SEND_RESPOND_VIA_MESSAGE
    Diperlukan untuk menerima intent ACTION_RESPOND_VIA_MESSAGE.

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