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 değerinden bağımsız olarak, Android 14'te çalışan tüm uygulamaları etkileyen davranış değişikliklerinin listesini de inceleyin.
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, aşağıdaki snippet'te gösterildiği gibi BLUETOOTH_CONNECT öğesini uygulamanızın AndroidManifest.xml dosyasında beyan ettiğinden emin olun ve getProfileConnectionState öğesini çağırmadan önce kullanıcının izin verip vermediğ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.Matchersınıfı tarafındanIllegalArgumentExceptionatanması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_REFERENCEiş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 birIllegalArgumentExceptiongö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_VALIDATIONiş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.ClassValuesı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.ClassValuesınıfının bulunmadığı çalışma ortamının eski bir sürümüne göre geliştirildiyse bu optimizasyonlar,java.lang.ClassValuesınıfından türetilen sınıflardancomputeValueyö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 introduces Selected Photos Access, which allows users to grant apps access to specific images and videos in their library, rather than granting access to all media of a given type.
This change is only enabled if your app targets Android 14 (API level 34) or higher. If you don't use the photo picker yet, we recommend implementing it in your app to provide a consistent experience for selecting images and videos that also enhances user privacy without having to request any storage permissions.
If you maintain your own gallery picker using storage permissions and need to
maintain full control over your implementation, adapt your implementation
to use the new READ_MEDIA_VISUAL_USER_SELECTED permission. If your app
doesn't use the new permission, the system runs your app in a compatibility
mode.
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#registerReceiveryö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
If your app targets Android 14 (API level 34) or higher and uses Dynamic Code Loading (DCL), all dynamically-loaded files must be marked as read-only. Otherwise, the system throws an exception. We recommend that apps avoid dynamically loading code whenever possible, as doing so greatly increases the risk that an app can be compromised by code injection or code tampering.
If you must dynamically load code, use the following approach to set the dynamically-loaded file (such as a DEX, JAR, or APK file) as read-only as soon as the file is opened and before any content is written:
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);
Handle dynamically-loaded files that already exist
To prevent exceptions from being thrown for existing dynamically-loaded files, we recommend deleting and recreating the files before you try to dynamically load them again in your app. As you recreate the files, follow the preceding guidance for marking the files read-only at write time. Alternatively, you can re-label the existing files as read-only, but in this case, we strongly recommend that you verify the integrity of the files first (for example, by checking the file's signature against a trusted value), to help protect your app from malicious actions.
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 kullanarakPendingIntentgö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 birActivityOptionspaketi 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_STARTSiş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
Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalarda, aşağıdaki senaryolardan birinde MediaProjection#createVirtualDisplay tarafından bir SecurityException atılır:
- Uygulamanız,
MediaProjectionManager#createScreenCaptureIntentkaynağından döndürülenIntentöğesini önbelleğe alır veMediaProjectionManager#getMediaProjectionkaynağına birden çok kez iletir. - Uygulamanız aynı
MediaProjectionörneğindeMediaProjection#createVirtualDisplayişlevini birden fazla kez çağırıyor.
Uygulamanız, her yakalama oturumundan önce kullanıcıdan izin almalıdır. Tek bir yakalama oturumu, MediaProjection#createVirtualDisplay üzerinde tek bir çağrıdır ve her MediaProjection örneği yalnızca bir kez kullanılmalıdır.
Yapılandırma değişikliklerini işleme
Uygulamanızın yapılandırma değişikliklerini (ör. ekran yönü veya ekran boyutu değişikliği) işlemek için MediaProjection#createVirtualDisplay'ü çağırması gerekiyorsa mevcut MediaProjection örneği için VirtualDisplay'ı güncellemek üzere aşağıdaki adımları uygulayabilirsiniz:
- Yeni genişlik ve yükseklikle
VirtualDisplay#resizeişlevini çağırın. VirtualDisplay#setSurfaceiçin yeni genişlik ve yükseklik içeren yeni birSurfacesağlayın.
Geri arama kaydı
Uygulamanız, kullanıcının yakalama oturumuna devam etmek için izin vermediği durumları işlemek üzere bir geri çağırma işlevi kaydetmelidir. Bunu yapmak için Callback#onStop'u uygulayın ve uygulamanızın ilgili tüm kaynakları (ör. VirtualDisplay ve Surface) yayınlamasını sağlayın.
Uygulamanız bu geri çağırma işlevini kaydetmezse MediaProjection#createVirtualDisplay, uygulamanız işlevi çağırdığında IllegalStateException hatası verir.
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ızın SDK dışı arayüzler kullanıp kullanmadığı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.