Android 14, önceki sürümlerde olduğu gibi uygulamanızı etkileyebilecek davranış değişiklikleri içerir. Aşağıdaki davranış değişiklikleri yalnızca Android 14'ü (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalar için geçerlidir. Uygulamanız Android 14 veya sonraki sürümleri hedefliyorsa geçerli durumlarda bu davranışları düzgün şekilde destekleyecek şekilde değiştirmeniz gerekir.
Uygulamanın targetSdkVersion
'sinden bağımsız olarak Android 14'te çalışan tüm uygulamaları etkileyen davranış değişiklikleri listesini de incelemeyi unutmayın.
Temel işlevler
Ön plan hizmeti türleri zorunludur
Uygulamanız Android 14 (API düzeyi 34) veya sonraki sürümleri hedefliyorsa uygulamanızdaki her ön plan hizmeti için en az bir ön plan hizmet türü belirtilmelidir. Uygulamanızın kullanım alanını temsil eden bir ön plan hizmet türü seçmeniz gerekir. Sistem, belirli bir türe sahip ön plan hizmetlerinin belirli bir kullanım alanını karşılamasını bekler.
Uygulamanızdaki bir kullanım alanı bu türlerden hiçbiriyle ilişkili değilse mantığınızı WorkManager veya kullanıcı tarafından başlatılan veri aktarım işleri kullanmaya taşımanız önemle tavsiye edilir.
BluetoothAdapter'da BLUETOOTH_CONNECT izninin zorunlu kılınması
Android 14, Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalar için BluetoothAdapter
getProfileConnectionState()
yöntemi çağrılırken BLUETOOTH_CONNECT
iznini zorunlu kılar.
Bu yöntem için BLUETOOTH_CONNECT
izni zaten gerekliydi ancak bu şart uygulanmadı. Uygulamanızın AndroidManifest.xml
dosyasında aşağıdaki snippet'te gösterildiği gibi BLUETOOTH_CONNECT
beyan ettiğinden emin olun ve getProfileConnectionState
işlevini çağırmadan önce kullanıcıya iznin verildiğini kontrol edin.
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
OpenJDK 17 güncellemeleri
Android 14, Android'in temel kitaplıklarını en son OpenJDK LTS sürümlerindeki özelliklerle uyumlu hale getirmek için yenileme çalışmalarına devam ediyor. Bu çalışmalara hem kitaplık güncellemeleri hem de uygulama ve platform geliştiricileri için Java 17 dil desteği dahildir.
Bu değişikliklerden bazıları uygulama uyumluluğunu etkileyebilir:
- Normal ifadelerdeki değişiklikler: OpenJDK'nın anlamını daha yakından takip etmek için geçersiz grup referanslarına artık izin verilmiyor.
java.util.regex.Matcher
sınıfı tarafındanIllegalArgumentException
atanmasının olduğu yeni durumlar görebilirsiniz. Bu nedenle, uygulamanızı normal ifadelerin kullanıldığı alanlar açısından test ettiğinizden emin olun. Test sırasında bu değişikliği etkinleştirmek veya devre dışı bırakmak için uyumluluk çerçevesi araçlarını kullanarakDISALLOW_INVALID_GROUP_REFERENCE
işaretini açın veya kapatın. - UUID işleme:
java.util.UUID.fromString()
yöntemi artık giriş bağımsız değişkenini doğrularken daha katı kontroller yapıyor. Bu nedenle, seri dışılaştırma sırasında birIllegalArgumentException
görebilirsiniz. Test sırasında bu değişikliği etkinleştirmek veya devre dışı bırakmak için uyumluluk çerçevesi araçlarını kullanarakENABLE_STRICT_VALIDATION
işaretini açın veya kapatın. - ProGuard sorunları: Bazı durumlarda, ProGuard'ı kullanarak uygulamanızı küçültmeye, kod karartmaya ve optimize etmeye çalıştığınızda
java.lang.ClassValue
sınıfının eklenmesi soruna neden olur. Sorun,Class.forName("java.lang.ClassValue")
'ün sınıf döndürüp döndürmediğine bağlı olarak çalışma zamanı davranışını değiştiren bir Kotlin kitaplığından kaynaklanıyor. Uygulamanız,java.lang.ClassValue
sınıfının bulunmadığı çalışma ortamının eski bir sürümüne göre geliştirildiyse bu optimizasyonlar,java.lang.ClassValue
sınıfından türetilen sınıflardancomputeValue
yöntemini kaldırabilir.
JobScheduler, geri çağırma ve ağ davranışını güçlendirir
Since its introduction, JobScheduler expects your app to return from
onStartJob
or onStopJob
within a few seconds. Prior to Android 14,
if a job runs too long, the job is stopped and fails silently.
If your app targets Android 14 (API level 34) or higher and
exceeds the granted time on the main thread, the app triggers an ANR
with the error message "No response to onStartJob
" or
"No response to onStopJob
".
This ANR may be a result of 2 scenarios:
1. There is work blocking the main thread, preventing the callbacks onStartJob
or onStopJob
from executing and completing within the expected time limit.
2. The developer is running blocking work within the JobScheduler
callback onStartJob
or onStopJob
, preventing the callback from
completing within the expected time limit.
To address #1, you will need to further debug what is blocking the main thread
when the ANR occurs, you can do this using
ApplicationExitInfo#getTraceInputStream()
to get the tombstone
trace when the ANR occurs. If you're able to manually reproduce the ANR,
you can record a system trace and inspect the trace using either
Android Studio or Perfetto to better understand what is running on
the main thread when the ANR occurs.
Note that this can happen when using JobScheduler API directly
or using the androidx library WorkManager.
To address #2, consider migrating to WorkManager, which provides
support for wrapping any processing in onStartJob
or onStopJob
in an asynchronous thread.
JobScheduler
also introduces a requirement to declare the
ACCESS_NETWORK_STATE
permission if using setRequiredNetworkType
or
setRequiredNetwork
constraint. If your app does not declare the
ACCESS_NETWORK_STATE
permission when scheduling the job and is targeting
Android 14 or higher, it will result in a SecurityException
.
Tiles launch API
14 ve sonraki sürümleri hedefleyen uygulamalar için
TileService#startActivityAndCollapse(Intent)
desteği sonlandırıldı ve artık çalışıyor
çağrıldığında bir istisna oluşturur. Uygulamanız kartlardan etkinlik başlatıyorsa bunun yerine TileService#startActivityAndCollapse(PendingIntent)
değerini kullanın.
Gizlilik
Fotoğraflara ve videolara kısmi erişim
Android 14, kullanıcıların belirli bir türdeki tüm medyalara erişim vermek yerine uygulamalara kitaplarındaki belirli resimlere ve videolara erişim izni vermesine olanak tanıyan Seçili Fotoğraflar Erişimi özelliğini kullanıma sunar.
Bu değişiklik yalnızca uygulamanız Android 14'ü (API düzeyi 34) veya sonraki sürümleri hedefliyorsa etkinleştirilir. Fotoğraf seçiciyi henüz kullanmıyorsanız depolama alanı izni istemek zorunda kalmadan resim ve video seçmek için tutarlı bir deneyim sunmak ve kullanıcı gizliliğini artırmak amacıyla uygulamanıza uygulamanızı öneririz.
Depolama alanı izinlerini kullanarak kendi galeri seçicinizi kullanıyorsanız ve uygulamanız üzerinde tam kontrol sahibi olmanız gerekiyorsa yeni READ_MEDIA_VISUAL_USER_SELECTED
iznini kullanmak için uygulamanızı uyarlayın. Uygulamanız yeni izni kullanmıyorsa sistem, uygulamanızı uyumluluk modunda çalıştırır.
Kullanıcı deneyimi
Güvenli tam ekran intent bildirimleri
Android 11 (API düzeyi 30) ile birlikte, telefon kilitliyken tam ekran intent'ler göndermek için tüm uygulamaların Notification.Builder.setFullScreenIntent
kullanması mümkündü. AndroidManifest dosyasında USE_FULL_SCREEN_INTENT
iznini belirterek bu izni uygulama yüklenirken otomatik olarak verebilirsiniz.
Tam ekran intent bildirimleri, kullanıcının hemen ilgilenmesini gerektiren son derece yüksek öncelikli bildirimler (ör. gelen telefon araması veya kullanıcı tarafından yapılandırılmış alarm saati ayarları) için tasarlanmıştır. Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalarda bu iznin kullanılmasına izin verilen uygulamalar yalnızca arama ve alarm sağlayan uygulamalarla sınırlıdır. Google Play Store, bu profile uymayan uygulamaların varsayılan USE_FULL_SCREEN_INTENT
izinlerini iptal eder. Bu politika değişikliklerinin son tarihi 31 Mayıs 2024'tür.
Bu izin, kullanıcı Android 14'e güncellemeden önce telefona yüklenen uygulamalarda etkin kalır. Kullanıcılar bu izni etkinleştirip devre dışı bırakabilir.
Uygulamanızın izin alıp almadığını kontrol etmek için yeni API'yi NotificationManager.canUseFullScreenIntent
kullanabilirsiniz. İzin yoksa uygulamanız, kullanıcıların izni verebileceği ayarlar sayfasını başlatmak için yeni intent'i ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
kullanabilir.
Güvenlik
Örtülü ve bekleyen amaçlarla ilgili kısıtlamalar
Android, Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalar için uygulamaların dahili uygulama bileşenlerine örtülü niyet göndermesini aşağıdaki şekillerde kısıtlar:
- Örtük intent'ler yalnızca dışa aktarılan bileşenlere gönderilir. Uygulamalar, dışa aktarılmayan bileşenlere yayın yapmak için açık bir intent kullanmalı veya bileşeni dışa aktarıldı olarak işaretlemelidir.
- Bir uygulama, bileşen veya paket belirtmeyen bir intent ile değişken bekleyen intent oluşturursa sistem bir istisna oluşturur.
Bu değişiklikler, kötü amaçlı uygulamaların, uygulamanın dahili bileşenleri tarafından kullanılması amaçlanan örtülü niyetlere müdahale etmesini önler.
Örneğin burada, uygulamanızın manifest dosyasında bildirilebilecek bir amaç filtresi verilmiştir:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Uygulamanız bu etkinliği dolaylı intent kullanarak başlatmaya çalıştıysa ActivityNotFoundException
istisnası atılır:
Kotlin
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(Intent("com.example.action.APP_ACTION"))
Java
// Throws an ActivityNotFoundException exception when targeting Android 14. context.startActivity(new Intent("com.example.action.APP_ACTION"));
Dışa aktarılmayan etkinliği başlatmak için uygulamanızın bunun yerine açık bir intent kullanması gerekir:
Kotlin
// This makes the intent explicit. val explicitIntent = Intent("com.example.action.APP_ACTION") explicitIntent.apply { package = context.packageName } context.startActivity(explicitIntent)
Java
// This makes the intent explicit. Intent explicitIntent = new Intent("com.example.action.APP_ACTION") explicitIntent.setPackage(context.getPackageName()); context.startActivity(explicitIntent);
Çalışma zamanında kaydedilen yayın alıcılar, dışa aktarma davranışını belirtmelidir
Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen ve bağlama kayıtlı alıcıları kullanan uygulamaların ve hizmetlerin, alıcının cihazdaki diğer tüm uygulamalara aktarılıp aktarılmayacağını belirtmek için bir işaret belirtmesi gerekir: sırasıyla RECEIVER_EXPORTED
veya RECEIVER_NOT_EXPORTED
.
Bu şart, Android 13'te kullanıma sunulan bu alıcılara yönelik özelliklerden yararlanarak uygulamaları güvenlik açıklarına karşı korumaya yardımcı olur.
Yalnızca sistem yayınları alan alıcılar için istisna
Uygulamanız, Context#registerReceiver()
gibi Context#registerReceiver
yöntemleri kullanarak yalnızca sistem yayınları için alıcı kaydediyorsa alıcıyı kaydederken bir işaret belirtmemelidir.
Daha güvenli dinamik kod yükleme
Uygulamanız Android 14 (API düzeyi 34) veya sonraki sürümleri hedefliyorsa ve dinamik kod yükleme (DCL) kullanıyorsa dinamik olarak yüklenen tüm dosyalar salt okunur olarak işaretlenmelidir. Aksi takdirde sistem bir istisna oluşturur. Uygulamaların mümkün olduğunda kodu dinamik olarak yüklemekten kaçınmasını öneririz. Aksi takdirde, uygulamanın kod ekleme veya kodla oynama yoluyla güvenliğinin ihlal edilme riski büyük ölçüde artar.
Kodu dinamik olarak yüklemeniz gerekiyorsa dinamik olarak yüklenen dosyayı (ör. DEX, JAR veya APK dosyası) açıldıktan hemen sonra ve herhangi bir içerik yazılmadan önce salt okunur olarak ayarlamak için aşağıdaki yaklaşımı kullanın:
Kotlin
val jar = File("DYNAMICALLY_LOADED_FILE.jar") val os = FileOutputStream(jar) os.use { // Set the file to read-only first to prevent race conditions jar.setReadOnly() // Then write the actual file content } val cl = PathClassLoader(jar, parentClassLoader)
Java
File jar = new File("DYNAMICALLY_LOADED_FILE.jar"); try (FileOutputStream os = new FileOutputStream(jar)) { // Set the file to read-only first to prevent race conditions jar.setReadOnly(); // Then write the actual file content } catch (IOException e) { ... } PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
Zaten mevcut olan dinamik olarak yüklenen dosyaları işleme
Mevcut dinamik olarak yüklenen dosyalar için istisnaların atılmasını önlemek amacıyla, dosyaları uygulamanızda tekrar dinamik olarak yüklemeyi denemeden önce dosyaları silip yeniden oluşturmanızı öneririz. Dosyaları yeniden oluştururken, yazma sırasında dosyaları salt okunur olarak işaretlemeyle ilgili önceki talimatları uygulayın. Alternatif olarak, mevcut dosyaları salt okunur olarak yeniden etiketleyebilirsiniz. Ancak bu durumda, uygulamanızı kötü amaçlı işlemlere karşı korumak için önce dosyaların bütünlüğünü doğrulamanızı (örneğin, dosyanın imzasını güvenilir bir değerle karşılaştırarak) önemle tavsiye ederiz.
Arka planda etkinlik başlatmayla ilgili ek kısıtlamalar
Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalar için sistem, uygulamaların arka planda etkinlik başlatmasına izin verildiği durumları daha da kısıtlar:
- Bir uygulama,
PendingIntent#send()
veya benzer yöntemler kullanarakPendingIntent
gönderdiğinde, bekleyen intent'i başlatmak için kendi arka plan etkinliği başlatma ayrıcalıklarını vermek istiyorsa bu özelliği etkinleştirmelidir. Etkinleştirmek için uygulamanınsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
ile birActivityOptions
paketi iletmesi gerekir. - Görünen bir uygulama,
bindService()
yöntemini kullanarak arka planda olan başka bir uygulamanın hizmetini bağladığında, bağlı hizmete kendi arka plan etkinliği başlatma ayrıcalıklarını vermek istiyorsa artık bu seçeneği etkinleştirmesi gerekir. Etkinleştirmek için uygulama,bindService()
yöntemini çağırırkenBIND_ALLOW_ACTIVITY_STARTS
işaretini içermelidir.
Bu değişiklikler, kötü amaçlı uygulamaların arka planda rahatsız edici etkinlikler başlatmak için API'leri kötüye kullanmasını engelleyerek kullanıcıları korumak amacıyla mevcut kısıtlama grubunu genişletir.
Zip path traversal
Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalarda Android, ZIP Yol Geçiş Güvenlik Açığını aşağıdaki şekilde önler: ZipFile(String)
ve ZipInputStream.getNextEntry()
, ZIP dosyası giriş adları ".." içeriyorsa veya "/" ile başlıyorsa ZipException
hatası oluşturur.
Uygulamalar, dalvik.system.ZipPathValidator.clearCallback()
çağrısı yaparak bu doğrulamayı devre dışı bırakabilir.
Her MediaProjection yakalama oturumu için kullanıcı izni gerekir
For apps targeting Android 14 (API level 34) or higher, a SecurityException
is
thrown by MediaProjection#createVirtualDisplay
in either of the following
scenarios:
- Your app caches the
Intent
that is returned fromMediaProjectionManager#createScreenCaptureIntent
, and passes it multiple times toMediaProjectionManager#getMediaProjection
. - Your app invokes
MediaProjection#createVirtualDisplay
multiple times on the sameMediaProjection
instance.
Your app must ask the user to give consent before each capture session. A single
capture session is a single invocation on
MediaProjection#createVirtualDisplay
, and each MediaProjection
instance must
be used only once.
Handle configuration changes
If your app needs to invoke MediaProjection#createVirtualDisplay
to handle
configuration changes (such as the screen orientation or screen size changing),
you can follow these steps to update the VirtualDisplay
for the existing
MediaProjection
instance:
- Invoke
VirtualDisplay#resize
with the new width and height. - Provide a new
Surface
with the new width and height toVirtualDisplay#setSurface
.
Register a callback
Your app should register a callback to handle cases where the user doesn't grant
consent to continue a capture session. To do this, implement
Callback#onStop
and have your app release any related resources (such as
the VirtualDisplay
and Surface
).
If your app doesn't register this callback,
MediaProjection#createVirtualDisplay
throws an IllegalStateException
when your app invokes it.
SDK olmayan arayüzlerle ilgili güncellenen kısıtlamalar
Android 14, Android geliştiricilerle işbirliği ve en son dahili testlere dayalı olarak kısıtlanmış, SDK dışı arayüzlerin güncellenmiş listelerini içerir. Mümkün olduğunda, SDK olmayan arayüzleri kısıtlamadan önce herkese açık alternatiflerin kullanılabilir olmasını sağlarız.
Uygulamanız Android 14'ü hedeflemiyorsa bu değişikliklerin bazıları sizi hemen etkilemeyebilir. Ancak şu anda bazı SDK dışı arayüzleri (uygulamanızın hedef API düzeyine bağlı olarak) kullanabilseniz de herhangi bir SDK dışı yöntemi veya alanı kullanmak uygulamanızın bozulma riskini her zaman yüksek tutar.
Uygulamanızda SDK dışı arayüzler kullanılıp kullanılmadığından emin değilseniz öğrenmek için uygulamanızı test edebilirsiniz. Uygulamanız SDK dışı arayüzleri kullanıyorsa SDK alternatiflerine geçişi planlamaya başlamanız gerekir. Bununla birlikte, bazı uygulamaların SDK dışı arayüzleri kullanmak için geçerli kullanım alanları olduğunu anlıyoruz. Uygulamanızdaki bir özellik için SDK dışı arayüz kullanmaya alternatif bulamıyorsanız yeni bir herkese açık API isteğinde bulunmalısınız.
Android'in bu sürümündeki değişiklikler hakkında daha fazla bilgi edinmek için Android 14'te SDK dışı arayüz kısıtlamalarında yapılan güncellemeler başlıklı makaleyi inceleyin. Genel olarak SDK olmayan arayüzler hakkında daha fazla bilgi edinmek için SDK olmayan arayüzlerde kısıtlamalar başlıklı makaleyi inceleyin.