Android 17 memperkenalkan fitur dan API baru yang hebat untuk para developer. Bagian berikut merangkum fitur ini untuk membantu Anda mulai menggunakan API terkait.
Untuk melihat daftar mendetail tentang API yang baru, diubah, dan dihapus, baca laporan perbedaan API. Untuk mengetahui detail tentang API baru, buka referensi API Android — API baru ditandai agar lebih mudah dilihat.
Anda juga harus meninjau area tempat perubahan platform dapat memengaruhi aplikasi Anda. Untuk informasi selengkapnya, lihat halaman berikut:
- Perubahan perilaku yang memengaruhi aplikasi saat menargetkan Android 17
- Perubahan perilaku yang memengaruhi semua aplikasi terlepas dari
targetSdkVersion.
Fungsi inti
Android 17 menambahkan fitur baru berikut terkait fungsi inti Android.
Pemicu ProfilingManager baru
Android 17 menambahkan beberapa pemicu sistem baru ke ProfilingManager untuk
membantu Anda mengumpulkan data mendalam guna men-debug masalah performa.
Pemicu baru tersebut adalah:
TRIGGER_TYPE_COLD_START: Pemicu terjadi selama mulai dingin aplikasi. API ini memberikan contoh call stack dan rekaman aktivitas sistem dalam respons.TRIGGER_TYPE_OOM: Pemicuan terjadi saat aplikasi memunculkanOutOfMemoryErrordan memberikan Java Heap Dump sebagai respons.TRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE: Pemicu terjadi saat aplikasi dihentikan karena penggunaan CPU yang tidak normal dan berlebihan, serta memberikan sampel call stack sebagai respons.
Untuk memahami cara menyiapkan pemicu sistem, lihat dokumentasi tentang pembuatan profil berbasis pemicu dan cara mengambil dan menganalisis data pembuatan profil.
JobDebugInfo API
Android 17 memperkenalkan API JobDebugInfo baru untuk membantu developer men-debug
tugas JobScheduler mereka--mengapa tugas tidak berjalan, berapa lama tugas berjalan, dan
informasi gabungan lainnya.
Metode pertama dari JobDebugInfo API yang diperluas adalah
getPendingJobReasonStats(), yang menampilkan peta alasan mengapa tugas berada dalam
status eksekusi tertunda dan durasi tertunda kumulatifnya masing-masing. Metode ini menggabungkan metode getPendingJobReasonsHistory() dan
getPendingJobReasons() untuk memberi Anda insight tentang alasan tugas terjadwal tidak berjalan seperti yang diharapkan, tetapi menyederhanakan pengambilan informasi dengan membuat durasi dan alasan tugas tersedia dalam satu metode.
Misalnya, untuk jobId yang ditentukan, metode dapat menampilkan
PENDING_JOB_REASON_CONSTRAINT_CHARGING dan durasi 60000 md, yang menunjukkan
tugas tertunda selama 60000 md karena batasan pengisian daya tidak
terpenuhi.
Privasi
Android 17 menyertakan fitur baru berikut untuk meningkatkan privasi pengguna.
Pemilih kontak Android
Pemilih Kontak Android adalah antarmuka standar yang dapat dijelajahi bagi pengguna untuk membagikan kontak ke aplikasi Anda. Tersedia di perangkat yang menjalankan Android 17 atau yang lebih tinggi, pemilih ini menawarkan alternatif yang menjaga privasi untuk izin READ_CONTACTS yang luas. Daripada meminta
akses ke seluruh buku alamat pengguna, aplikasi Anda menentukan kolom data yang
diperlukan, seperti nomor telepon atau alamat email, dan pengguna memilih kontak
tertentu untuk dibagikan. Hal ini memberi aplikasi Anda akses baca hanya ke data yang dipilih, sehingga memastikan kontrol terperinci sekaligus memberikan pengalaman pengguna yang konsisten dengan kemampuan penelusuran bawaan, penggantian profil, dan multi-seleksi tanpa harus membangun atau memelihara UI.
Untuk mengetahui informasi selengkapnya, lihat dokumentasi pemilih kontak.
Keamanan
Android 17 menambahkan fitur baru berikut untuk meningkatkan keamanan perangkat dan aplikasi.
Mode Perlindungan Lanjutan Android (AAPM)
Mode Perlindungan Lanjutan Android menawarkan serangkaian fitur keamanan baru yang canggih bagi pengguna Android, yang menandai langkah signifikan dalam mengamankan pengguna—terutama mereka yang berisiko lebih tinggi—dari serangan canggih. Dirancang sebagai fitur keikutsertaan, AAPM diaktifkan dengan satu setelan konfigurasi yang dapat diaktifkan pengguna kapan saja untuk menerapkan serangkaian perlindungan keamanan yang berpihak.
Konfigurasi inti ini mencakup pemblokiran penginstalan aplikasi dari sumber tidak dikenal (pengunduhan dari luar Play Store), pembatasan sinyal data USB, dan mewajibkan pemindaian Google Play Protect, yang secara signifikan mengurangi area permukaan serangan perangkat.
Developer dapat berintegrasi dengan fitur ini menggunakan API
AdvancedProtectionManager untuk mendeteksi status mode, sehingga aplikasi dapat
secara otomatis mengadopsi postur keamanan yang lebih kuat atau membatasi
fungsi berisiko tinggi saat pengguna telah mengaktifkannya.
Konektivitas
Android 17 menambahkan fitur berikut untuk meningkatkan konektivitas perangkat dan aplikasi.
Jaringan satelit yang dibatasi
Menerapkan pengoptimalan agar aplikasi dapat berfungsi secara efektif melalui jaringan satelit dengan bandwidth rendah.
Pengalaman pengguna dan UI sistem
Android 17 menyertakan perubahan berikut untuk meningkatkan pengalaman pengguna.
Handoff
Penyerahan adalah fitur dan API baru yang akan hadir di Android 17 yang dapat diintegrasikan oleh developer aplikasi untuk memberikan kontinuitas lintas perangkat bagi pengguna mereka. Fitur ini memungkinkan pengguna memulai aktivitas aplikasi di satu perangkat Android dan mentransisikannya ke perangkat Android lain. Pengalihan berjalan di latar belakang perangkat pengguna dan menampilkan aktivitas yang tersedia dari perangkat terdekat pengguna lainnya melalui berbagai titik entri, seperti peluncur dan taskbar, di perangkat penerima.
Aplikasi dapat menetapkan Handoff untuk meluncurkan aplikasi Android native yang sama, jika aplikasi tersebut diinstal dan tersedia di perangkat penerima. Dalam alur aplikasi-ke-aplikasi ini, pengguna ditautkan secara mendalam ke aktivitas yang ditentukan. Atau, Penyerahan dari aplikasi ke web dapat ditawarkan sebagai opsi penggantian atau diterapkan langsung dengan Penyerahan URL.
Dukungan Handoff diimplementasikan per aktivitas. Untuk mengaktifkan Handoff, panggil
metode setHandoffEnabled() untuk aktivitas. Data tambahan mungkin perlu diteruskan bersama dengan pengalihan sehingga aktivitas yang dibuat ulang di perangkat penerima dapat memulihkan status yang sesuai. Terapkan callback
onHandoffActivityRequested() untuk menampilkan objek HandoffActivityData
yang berisi detail yang menentukan cara Handoff harus menangani dan membuat ulang
aktivitas di perangkat penerima.
Update Langsung - Semantic color API
Dengan Android 17, Update Langsung meluncurkan Semantic Coloring API untuk mendukung warna dengan makna universal.
Class berikut mendukung pewarnaan semantik:
NotificationNotification.MetricNotification.ProgressStyle.PointNotification.ProgressStyle.Segment
Mewarnai
- Hijau: Terkait dengan keselamatan. Warna ini harus digunakan untuk kasus yang memberi tahu orang lain bahwa Anda berada dalam situasi aman.
- Oranye: Untuk menunjukkan kehati-hatian dan menandai bahaya fisik. Warna ini harus digunakan dalam situasi saat pengguna perlu memperhatikan setelan perlindungan yang lebih baik.
- Merah: Umumnya menunjukkan bahaya, berhenti. Harus ditampilkan untuk kasus yang memerlukan perhatian orang dengan segera.
- Biru: Warna netral untuk konten yang bersifat informatif dan harus terlihat berbeda dari konten lainnya.
Contoh berikut menunjukkan cara menerapkan gaya semantik ke teks dalam notifikasi:
val ssb = SpannableStringBuilder()
.append("Colors: ")
.append("NONE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_UNSPECIFIED), 0)
.append(", ")
.append("INFO", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_INFO), 0)
.append(", ")
.append("SAFE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_SAFE), 0)
.append(", ")
.append("CAUTION", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_CAUTION), 0)
.append(", ")
.append("DANGER", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_DANGER), 0)
Notification.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_icon)
.setContentTitle("Hello World!")
.setContentText(ssb)
.setOngoing(true)
.setRequestPromotedOngoing(true)
UWB Downlink-TDoA API untuk Android 17
Pengukuran Downlink Time Difference of Arrival (DL-TDoA) memungkinkan perangkat menentukan posisinya relatif terhadap beberapa anchor dengan mengukur waktu kedatangan sinyal relatif.
Cuplikan berikut menunjukkan cara menginisialisasi Ranging Manager, memverifikasi kemampuan perangkat, dan memulai sesi DL-TDoA:
Kotlin
class RangingApp {
fun initDlTdoa(context: Context) {
// Initialize the Ranging Manager
val rangingManager = context.getSystemService(RangingManager::class.java)
// Register for device capabilities
val capabilitiesCallback = object : RangingManager.CapabilitiesCallback {
override fun onRangingCapabilities(capabilities: RangingCapabilities) {
// Make sure Dl-TDoA is supported before starting the session
if (capabilities.uwbCapabilities != null && capabilities.uwbCapabilities!!.isDlTdoaSupported) {
startDlTDoASession(context)
}
}
}
rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback)
}
fun startDlTDoASession(context: Context) {
// Initialize the Ranging Manager
val rangingManager = context.getSystemService(RangingManager::class.java)
// Create session and configure parameters
val executor = Executors.newSingleThreadExecutor()
val rangingSession = rangingManager.createRangingSession(executor, RangingSessionCallback())
val rangingRoundIndexes = intArrayOf(0)
val config: ByteArray = byteArrayOf() // OOB config data
val params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes)
val rangingDevice = RangingDevice.Builder().build()
val rawTagDevice = RawRangingDevice.Builder()
.setRangingDevice(rangingDevice)
.setDlTdoaRangingParams(params)
.build()
val dtTagConfig = RawDtTagRangingConfig.Builder(rawTagDevice).build()
val preference = RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
.setSessionConfig(SessionConfig.Builder().build())
.build()
// Start the ranging session
rangingSession.start(preference)
}
}
private class RangingSessionCallback : RangingSession.Callback {
override fun onDlTdoaResults(peer: RangingDevice, measurement: DlTdoaMeasurement) {
// Process measurement results here
}
}
Java
public class RangingApp {
public void initDlTdoa(Context context) {
// Initialize the Ranging Manager
RangingManager rangingManager = context.getSystemService(RangingManager.class);
// Register for device capabilities
RangingManager.CapabilitiesCallback capabilitiesCallback = new RangingManager.CapabilitiesCallback() {
@Override
public void onRangingCapabilities(RangingCapabilities capabilities) {
// Make sure Dl-TDoA is supported before starting the session
if (capabilities.getUwbCapabilities() != null && capabilities.getUwbCapabilities().isDlTdoaSupported) {
startDlTDoASession(context);
}
}
};
rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback);
}
public void startDlTDoASession(Context context) {
RangingManager rangingManager = context.getSystemService(RangingManager.class);
// Create session and configure parameters
Executor executor = Executors.newSingleThreadExecutor();
RangingSession rangingSession = rangingManager.createRangingSession(executor, new RangingSessionCallback());
int[] rangingRoundIndexes = new int[] {0};
byte[] config = new byte[0]; // OOB config data
DlTdoaRangingParams params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes);
RangingDevice rangingDevice = new RangingDevice.Builder().build();
RawRangingDevice rawTagDevice = new RawRangingDevice.Builder()
.setRangingDevice(rangingDevice)
.setDlTdoaRangingParams(params)
.build();
RawDtTagRangingConfig dtTagConfig = new RawDtTagRangingConfig.Builder(rawTagDevice).build();
RangingPreference preference = new RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
.setSessionConfig(new SessionConfig.Builder().build())
.build();
// Start the ranging session
rangingSession.start(preference);
}
private static class RangingSessionCallback implements RangingSession.Callback {
@Override
public void onDlTdoaResults(RangingDevice peer, DlTdoaMeasurement measurement) {
// Process measurement results here
}
}
}
Konfigurasi Out-of-Band (OOB)
Cuplikan berikut memberikan contoh data konfigurasi OOB DL-TDoA untuk Wi-Fi dan BLE:
Java
// Wifi Configuration
byte[] wifiConfig = {
(byte) 0xDD, (byte) 0x2D, (byte) 0x5A, (byte) 0x18, (byte) 0xFF, // Header
(byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
(byte) 0x02, (byte) 0x00, // Profile ID
(byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
(byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
(byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
(byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
(byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
(byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
(byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
(byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01 // Session ID
};
// BLE Configuration
byte[] bleConfig = {
(byte) 0x2D, (byte) 0x16, (byte) 0xF4, (byte) 0xFF, // Header
(byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
(byte) 0x02, (byte) 0x00, // Profile ID
(byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
(byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
(byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
(byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
(byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
(byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
(byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
(byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01 // Session ID
};
Jika Anda tidak dapat menggunakan konfigurasi OOB karena tidak ada, atau jika Anda perlu mengubah nilai default yang tidak ada dalam konfigurasi OOB, Anda dapat membuat parameter dengan DlTdoaRangingParams.Builder seperti yang ditunjukkan dalam cuplikan berikut. Anda dapat menggunakan
parameter ini sebagai pengganti DlTdoaRangingParams.createFromFiraConfigPacket():
Kotlin
val dlTdoaParams = DlTdoaRangingParams.Builder(1)
.setComplexChannel(UwbComplexChannel.Builder()
.setChannel(9).setPreambleIndex(10).build())
.setDeviceAddress(deviceAddress)
.setSessionKeyInfo(byteArrayOf(0x01, 0x02, 0x03, 0x04))
.setRangingIntervalMillis(240)
.setSlotDuration(UwbRangingParams.DURATION_2_MS)
.setSlotsPerRangingRound(20)
.setRangingRoundIndexes(byteArrayOf(0x01, 0x05))
.build()
Java
DlTdoaRangingParams dlTdoaParams = new DlTdoaRangingParams.Builder(1)
.setComplexChannel(new UwbComplexChannel.Builder()
.setChannel(9).setPreambleIndex(10).build())
.setDeviceAddress(deviceAddress)
.setSessionKeyInfo(new byte[]{0x01, 0x02, 0x03, 0x04})
.setRangingIntervalMillis(240)
.setSlotDuration(UwbRangingParams.DURATION_2_MS)
.setSlotsPerRangingRound(20)
.setRangingRoundIndexes(new byte[]{0x01, 0x05})
.build();