From 157696fbcd2b570baab6174d9d3e090eb9bbfd30 Mon Sep 17 00:00:00 2001 From: Cedric Goffoy Date: Wed, 25 Oct 2023 15:38:22 +0000 Subject: [PATCH 1/4] feat: whats new in android 14 --- _data/authors.yml | 2 + _posts/2023-10-25-android-14.md | 90 ++++++++++++++++++ images/posts/2023-10-25-android-14/header.png | Bin 0 -> 45210 bytes 3 files changed, 92 insertions(+) create mode 100644 _posts/2023-10-25-android-14.md create mode 100644 images/posts/2023-10-25-android-14/header.png diff --git a/_data/authors.yml b/_data/authors.yml index 1766755cf..38657e372 100644 --- a/_data/authors.yml +++ b/_data/authors.yml @@ -49,6 +49,8 @@ c_chaplin: url: https://twitter.com/corychaplin c_cousin: name: Camille Cousin +c_goffoy: + name: Cédric Goffoy c_niel: name: Camille Niel url: https://www.camilleniel.com/ diff --git a/_posts/2023-10-25-android-14.md b/_posts/2023-10-25-android-14.md new file mode 100644 index 000000000..86d457d28 --- /dev/null +++ b/_posts/2023-10-25-android-14.md @@ -0,0 +1,90 @@ +--- +layout: post +title: Android 14 is out +description: "and here’s what it means for users and developers" +author: [c_goffoy] +tags: [android, mobile, google, "14"] +color: rgb(254,91,73) +language: en +thumbnail: "/images/posts/2023-10-25-android-14/header.png" +--- +and here’s what it means for users and developers. + +With each new OS version, new things, upgrades, deprecations and changes are introduced, affecting the way we use and develop our apps. +Google keeps going in the direction of more privacy, more accessibility and more control over what the apps can do to maximise security and integrity. +Android 14 is no exception and here’s what it means for us in different areas that I will try to vulgarize to keep everyone on board. + +### Technical + +Technical changes build over features and APIs already introduced in previous versions, mostly Android 12 and 13. +They tend to modernise tools by catching up with some Java features and semantics, helping manufacturers and improving the developer’s IDE to embrace those changes. +Due to the nature of the changes, some of the following points may remain more opaque. + +* Screens are getting bigger with different ratios, we’re moving further and further away from the binary world of phone vs tablet. To ensure the best experience on this wide range of devices, Android 14 introduces the `Large Screen Compatibility Mode` to help manufacturers improve the experience on their devices. +* Updates to OpenJDK17 may require a bit of attention to apps using `Regex` that are not close enough to openJDK semantics, throwing exceptions when confronted to an invalid groupe reference. +* Generating a `UUID` from a string sees the validation become stricter and lead to exceptions due to deserialization issues. More than ever, it’s time to unit test our UUID generation. +* A bit of additional ruling may be needed to fix new Proguard issues when shrinking / obfuscating code involving `ClassValue`. +* The new `Back APIs` are now strengthened by built-in animations and support for custom ones. +* Making the `ForegroundService` type explicit is now mandatory, if your app did it properly back in Android 10 days when it was introduced, congratulations, you’re good to go. +* Foreground services are also encouraged to be migrated to user-initiated jobs. A new `RUN_USER_INITIATED_JOBS` permission is introduced and new methods on the `JobInfo` builder allow to set the userInitiated status along with the estimated amount of bytes the job will expect from the network. Scheduling the job is now done with the app foregrounded and the notification icon system remains the same so the user knows something is going on even if the app is backgrounded after. + +### Battery and performance + +Without a single ounce of surprise, Google continues its effort to improve battery life and takes steps to sanction bad actors publishing battery-draining or unstable apps. +Today, not crashing is no longer enough, developers should take steps to push their app to their full potential and that means power management and performance monitoring. + +* Bad behaviours like `ANRs (screen freezes)` or `background crashes` now more aggressively flag the guilty apps and put them at the bottom of the priority list where apps are fighting for resources, meaning they’ll also be the first to go if the system needs some. No more filtering out `ANR` and non-fatal crashes on Crashlytics, everything matters now. +* While on the subject of fighting for resources, let’s also note that now, `context-registered broadcasts` are now queued when the app is backgrounded and the system will deliver them when the app is awake or system conditions allow it. +* Another change to the cached state (aka when the app is backgrounded) impacts background tasks that can no longer be triggered unless one of the components is awake. This change pushes devs to use more `JobScheduler` and `WorkManager` that aren’t impacted by this change. +* Still with `Jobscheduler`, jobs don’t just fail silently anymore if they don’t respond in time but trigger an `ANR`, it is advised to move to ``WorkManager` with its out of the box async support. +* If a job requires a special network state to be triggered, the `ACCESS_NETWORK_STATE` permission is now mandatory. Without it, a `SecurityException` will be raised. +* `Intents` keep getting more and more headache prone as the implicit and pending intents now can only be delivered to exported components. If you need to reach an unexported component, explicit intent is your go-to solution. Note that mutable pending intents now need to specify a component or it will throw an exception. + +### Notifications + +Finding the right balance between informative presence and in-your-face nuisance has always been a challenge for notifications and it seems Google keeps pushing to make them less invasive and easier to dismiss or delay. + +* The `Fullscreen Intent` notifications that we see when our clock rings or when we receive a phone call are luckily already rarely used. +They are now more restricted and available only to apps declaring `Call` or `Alarm` features, meaning we shouldn’t see bad actors abusing this feature that would allow them to bypass the lock screen amongst other things. +* Non-dismissible `foreground notifications` are now dismissible in some cases but will remain non-dismissible + * on top of the `Lock Screen` to prevent it from being swiped by anyone accessing your device behind your back. + * from the `Clear all` feature to prevent misclicks. + +### Privacy and security + +This is, once again without surprise, where a lot of the changes happen and it is aligned with Google’s vision and goals when it comes to give users back the control of their data and permissions. +Some of them seem so obvious that it’s surprising to see them in action only now. Maybe the EU pressure with GDPR starts to pay off? Maybe… + +* Android 14 introduces new places where the data sharing purposes are displayed. Until now, we could only check them from the PlayStore app page. +Now, it will also be displayed in the `runtime permission popups`, starting with those related to location to remind why the data is necessary and with whom it will be shared. +* It will now be impossible to install apps that don’t target at least the `API 23` to prevent bad actors from exploiting security breaches discovered inside older Android versions. +/!\ Note that installed apps won’t be removed and the system won’t warn you when starting one of those apps, maybe a new feature for Android 15? +* `Dynamic Code Loading` now requires to flag the file as read-only to avoid any tampering or code injection. In any case, DCL should be avoided when possible and only trusted files should obviously be loaded this way. +* When saving a file inside the app storage, the system attributes to the file an owner package name, this name being the app name that saved it. +This feature allows apps to know which file they can open without requesting the external read permission. The issue was that by querying this id, other apps could access the list of installed apps by getting the owner name that weren’t them and deducting the owners apps. +To fix this, the name is now redacted, increasing again a little bit the user data protection, the list of the installed apps being considered a sensitive data by Google. +* If an app features `screen` or `audio recording`, it is now required to be granted the user consent to do so before each session start and therefore be able to handle permission denied scenarios. +* Zip files are also impacted as a fixed vulnerability with the `path transversal reading` now triggers an exception if some characters are found inside it. (Contains `..` Or starts with `/`) +* Even though already required, the `BLUETOOTH_CONNECT` permission was not yet enforced to access the profile state, it is now the case. +* Users are no more required to grant access to all `images` or `videos` to share or display a single media, Android 14 now upgrades the permission popup with an option to select only the media the app is allowed to access. +* Apps can now react to a user `screenshot` event, they can’t manipulate the content but developers can now add a callback bound to the activity lifecycle. +Sensitive screens should still be protected with the secure flag. +* Starting activities from the background with a `pending intent` or through another app in the foreground now requires the app to opt-in to this behaviour inside said activity. + +### Accessibility + +It is no secret that mobile devices are now owned by more and more people every year, which includes people with a range of disabilities or personalities that may make an app usage more challenging. +Android 14 helps them with new and upgraded features to ease their journey with a mobile device. + +* A step is taken towards low-vision users’ direction, the changes and impacts to the `font scaling` should be negligible to developers already using SP as their size units but a full testing pass with the scaling enabled should be scheduled to be safe. +* New tools inside Android studio are added to help developers handling `per-app language` more efficiently and easily. +* `Grammatical Inflection API` is introduced, helping developers with gendered languages management. It adds a layer of complexity to the strings files by having three genders by gendered language where the developers will add the strings affected by gender like `Vous êtes déconnecté` for masculine, `Vous êtes déconnectée` for feminine or `La déconnection est effective` for neutral. More work for translators but an overall better experience for users. + +--- + +All in all, Android 14 is an update faithful to the Google roadmap. +Users today are very different than users 10 years ago. They care more about their data, their privacy and the Mobile ecosystem and business is a lot more professional too. +It's important for us developers to be aware of those changes in order to continuously improve the experience, be it related to our core business or simply to keep the user engaged in a safe environment. + +When this article is released, Android 14 should be freshly out and developer teams hands deep in the migration tasks. +I hope you enjoyed the information and see you soon for more Android related articles! diff --git a/images/posts/2023-10-25-android-14/header.png b/images/posts/2023-10-25-android-14/header.png new file mode 100644 index 0000000000000000000000000000000000000000..8f7964c90de4baab5e6df6561c10e87c6675a7a7 GIT binary patch literal 45210 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 Date: Fri, 27 Oct 2023 08:29:25 +0000 Subject: [PATCH 2/4] self review --- ...android-14.md => 2023-10-27-android-14.md} | 54 +++++++++--------- .../header.png | Bin 2 files changed, 27 insertions(+), 27 deletions(-) rename _posts/{2023-10-25-android-14.md => 2023-10-27-android-14.md} (65%) rename images/posts/{2023-10-25-android-14 => 2023-10-27-android-14}/header.png (100%) diff --git a/_posts/2023-10-25-android-14.md b/_posts/2023-10-27-android-14.md similarity index 65% rename from _posts/2023-10-25-android-14.md rename to _posts/2023-10-27-android-14.md index 86d457d28..348358da6 100644 --- a/_posts/2023-10-25-android-14.md +++ b/_posts/2023-10-27-android-14.md @@ -1,54 +1,54 @@ --- layout: post title: Android 14 is out -description: "and here’s what it means for users and developers" +description: "Android 14 changes impacts" author: [c_goffoy] tags: [android, mobile, google, "14"] color: rgb(254,91,73) language: en -thumbnail: "/images/posts/2023-10-25-android-14/header.png" +thumbnail: "/images/posts/2023-10-27-android-14/header.png" --- -and here’s what it means for users and developers. +Here’s what it means for users and developers. With each new OS version, new things, upgrades, deprecations and changes are introduced, affecting the way we use and develop our apps. -Google keeps going in the direction of more privacy, more accessibility and more control over what the apps can do to maximise security and integrity. -Android 14 is no exception and here’s what it means for us in different areas that I will try to vulgarize to keep everyone on board. +Google keeps going in the direction of more privacy, more accessibility and more control over what the apps can do to maximize security and integrity. +Android 14 is no exception and here’s what I compiled on different topics that I will try to vulgarize to keep everyone on board. ### Technical Technical changes build over features and APIs already introduced in previous versions, mostly Android 12 and 13. -They tend to modernise tools by catching up with some Java features and semantics, helping manufacturers and improving the developer’s IDE to embrace those changes. -Due to the nature of the changes, some of the following points may remain more opaque. +They tend to modernize tools by catching up with some Java features and semantics, helping manufacturers and improving the developers' IDE to embrace those changes. +Due to the nature of the changes, this is the topic that has to remain...technical, sorry for that. -* Screens are getting bigger with different ratios, we’re moving further and further away from the binary world of phone vs tablet. To ensure the best experience on this wide range of devices, Android 14 introduces the `Large Screen Compatibility Mode` to help manufacturers improve the experience on their devices. -* Updates to OpenJDK17 may require a bit of attention to apps using `Regex` that are not close enough to openJDK semantics, throwing exceptions when confronted to an invalid groupe reference. -* Generating a `UUID` from a string sees the validation become stricter and lead to exceptions due to deserialization issues. More than ever, it’s time to unit test our UUID generation. -* A bit of additional ruling may be needed to fix new Proguard issues when shrinking / obfuscating code involving `ClassValue`. +* Mobile screens are getting bigger with more ratios to support, we’re moving further and further away from the binary world of phone vs tablet. To ensure the best experience on this wide range of devices, Android 14 introduces the `Large Screen Compatibility Mode` to help manufacturers improve the experience on their devices. +* Updates to OpenJDK17 may require a bit of attention from apps using `Regex` that are not close enough to openJDK's new semantics, throwing exceptions when confronted to an invalid groupe reference. +* Generating a `UUID` from a string sees the validation become stricter and will now lead to exceptions due to deserialization issues. More than ever, it’s time to unit test UUID generation. +* A bit of additional ruling may be needed to fix Proguard issues when shrinking / obfuscating code involving the `ClassValue` class coming with `API34`. * The new `Back APIs` are now strengthened by built-in animations and support for custom ones. -* Making the `ForegroundService` type explicit is now mandatory, if your app did it properly back in Android 10 days when it was introduced, congratulations, you’re good to go. -* Foreground services are also encouraged to be migrated to user-initiated jobs. A new `RUN_USER_INITIATED_JOBS` permission is introduced and new methods on the `JobInfo` builder allow to set the userInitiated status along with the estimated amount of bytes the job will expect from the network. Scheduling the job is now done with the app foregrounded and the notification icon system remains the same so the user knows something is going on even if the app is backgrounded after. +* Making the `ForegroundService` type explicit is now mandatory, if the implementation was already properly done back in the Android 10 days when it was introduced, congratulations, nothing to do here. +* Foreground services are also encouraged to be migrated to user-initiated jobs. A new `RUN_USER_INITIATED_JOBS` permission is introduced and new methods on the `JobInfo` builder allow to set the `userInitiated()` status along with the estimated amount of bytes the job will expect from the network. Scheduling the job is now done with the app foregrounded and the notification icon system remains the same so the user knows something is going on even if the app is backgrounded post launch. ### Battery and performance -Without a single ounce of surprise, Google continues its effort to improve battery life and takes steps to sanction bad actors publishing battery-draining or unstable apps. +Without a single ounce of surprise, Google continues its effort to improve battery life and takes steps towards sanctioning bad actors that publish battery-draining or unstable apps. Today, not crashing is no longer enough, developers should take steps to push their app to their full potential and that means power management and performance monitoring. -* Bad behaviours like `ANRs (screen freezes)` or `background crashes` now more aggressively flag the guilty apps and put them at the bottom of the priority list where apps are fighting for resources, meaning they’ll also be the first to go if the system needs some. No more filtering out `ANR` and non-fatal crashes on Crashlytics, everything matters now. +* Bad behaviours like `ANRs (screen freezes)` or `background crashes` now more aggressively flag the guilty apps and put them at the bottom of the priority list where apps are fighting for resources, meaning they’ll also be the first to go if the system needs some. No more filtering out `ANRs` and non-fatal crashes on Crashlytics, everything matters now. * While on the subject of fighting for resources, let’s also note that now, `context-registered broadcasts` are now queued when the app is backgrounded and the system will deliver them when the app is awake or system conditions allow it. -* Another change to the cached state (aka when the app is backgrounded) impacts background tasks that can no longer be triggered unless one of the components is awake. This change pushes devs to use more `JobScheduler` and `WorkManager` that aren’t impacted by this change. -* Still with `Jobscheduler`, jobs don’t just fail silently anymore if they don’t respond in time but trigger an `ANR`, it is advised to move to ``WorkManager` with its out of the box async support. +* Another change to the cached state (aka when the app is backgrounded) impacts background tasks that can no longer be triggered unless one of the app components is awake. This change pushes devs to use framework's `JobScheduler` and `WorkManager` more as they aren’t impacted by this change. +* Still with `Jobscheduler`, jobs don’t just fail silently anymore if they don’t respond in time but trigger an `ANR`, it is advised to move to `WorkManager` with its out of the box async support. * If a job requires a special network state to be triggered, the `ACCESS_NETWORK_STATE` permission is now mandatory. Without it, a `SecurityException` will be raised. * `Intents` keep getting more and more headache prone as the implicit and pending intents now can only be delivered to exported components. If you need to reach an unexported component, explicit intent is your go-to solution. Note that mutable pending intents now need to specify a component or it will throw an exception. ### Notifications -Finding the right balance between informative presence and in-your-face nuisance has always been a challenge for notifications and it seems Google keeps pushing to make them less invasive and easier to dismiss or delay. +Finding the right balance between informative presence and in-your-face nuisance has always been a challenge for notifications and it seems Google keeps pushing to make them less invasive and easier for the user to dismiss or delay them. * The `Fullscreen Intent` notifications that we see when our clock rings or when we receive a phone call are luckily already rarely used. They are now more restricted and available only to apps declaring `Call` or `Alarm` features, meaning we shouldn’t see bad actors abusing this feature that would allow them to bypass the lock screen amongst other things. * Non-dismissible `foreground notifications` are now dismissible in some cases but will remain non-dismissible - * on top of the `Lock Screen` to prevent it from being swiped by anyone accessing your device behind your back. - * from the `Clear all` feature to prevent misclicks. + - on top of the `Lock Screen` to prevent it from being swiped by anyone accessing a device behind the owner's back. + - from the `Clear all` feature to prevent misclicks. ### Privacy and security @@ -58,10 +58,10 @@ Some of them seem so obvious that it’s surprising to see them in action only n * Android 14 introduces new places where the data sharing purposes are displayed. Until now, we could only check them from the PlayStore app page. Now, it will also be displayed in the `runtime permission popups`, starting with those related to location to remind why the data is necessary and with whom it will be shared. * It will now be impossible to install apps that don’t target at least the `API 23` to prevent bad actors from exploiting security breaches discovered inside older Android versions. -/!\ Note that installed apps won’t be removed and the system won’t warn you when starting one of those apps, maybe a new feature for Android 15? +Be aware that installed apps won’t be removed and the system won’t warn you when starting one of those apps, maybe a new feature for Android 15? * `Dynamic Code Loading` now requires to flag the file as read-only to avoid any tampering or code injection. In any case, DCL should be avoided when possible and only trusted files should obviously be loaded this way. -* When saving a file inside the app storage, the system attributes to the file an owner package name, this name being the app name that saved it. -This feature allows apps to know which file they can open without requesting the external read permission. The issue was that by querying this id, other apps could access the list of installed apps by getting the owner name that weren’t them and deducting the owners apps. +* When saving a file inside the app storage, the system attributes to the file an owner id, this id being the app package name that saved it. +This feature allows apps to know which file they can open without requesting the external read permission. The issue was that by querying this id, other apps could access the owner ids that weren’t them and deducting the owner's installed apps list. To fix this, the name is now redacted, increasing again a little bit the user data protection, the list of the installed apps being considered a sensitive data by Google. * If an app features `screen` or `audio recording`, it is now required to be granted the user consent to do so before each session start and therefore be able to handle permission denied scenarios. * Zip files are also impacted as a fixed vulnerability with the `path transversal reading` now triggers an exception if some characters are found inside it. (Contains `..` Or starts with `/`) @@ -69,21 +69,21 @@ To fix this, the name is now redacted, increasing again a little bit the user da * Users are no more required to grant access to all `images` or `videos` to share or display a single media, Android 14 now upgrades the permission popup with an option to select only the media the app is allowed to access. * Apps can now react to a user `screenshot` event, they can’t manipulate the content but developers can now add a callback bound to the activity lifecycle. Sensitive screens should still be protected with the secure flag. -* Starting activities from the background with a `pending intent` or through another app in the foreground now requires the app to opt-in to this behaviour inside said activity. +* Starting activities from the background with a `pending intent` or through another app in the foreground now requires the app to opt-in to this feature inside said activity and is no longer a default behaviour. ### Accessibility It is no secret that mobile devices are now owned by more and more people every year, which includes people with a range of disabilities or personalities that may make an app usage more challenging. Android 14 helps them with new and upgraded features to ease their journey with a mobile device. -* A step is taken towards low-vision users’ direction, the changes and impacts to the `font scaling` should be negligible to developers already using SP as their size units but a full testing pass with the scaling enabled should be scheduled to be safe. +* A step is taken towards low-vision users’ direction, the changes and impacts to the `font scaling` should be negligible to developers already properly using `SP` as their size units but a full testing pass with the scaling enabled should be scheduled to be safe and tweak improvable screens. * New tools inside Android studio are added to help developers handling `per-app language` more efficiently and easily. -* `Grammatical Inflection API` is introduced, helping developers with gendered languages management. It adds a layer of complexity to the strings files by having three genders by gendered language where the developers will add the strings affected by gender like `Vous êtes déconnecté` for masculine, `Vous êtes déconnectée` for feminine or `La déconnection est effective` for neutral. More work for translators but an overall better experience for users. +* `Grammatical Inflection API` is introduced, offering developers working on apps with gendered languages new tools. It adds a layer of complexity to the strings files by having three gender-files by gendered language. In those files are added only the strings affected by gender inflections like `Vous êtes déconnecté` for masculine, `Vous êtes déconnectée` for feminine or `La déconnection est effective` for neutral in french. More work for developers and translators but an overall better experience for users. --- All in all, Android 14 is an update faithful to the Google roadmap. -Users today are very different than users 10 years ago. They care more about their data, their privacy and the Mobile ecosystem and business is a lot more professional too. +Users today are very different than users 10 years ago. They care more about their data and their privacy; the Mobile ecosystem and business is also a lot more professional. It's important for us developers to be aware of those changes in order to continuously improve the experience, be it related to our core business or simply to keep the user engaged in a safe environment. When this article is released, Android 14 should be freshly out and developer teams hands deep in the migration tasks. diff --git a/images/posts/2023-10-25-android-14/header.png b/images/posts/2023-10-27-android-14/header.png similarity index 100% rename from images/posts/2023-10-25-android-14/header.png rename to images/posts/2023-10-27-android-14/header.png From be6bde5957411602ccb34209cca50a3460b92e59 Mon Sep 17 00:00:00 2001 From: Cedric Goffoy Date: Mon, 4 Dec 2023 15:53:09 +0000 Subject: [PATCH 3/4] add official doc links --- _posts/2023-10-27-android-14.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/_posts/2023-10-27-android-14.md b/_posts/2023-10-27-android-14.md index 348358da6..39c3ba1a4 100644 --- a/_posts/2023-10-27-android-14.md +++ b/_posts/2023-10-27-android-14.md @@ -88,3 +88,13 @@ It's important for us developers to be aware of those changes in order to contin When this article is released, Android 14 should be freshly out and developer teams hands deep in the migration tasks. I hope you enjoyed the information and see you soon for more Android related articles! + + + + + +* [Changes potentially affecting all apps](https://developer.android.com/about/versions/14/behavior-changes-all) +* [Changes affecting apps targetting Android 14](https://developer.android.com/about/versions/14/behavior-changes-14) +* [New features introduced by Android 14](https://developer.android.com/about/versions/14/features) +* [APIs changelog](https://developer.android.com/sdk/api_diff/34/changes) +* [Overview](https://developer.android.com/about/versions/14/summary) From 914bec9e53835f3b592934b92802cc3a3b36d8e8 Mon Sep 17 00:00:00 2001 From: Cedric Goffoy Date: Tue, 5 Dec 2023 09:49:52 +0000 Subject: [PATCH 4/4] update date --- ...10-27-android-14.md => 2023-12-05-android-14.md} | 2 +- .../header.png | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename _posts/{2023-10-27-android-14.md => 2023-12-05-android-14.md} (99%) rename images/posts/{2023-10-27-android-14 => 2023-12-05-android-14}/header.png (100%) diff --git a/_posts/2023-10-27-android-14.md b/_posts/2023-12-05-android-14.md similarity index 99% rename from _posts/2023-10-27-android-14.md rename to _posts/2023-12-05-android-14.md index 39c3ba1a4..449e2b718 100644 --- a/_posts/2023-10-27-android-14.md +++ b/_posts/2023-12-05-android-14.md @@ -6,7 +6,7 @@ author: [c_goffoy] tags: [android, mobile, google, "14"] color: rgb(254,91,73) language: en -thumbnail: "/images/posts/2023-10-27-android-14/header.png" +thumbnail: "/images/posts/2023-12-05-android-14/header.png" --- Here’s what it means for users and developers. diff --git a/images/posts/2023-10-27-android-14/header.png b/images/posts/2023-12-05-android-14/header.png similarity index 100% rename from images/posts/2023-10-27-android-14/header.png rename to images/posts/2023-12-05-android-14/header.png