Android 17, geliştiriciler için harika yeni özellikler ve API'ler sunuyor. Aşağıdaki bölümlerde, ilgili API'leri kullanmaya başlamanıza yardımcı olmak için bu özellikler özetlenmiştir.
Yeni, değiştirilmiş ve kaldırılmış API'lerin ayrıntılı listesi için API farklılıkları raporunu inceleyin. Yeni API'lerle ilgili ayrıntılar için Android API referansını ziyaret edin. Yeni API'ler görünürlük için vurgulanmıştır.
Platform değişikliklerinin uygulamalarınızı etkileyebileceği alanları da incelemeniz gerekir. Daha fazla bilgi için aşağıdaki sayfalara göz atın:
- Uygulamalar Android 17'yi hedeflediğinde etkileyen davranış değişiklikleri
targetSdkVersiondeğerinden bağımsız olarak tüm uygulamaları etkileyen davranış değişiklikleri.
Temel işlevler
Android 17, temel Android işlevleriyle ilgili aşağıdaki yeni özellikleri ekler.
Yeni ProfilingManager tetikleyicileri
Android 17 adds several new system triggers to ProfilingManager to
help you collect in-depth data to debug performance issues.
The new triggers are:
TRIGGER_TYPE_COLD_START: Trigger occurs during app cold start. It provides both a call stack sample and a system trace in the response.TRIGGER_TYPE_OOM: Trigger occurs when an app throws anOutOfMemoryErrorand provides a Java Heap Dump in response.TRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE: Trigger occurs when an app is killed due to abnormal and excessive CPU usage and provides a call stack sample in response.
To understand how to set up the system trigger, see the documentation on trigger-based profiling and how to retrieve and analyze profiling data documentation.
JobDebugInfo API'leri
Android 17, geliştiricilerin JobScheduler işlerinde hata ayıklamasına yardımcı olmak için yeni JobDebugInfo API'leri sunar. Bu API'ler, işlerin neden çalışmadığı, ne kadar süre çalıştığı ve diğer toplu bilgilerle ilgili veriler sağlar.
Genişletilmiş JobDebugInfo API'lerinin ilk yöntemi olan getPendingJobReasonStats(), işin neden bekleyen yürütme durumunda olduğuna dair nedenlerin ve ilgili kümülatif bekleyen sürelerin haritasını döndürür. Bu yöntem, planlanmış bir işin neden beklendiği gibi çalışmadığına dair bilgi edinmenizi sağlamak için getPendingJobReasonsHistory() ve getPendingJobReasons() yöntemlerini birleştirir. Ancak hem süreyi hem de iş nedenini tek bir yöntemde kullanılabilir hale getirerek bilgi almayı kolaylaştırır.
Örneğin, belirtilen bir jobId için yöntem, PENDING_JOB_REASON_CONSTRAINT_CHARGING ve 60.000 ms'lik bir süre döndürebilir. Bu, şarj kısıtlaması karşılanmadığı için işin 60.000 ms boyunca beklemede olduğunu gösterir.
Boşta kalma sırasında izin verilen alarmlar için dinleyici desteğiyle uyandırma kilitlerini azaltma
Android 17, PendingIntent yerine OnAlarmListener kabul eden yeni bir AlarmManager.setExactAndAllowWhileIdle varyantını kullanıma sunar. Bu yeni geri çağırmaya dayalı mekanizma, şu anda soket bağlantılarını koruyan mesajlaşma uygulamaları gibi periyodik görevleri gerçekleştirmek için sürekli uyandırma kilitlerine dayanan uygulamalar için idealdir.
Gizlilik
Android 17, kullanıcı gizliliğini iyileştirmek için aşağıdaki yeni özellikleri içerir.
Encrypted Client Hello (ECH) platform desteği
Android 17, ağ iletişimlerinde önemli bir gizlilik iyileştirmesi olan Encrypted Client Hello (ECH) için platform desteği sunuyor. ECH, ilk TLS el sıkışması sırasında Sunucu Adı Göstergesi'ni (SNI) şifreleyen bir TLS 1.3 uzantısıdır. Bu şifreleme, bir uygulamanın bağlandığı alanın ağ aracıları tarafından tanımlanmasını zorlaştırarak kullanıcı gizliliğinin korunmasına yardımcı olur.
Platform artık ağ kitaplıklarının ECH'yi uygulaması için gerekli API'leri içeriyor. Buna, ECH yapılandırmaları içeren HTTPS DNS kayıtlarını sorgulamak için DnsResolver'daki yeni özellikler ve bir alana bağlanırken bu yapılandırmaları ileterek ECH'yi etkinleştirmek için Conscrypt'in SSLEngines ve SSLSockets'indeki yeni yöntemler dahildir. Geliştiriciler, ECH tercihlerini (ör. fırsatçı bir şekilde etkinleştirme veya kullanımını zorunlu kılma) yeni <domainEncryption> öğesi aracılığıyla yapılandırabilir. Bu öğe, Ağ Güvenliği Yapılandırma dosyası içinde yer alır ve global olarak veya alan bazında geçerlidir.
HttpEngine, WebView ve OkHttp gibi popüler ağ kitaplıklarının gelecekteki güncellemelerde bu platform API'lerini entegre etmesi bekleniyor. Bu sayede uygulamaların ECH'yi benimsemesi ve kullanıcı gizliliğini artırması kolaylaşacak.
Daha fazla bilgi için Şifrelenmiş İstemci Merhaba belgesine bakın.
Android kişi seçici
Android Kişi Seçici, kullanıcıların kişilerle ilgili bilgileri uygulamanızla paylaşması için standartlaştırılmış ve gözatılabilir bir arayüzdür. Android 17 (API düzeyi 37) veya sonraki sürümlerin yüklü olduğu cihazlarda kullanılabilen seçici, geniş kapsamlı READ_CONTACTS iznine gizliliği korumaya yönelik bir alternatif sunar. Uygulamanız, kullanıcının tüm adres defterine erişim isteğinde bulunmak yerine ihtiyaç duyduğu veri alanlarını (ör. telefon numaraları veya e-posta adresleri) belirtir ve kullanıcı, paylaşılacak belirli kişileri seçer. Bu sayede uygulamanız yalnızca seçilen verilere okuma erişimi kazanır. Böylece, kullanıcı arayüzünü oluşturmak veya bakımını yapmak zorunda kalmadan yerleşik arama, profil değiştirme ve çoklu seçim özellikleri sayesinde tutarlı bir kullanıcı deneyimi sunarken ayrıntılı kontrol de sağlanır.
Daha fazla bilgi için kişi seçici dokümanlarına bakın.
Güvenlik
Android 17, cihaz ve uygulama güvenliğini artırmak için aşağıdaki yeni özellikleri ekler.
Android Gelişmiş Koruma Modu (AAPM)
Android Advanced Protection Mode offers Android users a powerful new set of security features, marking a significant step in safeguarding users—particularly those at higher risk—from sophisticated attacks. Designed as an opt-in feature, AAPM is activated with a single configuration setting that users can turn on at any time to apply an opinionated set of security protections.
These core configurations include blocking app installation from unknown sources
(sideloading), restricting USB data signaling, and mandating Google Play Protect
scanning, which significantly reduces the device's attack surface area.
Developers can integrate with this feature using the
AdvancedProtectionManager API to detect the mode's status, enabling
applications to automatically adopt a hardened security posture or restrict
high-risk functionality when a user has opted in.
PQC APK İmzalama
Android artık uygulamanızın imza kimliğini, kuantum bilgisayarlardan yararlanan saldırıların olası tehdidine karşı korumak için hibrit bir APK imza şemasını destekliyor. Bu özellik, klasik bir imzalama anahtarını (ör. RSA veya EC) yeni bir kuantum sonrası kriptografi (PQC) algoritmasıyla (ML-DSA) eşleştirmenize olanak tanıyan yeni bir APK İmza Şeması sunar.
Bu karma yaklaşım, uygulamanızın gelecekteki kuantum saldırılarına karşı güvenli kalmasını sağlarken eski Android sürümleri ve klasik imza doğrulamayı kullanan cihazlarla tam geriye dönük uyumluluğu korur.
Geliştiriciler üzerindeki etkisi
- Play Uygulama İmzalama'yı kullanan uygulamalar: Play Uygulama İmzalama'yı kullanıyorsanız Google Play'in, Google Play tarafından oluşturulan bir PQC anahtarı kullanarak karma imzayı yükseltme seçeneğini sunmasını bekleyebilirsiniz. Bu sayede, manuel anahtar yönetimi gerektirmeden uygulamanızın korunmasını sağlayabilirsiniz.
- Kendi kendine yönetilen anahtarları kullanan uygulamalar: Kendi imzalama anahtarlarını yöneten geliştiriciler, PQC anahtarını yeni bir klasik anahtarla birleştiren karma kimliğe geçmek için güncellenmiş Android derleme araçlarını (ör. apksigner) kullanabilir. (Yeni bir klasik anahtar oluşturmanız gerekir, eski anahtarı yeniden kullanamazsınız.)
Bağlantı
Android 17, cihaz ve uygulama bağlantısını iyileştirmek için aşağıdaki özellikleri ekler.
Kısıtlanmış uydu ağları
Uygulamaların düşük bant genişliğine sahip uydu ağlarında etkili bir şekilde çalışmasını sağlamak için optimizasyonlar uygular.
Kullanıcı deneyimi ve sistem arayüzü
Android 17, kullanıcı deneyimini iyileştirmek için aşağıdaki değişiklikleri içerir.
Özel Asistan ses akışı
Android 17, USAGE_ASSISTANT ile oynatma için Asistan uygulamalarına özel bir Asistan ses akışı sunar. Bu değişiklik, Asistan sesini standart medya akışından ayırarak kullanıcılara her iki ses düzeyi üzerinde de ayrı ayrı kontrol imkanı sunar. Bu sayede, Asistan yanıtlarının duyulabilirliğini korurken medya oynatmayı sessize alma veya tam tersi gibi senaryolar mümkün olur.
Yeni MODE_ASSISTANT_CONVERSATION ses moduna erişimi olan asistan uygulamaları, ses kontrolünün tutarlılığını daha da artırabilir. Asistan uygulamaları, etkin bir Asistan oturumu hakkında sisteme ipucu vermek için bu modu kullanabilir. Böylece Asistan akışının, etkin USAGE_ASSISTANT oynatma dışında veya bağlı Bluetooth çevre birimleriyle kontrol edilmesi sağlanır.
Aktarma
Handoff is a new feature and API coming to Android 17 that app developers can integrate with to provide cross-device continuity for their users. It allows the user to start an app activity on one Android device and transition it to another Android device. Handoff runs in the background of a user's device and surfaces available activities from the user's other nearby devices through various entry points, like the launcher and taskbar, on the receiving device.
Apps can designate Handoff to launch the same native Android app, if it is installed and available on the receiving device. In this app-to-app flow, the user is deep-linked to the designated activity. Alternatively, app-to-web Handoff can be offered as a fallback option or directly implemented with URL Handoff.
Handoff support is implemented on a per-activity basis. To enable Handoff, call
the setHandoffEnabled() method for the activity. Additional data may need to
be passed along with the handoff so the recreated activity on the receiving
device can restore appropriate state. Implement the
onHandoffActivityRequested() callback to return a HandoffActivityData object
which contains details that specify how Handoff should handle and recreate
the activity on the receiving device.
Canlı Güncelleme - Semantic Color API
Android 17 ile Live Update, evrensel anlamı olan renkleri desteklemek için Semantic Coloring API'lerini kullanıma sunuyor.
Aşağıdaki sınıflar semantik renklendirmeyi destekler:
NotificationNotification.MetricNotification.ProgressStyle.PointNotification.ProgressStyle.Segment
Boyama
- Yeşil: Güvenlikle ilişkilidir. Bu renk, kullanıcılara güvenli bir durumda olduğunuzu bildirmek için kullanılmalıdır.
- Turuncu: Dikkat çekmek ve fiziksel tehlikeleri işaretlemek için kullanılır. Bu renk, kullanıcıların daha iyi koruma ayarları yapmak için dikkat etmesi gereken durumlarda kullanılmalıdır.
- Kırmızı: Genellikle tehlikeyi gösterir, durdurma. Kullanıcıların dikkatini acilen çekmeniz gereken durumlarda gösterilmelidir.
- Mavi: Bilgilendirici olan ve diğer içeriklerden ayrılması gereken içerikler için nötr renk.
Aşağıdaki örnekte, bir bildirimdeki metne anlamsal stillerin nasıl uygulanacağı gösterilmektedir:
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)
Android 17 için UWB Downlink-TDoA API'si
Aşağı bağlantı geliş zamanı farkı (DL-TDoA) aralığı, bir cihazın sinyallerin göreli geliş zamanlarını ölçerek birden fazla sabite göre konumunu belirlemesine olanak tanır.
Aşağıdaki snippet'te Ranging Manager'ın nasıl başlatılacağı, cihaz özelliklerinin nasıl doğrulanacağı ve DL-TDoA oturumunun nasıl başlatılacağı gösterilmektedir:
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
}
}
}
Bant dışı (OOB) yapılandırmalar
Aşağıdaki snippet'te, Wi-Fi ve BLE için DL-TDoA OOB yapılandırma verilerine örnek verilmiştir:
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
};
Eksik olduğu için kullanıma hazır yapılandırmayı kullanamıyorsanız veya kullanıma hazır yapılandırmada olmayan varsayılan değerleri değiştirmeniz gerekiyorsa aşağıdaki snippet'te gösterildiği gibi DlTdoaRangingParams.Builder ile parametreler oluşturabilirsiniz. DlTdoaRangingParams.createFromFiraConfigPacket() yerine aşağıdaki parametreleri kullanabilirsiniz:
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();