Wie bei früheren Releases umfasst auch Android 14 Verhaltensänderungen, die sich auf deine App auswirken können. Die folgenden Änderungen gelten ausschließlich für Apps, die auf Android 14 (API-Level 34) oder höher ausgerichtet sind. Wenn Ihre App auf Android 14 oder höher ausgerichtet ist, sollten Sie sie gegebenenfalls so anpassen, dass diese Verhaltensweisen korrekt unterstützt werden.
Sieh dir unbedingt auch die Liste der Verhaltensänderungen an, die sich auf alle Apps unter Android 14 auswirken, unabhängig vom targetSdkVersion
der App.
Hauptfunktion
Typen von Diensten im Vordergrund sind erforderlich
Wenn deine App auf Android 14 (API-Level 34) oder höher ausgerichtet ist, muss mindestens ein Diensttyp im Vordergrund für jeden Dienst im Vordergrund innerhalb deiner App angegeben werden. Du solltest einen Typ auswählen, der den Anwendungsfall deiner App im Vordergrund repräsentiert. Das System erwartet Dienste im Vordergrund eines bestimmten Typs, die einem bestimmten Anwendungsfall entsprechen.
Wenn ein Anwendungsfall in Ihrer Anwendung keinem dieser Typen zugeordnet ist, sollten Sie Ihre Logik auf die Verwendung von WorkManager oder vom Nutzer initiierten Datenübertragungsjobs migrieren.
Erzwingung der Berechtigung BLUETOOTH_CONNECT im BluetoothAdapter
Unter Android 14 wird die Berechtigung BLUETOOTH_CONNECT
beim Aufrufen der Methode BluetoothAdapter
getProfileConnectionState()
für Apps erzwungen, die auf Android 14 (API-Level 34) oder höher ausgerichtet sind.
Für diese Methode war bereits die Berechtigung BLUETOOTH_CONNECT
erforderlich, diese wurde aber nicht erzwungen. Achte darauf, dass deine App BLUETOOTH_CONNECT
in der Datei AndroidManifest.xml
deiner App deklariert, wie im folgenden Snippet gezeigt, und prüfe, ob ein Nutzer die Berechtigung erteilt hat, bevor du getProfileConnectionState
aufrufst.
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
OpenJDK 17-Updates
Android 14 continues the work of refreshing Android's core libraries to align with the features in the latest OpenJDK LTS releases, including both library updates and Java 17 language support for app and platform developers.
A few of these changes can affect app compatibility:
- Changes to regular expressions: Invalid group references are now
disallowed to more closely follow the semantics of OpenJDK. You might see
new cases where an
IllegalArgumentException
is thrown by thejava.util.regex.Matcher
class, so make sure to test your app for areas that use regular expressions. To enable or disable this change while testing, toggle theDISALLOW_INVALID_GROUP_REFERENCE
flag using the compatibility framework tools. - UUID handling: The
java.util.UUID.fromString()
method now does more strict checks when validating the input argument, so you might see anIllegalArgumentException
during deserialization. To enable or disable this change while testing, toggle theENABLE_STRICT_VALIDATION
flag using the compatibility framework tools. - ProGuard issues: In some cases, the addition of the
java.lang.ClassValue
class causes an issue if you try to shrink, obfuscate, and optimize your app using ProGuard. The problem originates with a Kotlin library that changes runtime behaviour based on whetherClass.forName("java.lang.ClassValue")
returns a class or not. If your app was developed against an older version of the runtime without thejava.lang.ClassValue
class available, then these optimizations might remove thecomputeValue
method from classes derived fromjava.lang.ClassValue
.
JobScheduler verstärkt Callback- und Netzwerkverhalten
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, it stops 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
". Consider migrating to WorkManager, which provides
support for asynchronous processing or migrating any heavy work into a
background 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
Für Apps, die auf 14 und höher ausgerichtet sind, wurde TileService#startActivityAndCollapse(Intent)
verworfen und löst beim Aufruf eine Ausnahme aus. Wenn Ihre App Aktivitäten über Kacheln startet, verwenden Sie stattdessen TileService#startActivityAndCollapse(PendingIntent)
.
Datenschutz
Teilweiser Zugriff auf Fotos und Videos
Mit Android 14 wird der Zugriff auf ausgewählte Fotos eingeführt. Damit können Nutzer Apps Zugriff auf bestimmte Bilder und Videos in ihrer Fotogalerie gewähren, anstatt Zugriff auf alle Medien eines bestimmten Typs zu gewähren.
Diese Änderung ist nur aktiviert, wenn deine App auf Android 14 (API-Level 34) oder höher ausgerichtet ist. Wenn Sie die Bildauswahl noch nicht verwenden, empfehlen wir, sie in Ihrer App zu implementieren. So können Sie Bilder und Videos einheitlich auswählen und die Privatsphäre der Nutzer verbessern, ohne Speicherberechtigungen anfordern zu müssen.
Wenn Sie eine eigene Galerieauswahl mit Speicherberechtigungen verwenden und die volle Kontrolle über Ihre Implementierung haben müssen, passen Sie Ihre Implementierung an, um die neue Berechtigung READ_MEDIA_VISUAL_USER_SELECTED
zu verwenden. Wenn Ihre App die neue Berechtigung nicht verwendet, führt das System die App im Kompatibilitätsmodus aus.
Nutzererfahrung
Sichere Full-Screen-Intent-Benachrichtigungen
Mit Android 11 (API-Level 30) konnte jede App Notification.Builder.setFullScreenIntent
verwenden, um Vollbild-Intents zu senden, während das Smartphone gesperrt ist. Sie können dies bei der App-Installation automatisch gewähren, indem Sie die Berechtigung USE_FULL_SCREEN_INTENT
im AndroidManifest deklarieren.
Full-Screen Intent-Benachrichtigungen sind für Benachrichtigungen mit extrem hoher Priorität gedacht, die die sofortige Aufmerksamkeit des Nutzers erfordern, z. B. eingehende Anrufe oder vom Nutzer konfigurierte Weckereinstellungen. Bei Apps, die auf Android 14 (API-Level 34) oder höher ausgerichtet sind, dürfen diese Berechtigungen nur für Apps verwendet werden, die nur Anrufe und Alarme anbieten. Im Google Play Store werden die USE_FULL_SCREEN_INTENT
-Standardberechtigungen für alle Apps widerrufen, die diesem Profil nicht entsprechen. Die Frist für diese Richtlinienänderungen endet am 31. Mai 2024.
Diese Berechtigung bleibt für Apps aktiviert, die auf dem Smartphone installiert wurden, bevor der Nutzer ein Update auf Android 14 durchführt. Nutzer können diese Berechtigung aktivieren oder deaktivieren.
Mit der neuen API NotificationManager.canUseFullScreenIntent
kannst du prüfen, ob deine App die Berechtigung hat. Falls nicht, kann deine App mit dem neuen Intent ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT
die Seite mit den Einstellungen öffnen, auf der Nutzer die Berechtigung erteilen können.
Sicherheit
Einschränkungen für implizite und ausstehende Intents
For apps targeting Android 14 (API level 34) or higher, Android restricts apps from sending implicit intents to internal app components in the following ways:
- Implicit intents are only delivered to exported components. Apps must either use an explicit intent to deliver to unexported components, or mark the component as exported.
- If an app creates a mutable pending intent with an intent that doesn't specify a component or package, the system throws an exception.
These changes prevent malicious apps from intercepting implicit intents that are intended for use by an app's internal components.
For example, here is an intent filter that could be declared in your app's manifest file:
<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>
If your app tried to launch this activity using an implicit intent, an exception would be thrown:
Kotlin
// Throws an exception when targeting Android 14. context.startActivity(Intent("com.example.action.APP_ACTION"))
Java
// Throws an exception when targeting Android 14. context.startActivity(new Intent("com.example.action.APP_ACTION"));
To launch the non-exported activity, your app should use an explicit intent instead:
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);
Empfänger von laufzeitregistrierten Broadcasts müssen das Exportverhalten angeben
Apps und Dienste, die auf Android 14 (API-Level 34) oder höher ausgerichtet sind und kontextregistrierte Empfänger verwenden, müssen mit einem Flag angeben, ob der Empfänger in alle anderen Apps auf dem Gerät exportiert werden soll: entweder RECEIVER_EXPORTED
bzw. RECEIVER_NOT_EXPORTED
.
Diese Anforderung trägt durch die Funktionen für diese Empfänger in Android 13 zum Schutz von Apps vor Sicherheitslücken bei.
Ausnahme für Empfänger, die nur System-Broadcasts empfangen
Wenn Ihre App einen Empfänger nur für System-Broadcasts über Context#registerReceiver
-Methoden wie Context#registerReceiver()
registriert, sollte bei der Registrierung des Empfängers kein Flag angegeben werden.
Sichererer dynamischer Code wird geladen
Wenn Ihre App auf Android 14 (API-Level 34) oder höher ausgerichtet ist und Dynamic Code Loading (DCL) verwendet, müssen alle dynamisch geladenen Dateien als schreibgeschützt markiert werden. Andernfalls gibt das System eine Ausnahme aus. Wir empfehlen, dass Apps Code möglichst nicht dynamisch laden, da sich so das Risiko erheblich erhöht, dass eine App durch Codeinjektion oder Codemanipulation manipuliert werden kann.
Wenn Sie Code dynamisch laden müssen, verwenden Sie den folgenden Ansatz, um die dynamisch geladene Datei (z. B. eine DEX-, JAR- oder APK-Datei) als schreibgeschützt festzulegen, sobald die Datei geöffnet und bevor Inhalte geschrieben werden:
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);
Dynamisch geladene Dateien bearbeiten, die bereits vorhanden sind
Damit für vorhandene dynamisch geladene Dateien keine Ausnahmen ausgelöst werden, empfehlen wir, die Dateien zu löschen und neu zu erstellen, bevor Sie versuchen, sie wieder dynamisch in Ihre App zu laden. Folgen Sie beim Neuerstellen der Dateien der Anleitung oben, um die Dateien beim Schreiben als schreibgeschützt zu markieren. Alternativ können Sie die vorhandenen Dateien als schreibgeschützt kennzeichnen. In diesem Fall empfehlen wir jedoch dringend, zuerst die Integrität der Dateien zu prüfen (z. B. indem Sie die Signatur der Datei mit einem vertrauenswürdigen Wert vergleichen), um Ihre Anwendung vor schädlichen Aktionen zu schützen.
Zusätzliche Einschränkungen für das Starten von Aktivitäten im Hintergrund
Bei Apps, die auf Android 14 (API-Level 34) oder höher ausgerichtet sind, wird durch das System weiter eingeschränkt, wann Apps Aktivitäten im Hintergrund starten dürfen:
- Wenn eine App eine
PendingIntent
mitPendingIntent#send()
oder ähnlichen Methoden sendet, muss die App zustimmen, wenn sie ihre eigenen Berechtigungen zum Starten von Hintergrundaktivitäten gewähren möchte, um den ausstehenden Intent zu starten. Zur Aktivierung muss die App einActivityOptions
-Bundle mitsetPendingIntentBackgroundActivityStartMode(MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
übergeben. - Wenn eine sichtbare Anwendung einen Dienst einer anderen Anwendung, die sich im Hintergrund mit der Methode
bindService()
befindet, bindet, muss die sichtbare Anwendung jetzt aktivieren, wenn sie dem gebundenen Dienst ihre eigenen Berechtigungen zum Starten von Hintergrundaktivitäten gewähren möchte. Zum Aktivieren muss die App beim Aufrufen der MethodebindService()
das FlagBIND_ALLOW_ACTIVITY_STARTS
enthalten.
Durch diese Änderungen werden die bestehenden Einschränkungen erweitert, um Nutzer zu schützen. Es wird verhindert, dass schädliche Anwendungen APIs missbrauchen und störende Aktivitäten im Hintergrund auslösen.
ZIP-Pfaddurchlauf
Bei Apps, die auf Android 14 (API-Level 34) oder höher ausgerichtet sind, verhindert Android die Sicherheitslücke beim ZIP-Pfaddurchlauf auf folgende Weise: ZipFile(String)
und ZipInputStream.getNextEntry()
gibt ZipException
aus, wenn die Namen der ZIP-Dateieinträge „..“ enthalten oder mit „/“ beginnen.
Apps können diese Überprüfung durch Aufrufen von dalvik.system.ZipPathValidator.clearCallback()
deaktivieren.
Nutzereinwilligung für jede MediaProjection-Erfassungssitzung erforderlich
Für Apps, die auf Android 14 (API-Level 34) oder höher ausgerichtet sind, wird in einem der folgenden Szenarien von MediaProjection#createVirtualDisplay
ein SecurityException
ausgelöst:
- Ihre App speichert das von
MediaProjectionManager#createScreenCaptureIntent
zurückgegebeneIntent
im Cache und übergibt es mehrmals anMediaProjectionManager#getMediaProjection
. - Ihre Anwendung ruft
MediaProjection#createVirtualDisplay
mehrmals auf derselbenMediaProjection
-Instanz auf.
In Ihrer App muss der Nutzer vor jeder Aufnahme um seine Einwilligung gebeten werden. Eine einzelne Erfassungssitzung ist ein einzelner Aufruf von MediaProjection#createVirtualDisplay
. Jede MediaProjection
-Instanz darf nur einmal verwendet werden.
Umgang mit Konfigurationsänderungen
Wenn Ihre Anwendung MediaProjection#createVirtualDisplay
aufrufen muss, um Konfigurationsänderungen wie Änderungen der Bildschirmausrichtung oder der Bildschirmgröße zu verarbeiten, können Sie die folgenden Schritte ausführen, um VirtualDisplay
für die vorhandene MediaProjection
-Instanz zu aktualisieren:
- Rufen Sie
VirtualDisplay#resize
mit der neuen Breite und Höhe auf. - Geben Sie einen neuen
Surface
mit der neuen Breite und Höhe fürVirtualDisplay#setSurface
an.
Rückruf registrieren
Ihre App sollte einen Callback für den Fall registrieren, in dem der Nutzer keine Einwilligung zum Fortsetzen einer Erfassungssitzung erteilt. Implementieren Sie dazu Callback#onStop
und lassen Sie Ihre App alle zugehörigen Ressourcen wie VirtualDisplay
und Surface
veröffentlichen.
Wenn deine App diesen Callback nicht registriert,
MediaProjection#createVirtualDisplay
gibt ein IllegalStateException
aus, wenn deine App ihn aufruft.
Nicht-SDK-Einschränkungen aktualisiert
Android 14 enthält aktualisierte Listen eingeschränkter Nicht-SDK-Schnittstellen, die auf der Zusammenarbeit mit Android-Entwicklern und den neuesten internen Tests basieren. Wann immer möglich, achten wir darauf, dass öffentliche Alternativen verfügbar sind, bevor wir Nicht-SDK-Schnittstellen einschränken.
Wenn deine App nicht auf Android 14 ausgerichtet ist, betreffen dich einige dieser Änderungen möglicherweise nicht sofort. Sie können derzeit zwar einige Nicht-SDK-Schnittstellen verwenden (abhängig von der Ziel-API-Ebene Ihrer App), aber die Verwendung von Nicht-SDK-Methoden oder -Feldern birgt immer ein hohes Risiko für Probleme mit Ihrer App.
Wenn Sie sich nicht sicher sind, ob Ihre Anwendung Nicht-SDK-Schnittstellen verwendet, können Sie die Anwendung testen. Wenn Ihre App Nicht-SDK-Schnittstellen verwendet, sollten Sie mit der Planung einer Migration zu SDK-Alternativen beginnen. Trotzdem können einige Apps für die Verwendung von Nicht-SDK-Schnittstellen infrage kommen. Wenn Sie für eine Funktion in Ihrer App keine Alternative zur Verwendung einer Nicht-SDK-Schnittstelle finden, sollten Sie eine neue öffentliche API anfordern.
Weitere Informationen zu den Änderungen in diesem Android-Release finden Sie unter Aktualisierungen der Einschränkungen für Schnittstellen, die nicht auf SDK basieren, unter Android 14. Allgemeine Informationen zu Nicht-SDK-Schnittstellen finden Sie unter Einschränkungen für Nicht-SDK-Schnittstellen.