Önceki sürümlerde olduğu gibi Android 14'te de uygulamanızı etkileyebilecek davranış değişiklikleri yer alıyor. 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 bir sürümü hedefliyorsa (geçerli olduğunda) uygulamanızı bu davranışları doğru şekilde destekleyecek şekilde değiştirmeniz gerekir.
Uygulamanın targetSdkVersion
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
If your app targets Android 14 (API level 34) or higher, it must specify at least one foreground service type for each foreground service within your app. You should choose a foreground service type that represents your app's use case. The system expects foreground services that have a particular type to satisfy a particular use case.
If a use case in your app isn't associated with any of these types, it's strongly recommended that you migrate your logic to use WorkManager or user-initiated data transfer jobs.
BluetoothAdapter'da BLUETOOTH_CONNECT izninin uygulanması
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ı, uygulama ve platform geliştiricileri için kitaplık güncellemeleri ve Java 17 dil desteği de dahil olmak üzere en son OpenJDK LTS sürümlerindeki özelliklerle uyumlu olacak şekilde yenileme çalışmalarına devam ediyor.
Bu değişikliklerden birkaçı uygulama uyumluluğunu etkileyebilir:
- Normal ifadelerde yapılan değişiklikler: Geçersiz grup referanslarının, OpenJDK'nin anlamını daha yakından takip etmesine artık izin verilmemektedir.
java.util.regex.Matcher
sınıfınınIllegalArgumentException
değerini attığı yeni durumlar görebilirsiniz. Bu nedenle uygulamanızı normal ifadelerin kullanıldığı alanlar için 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 değiştirin. - UUID işleme:
java.util.UUID.fromString()
yöntemi artık giriş bağımsız değişkenini doğrularken daha sıkı kontroller gerçekleştirir. Bu nedenle serileştirme 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 etkinleştirin. - ProGuard sorunları: Bazı durumlarda, ProGuard'ı kullanarak uygulamanızı küçültmeye, gizlemeye ve optimize etmeye çalışırsanız
java.lang.ClassValue
sınıfının eklenmesi soruna neden olur. Sorun,Class.forName("java.lang.ClassValue")
ürününün bir 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ır. Uygulamanız, çalışma zamanınınjava.lang.ClassValue
sınıfının bulunmadığı eski bir sürüme göre geliştirildiyse bu optimizasyonlar,computeValue
yönteminijava.lang.ClassValue
öğesinden türetilen sınıflardan kaldırabilir.
JobScheduler geri çağırma ve ağ davranışını güçlendirir
Job Scheduler, kullanıma sunulduğu andan itibaren uygulamanızın
Birkaç saniye içinde onStartJob
veya onStopJob
. Android 14'ten önce
bir iş çok uzun süre çalışırsa iş durdurulur ve sessizce başarısız olur.
Uygulamanız Android 14 (API düzeyi 34) veya sonraki sürümleri hedefliyorsa ve ana iş parçacığında izin verilen süreyi aşıyorsa "onStartJob
için yanıt yok" veya "onStopJob
için yanıt yok" hata mesajıyla bir ANR tetikler.
Bu ANR, 2 senaryoya bağlı olabilir:
1. Ana iş parçacığını engelleyen ve geri çağırmaları engelleyen bir iş var (onStartJob
)
veya onStopJob
beklenen süre sınırı içinde yürütülmesini ve tamamlanmasını engeller.
2. Geliştirici, JobScheduler içinde engelleme çalışmasını çalıştırıyor
onStartJob
veya onStopJob
geri çağırması, geri çağırmanın önüne geçer.
beklenen süre aşılmadan
tamamlanmasıdır.
1. sorunu gidermek için ANR oluştuğunda ana iş parçacığının ne tarafından engellendiğini daha ayrıntılı bir şekilde hata ayıklamanız gerekir. ANR oluştuğunda tombstone izlemeyi almak için ApplicationExitInfo#getTraceInputStream()
'i kullanarak bunu yapabilirsiniz. ANR'yi manuel olarak yeniden oluşturabiliyorsanız
sistem izleme kaydedebilir ve
Android Studio veya Perfetto ile hangi uygulamaların yüklü olduğunu daha iyi anlayın
ANR gerçekleştiğinde ana iş parçacığı.
Bunun doğrudan JobScheduler API'yi kullanırken olabileceğini unutmayın
veya androidx kitaplığını kullanabilirsiniz.
2. sorunu gidermek için onStartJob
veya onStopJob
'deki tüm işlemleri asenkron bir iş parçacığında sarmalama desteği sunan WorkManager'a geçiş yapabilirsiniz.
JobScheduler
, setRequiredNetworkType
veya setRequiredNetwork
kısıtlaması kullanılıyorsa ACCESS_NETWORK_STATE
iznini beyan etme şartını da getirir. Uygulamanız
İşi planlarken ACCESS_NETWORK_STATE
izni
Android 14 veya sonraki sürümlerde SecurityException
oluşur.
Tiles launch API
For apps targeting 14 and higher,
TileService#startActivityAndCollapse(Intent)
is deprecated and now throws
an exception when called. If your app launches activities from tiles, use
TileService#startActivityAndCollapse(PendingIntent)
instead.
Gizlilik
Fotoğraflara ve videolara kısmi erişim
Android 14'te, kullanıcıların belirli bir türdeki tüm medyalara erişim izni vermek yerine, kitaplıklarındaki belirli resim ve videolara erişim izni verebilmelerini sağlayan Seçili Fotoğraflar Erişimi kullanıma sunuldu.
Bu değişiklik yalnızca uygulamanız Android 14 (API düzeyi 34) veya sonraki sürümleri hedefliyorsa etkin olur. Fotoğraf seçiciyi henüz kullanmıyorsanız herhangi bir depolama izni istemek zorunda kalmadan kullanıcı gizliliğini iyileştiren resim ve video seçerken tutarlı bir deneyim sunmak için uygulamanızda bu özelliği uygulamanızı öneririz.
Depolama 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
With Android 11 (API level 30), it was possible for any app to use
Notification.Builder.setFullScreenIntent
to send full-screen
intents while the phone is locked. You could auto-grant this on app install by
declaring USE_FULL_SCREEN_INTENT
permission in the
AndroidManifest.
Full-screen intent notifications are designed for extremely high-priority
notifications demanding the user's immediate attention, such as an incoming
phone call or alarm clock settings configured by the user. For apps targeting
Android 14 (API level 34) or higher, apps that are allowed to use this
permission are limited to those that provide calling and alarms only. The Google
Play Store revokes default USE_FULL_SCREEN_INTENT
permissions for any apps
that don't fit this profile. The deadline for these policy changes is May 31,
2024.
This permission remains enabled for apps installed on the phone before the user updates to Android 14. Users can turn this permission on and off.
You can use the new API
NotificationManager.canUseFullScreenIntent
to check if your app
has the permission; if not, your app can use the new intent
ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
to launch the settings
page where users can grant the permission.
Güvenlik
Dolaylı ve beklemedeki niyetlerle 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
Apps and services that target Android 14 (API level 34) or higher and use
context-registered receivers are required to specify a flag
to indicate whether or not the receiver should be exported to all other apps on
the device: either RECEIVER_EXPORTED
or RECEIVER_NOT_EXPORTED
, respectively.
This requirement helps protect apps from security vulnerabilities by leveraging
the features for these receivers introduced in Android 13.
Exception for receivers that receive only system broadcasts
If your app is registering a receiver only for
system broadcasts through Context#registerReceiver
methods, such as Context#registerReceiver()
, then it
shouldn't specify a flag when registering the receiver.
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.
Etkinliklerin arka planda başlatılmasıyla ilgili ek kısıtlamalar
Sistem, Android 14 (API düzeyi 34) veya sonraki sürümleri hedefleyen uygulamalar için uygulamaların arka planda etkinlik başlatmasına izin verilen zamanı kısıtlar:
- Bir uygulama şunu kullanarak
PendingIntent
gönderdiğinde:PendingIntent#send()
veya benzer yöntemler varsa uygulamanın etkinleştirilmesi gerekir. başlatmak için kendi arka plan etkinliği başlatma ayrıcalıklarını beklemeye gerek yoktur. Etkinleştirmek için uygulamanınsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
ile birActivityOptions
paketi iletmesi gerekir. - Görünür bir uygulama, arka plandaki başka bir uygulamanın hizmetini bağladığında
bindService()
yöntemi kullanıldığında, görünür uygulama artık Android'e kendi arka plan etkinliği başlatma ayrıcalıklarını bağlı hizmet. 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 yolu geçişi
For apps targeting Android 14 (API level 34) or higher, Android prevents the Zip
Path Traversal Vulnerability in the following way:
ZipFile(String)
and
ZipInputStream.getNextEntry()
throws a
ZipException
if zip file entry names contain ".." or start
with "/".
Apps can opt-out from this validation by calling
dalvik.system.ZipPathValidator.clearCallback()
.
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 dışı kısıtlamalar güncellendi
Android 14 includes updated lists of restricted non-SDK interfaces based on collaboration with Android developers and the latest internal testing. Whenever possible, we make sure that public alternatives are available before we restrict non-SDK interfaces.
If your app does not target Android 14, some of these changes might not immediately affect you. However, while you can currently use some non-SDK interfaces (depending on your app's target API level), using any non-SDK method or field always carries a high risk of breaking your app.
If you are unsure if your app uses non-SDK interfaces, you can test your app to find out. If your app relies on non-SDK interfaces, you should begin planning a migration to SDK alternatives. Nevertheless, we understand that some apps have valid use cases for using non-SDK interfaces. If you cannot find an alternative to using a non-SDK interface for a feature in your app, you should request a new public API.
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ıyla ilgili güncellemeler bölümüne göz atın. Genel olarak SDK olmayan arayüzler hakkında daha fazla bilgi edinmek için SDK olmayan arayüzlerle ilgili kısıtlamalar bölümüne bakın.