Android 12 Changes and Adaptation Guide

insert image description here

The past few months have been a bit busy, and the one-year adaptation article is a bit late. But it’s actually okay, because our project will only be adapted in the second half of the year. My side is also researching and stepping on pits in advance to evaluate the workload. This time point is also fully in line with the review requirements of Google Play (November 1st), and it is even ahead of the domestic side. . . Without further ado, let's start.

First, let's talk about some Android 12behavior changes that affect applications running on . This part will directly affect all apps running on Android 12, so even if you don't fit it, you need to pay attention.

App splash screen

Starting with Android 12, SplashScreenAPIs enable new app launch animations for apps running on all Android 12 or higher devices. This includes entering app animations on startup, splash screens showing app icons, and transitions to the app itself.

Take a look at an example splash screen:
insert image description here

The elements of the splash screen are defined by XML resource files in the Android manifest. Each element has light mode and dark mode versions.

Customizable elements of the splash screen include app icons, icon backgrounds, and window backgrounds:

insert image description here

①The application icon should be a vector drawable object (AVD XML), which can be static or animated. While animations can be unlimited in length, we recommend no more than 1,000 milliseconds. By default, the launcher icon is used.

② An icon background can be optionally added; the icon background is useful when higher contrast is required between the icon and the window background. If you use an adaptive icon, its background is displayed when the contrast between the icon and the window background is high enough.

③ Like the adaptive icon, one-third of the foreground is covered.

④ The window background is composed of opaque monochrome. If the window background is set and is a solid color, it will be used by default if the corresponding property is not set.

In fact, this may not be suitable. . . For example, my vivo mobile phone can actually switch this option in the developer mode, and it is turned off by default. For users who use non-native systems, it is an imperceptible change. But in the end whether it fits or not depends on whether the product is acceptable.

A word of caution though: by default, SplashScreenthe theme's windowBackground(if it's monochrome) and launcher icons are used.
Therefore windowBackground, if the contrast between the color of the logo and the color of the logo is relatively low, the actual display effect will be relatively poor. I think this can be properly dealt with.

I don’t need to spend space to explain it here. If you have adaptation needs, you can refer to: Migrating the existing splash screen implementation to Android 12 and later versions

Stretch scrolling effect

On devices running Android 12 and higher, the visual behavior of scroll events has changed.

On Android 11 and lower, swiping to the borders will result in an arc-shaped shadow mask. In Android 12 and higher, visual elements stretch and bounce on drag events, and slide and bounce quickly on flick events.

insert image description here

Location Permissions: Approximate Location

If your app requested it ACCESS_COARSE_LOCATIONbut didn't ACCESS_FINE_LOCATION, this change doesn't affect your app.
Please add a picture description
If your app requests ACCESS_FINE_LOCATIONruntime permissions, you should also request ACCESS_COARSE_LOCATIONthe permission to handle situations where the user grants the app approximate location access.

insert image description here

Probably for compatibility purposes. In fact, I tested it on my vivo phone and found that only asking for ACCESS_FINE_LOCATIONpermission can also pop up normally and select location accuracy. But for the sake of insurance, the actual adaptation is still in accordance with the requirements of the official documents.

If the user selects an approximate location for the first time, the user will be prompted whether to change to a precise location when requesting permission for the second time. You can pay attention to this point.

insert image description here

Activity life cycle

Android 12 changes the system's default handling of launcher activities that are the root of their tasks when the Back button is pressed. In previous versions, the system dismissed finishthese activities when the "Back" button was pressed. In Android 12, the system now moves the activity and its tasks to the background instead of finishing the activity. This new behavior is consistent with using the HOME button.

Note: The system applies the new behavior only to the launcher activity that is the root of its task, that is, an activity that declares intent filters ACTION_MAINwith and . CATEGORY_LAUNCHERFor other activities, when the "Back" button is pressed, the system finishes the activity as before.

For most apps, this change means that users who quit the app using the Back button can resume the app more quickly from a warm state without having to completely restart the app from a cold state.

We recommend that you test your app against this change. If your app currently overrides onBackPressed()to handle back navigation and finish Activity, update your implementation to call super.onBackPressed()instead finish. Calling super.onBackPressed()moves the activity and its tasks to the background when appropriate and provides a more consistent navigation experience for users across applications.

Also note that in general, we recommend that you use the custom back navigation provided by the AndroidX Activity API , rather than replacing it onBackPressed(). If no component intercepts the system pressing the "Back" button, the AndroidX Activity API automatically follows the appropriate system behavior.


There are many more behavior changes, I just picked a few important ones above. For other changes, see: Android 12 Behavior Changes: All Apps

Next up are app behavior changes targeting Android 12. First we need to targetSdkVersiongo up to 31.

custom notification

Android 12 changes the look and behavior of custom notifications. Previously, custom notifications were able to use the entire notification area and define their own layout and style. This can cause layout compatibility issues on different devices and confuse users.

For apps targeting Android 12, custom layout notifications no longer use the full notification area; instead, the system uses the standard template. This template ensures that the custom notification is identical to other notifications in all states, such as the notification icon and expanded functionality in the collapsed state, and the notification icon, app name, and collapsed functionality in the expanded state. This behavior Notification.DecoratedCustomViewStyleis almost identical to that of .
Figure 4
The following shows a custom notification rendered in the collapsed and expanded states:

Figure 5
insert image description here
This change affects some apps that define Notification.Stylesubclasses, or that use the , , and methods Notification.Builderin .setCustomContentView(RemoteViews)setCustomBigContentView(RemoteViews)setContent(RemoteViews)setCustomHeadsUpContentView(RemoteViews)

For specific adaptation, the following points should be paid attention to:

  • The dimensions of custom views have changed. In general, the height provided to custom notifications is smaller than before. In the collapsed state, the maximum height of custom content has been reduced from 106dp to 48dp. In addition, the horizontal space is also reduced.
  • For apps targeting Android 12, all notifications are expandable. Generally, this means that if you are using setCustomContentView, you also need to use setBigCustomContentView, to ensure that the collapsed and expanded states are consistent.
  • To make sure the "Floating Notifications" (Heads Up) state looks the way you expect it to, don't forget to set the notification channel's priority (setPriority) to "High" (pop in screen).

Safer component export

If your app targets Android 12 or higher and contains activities, services, or broadcast receivers that use intent filters, you must explicitly declare the attribute for those app components android:exported. Otherwise the application cannot be installed.

So we can explicitly declare properties for these components in AndroidManifest.xmlthe search .<intent-filter>android:exported

android:exportedThe attribute indicates whether it can be called implicitly by other applications. So if your app component contains LAUNCHERa class, android:exportedset to true. In most other cases, android:exportedset to false. For example:

<service android:name="com.example.app.backgroundService"
         android:exported="false">
    <intent-filter>
        <action android:name="com.example.app.START_BACKGROUND" />
    </intent-filter>
</service>

For third-party SDKs, configure according to the corresponding document requirements. If the sdk does not have this adaptation, you can refer to this article: Android 12 automatic adaptation exported In-depth analysis to avoid pitfalls

PendingIntent mutability

If your app targets Android 12, you must PendingIntentspecify mutability for each object your app creates. This additional requirement increases the security of the application. Because the three-party app can be hijacked PendingIntent, and then rewrite the action, category, data, etc. inside, causing redirection attacks.

So the specific adaptation is PendingIntentto use PendingIntent.FLAG_MUTABLEthe or PendingIntent.FLAG_IMMUTABLEflag when creating. Otherwise, it will report at runtime IllegalArgumentException:

java.lang.IllegalArgumentException: com.dailyyoga.inc: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.

We can check PendingIntentwhere the code is used, for example PendingIntent.getActivity(), PendingIntent.getService(),
PendingIntent.getBroadcast()method. Specify mutability flags:

PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

In general, create FLAG_IMMUTABLEimmutable ​PendingIntent​objects whenever possible. If you need to create a variable ​PendingIntent​, then be sure to use an explicit intent and set the ​ComponentName​.

In our project, we use the androidx.worklibrary google-exo, which PendingIntentdoes not specify variability when creating objects, which leads to compatibility problems, so we need to upgrade the version to 2.7.0and 2.16.0above.

application hibernation

Android 11 introduced an automatic permission reset mechanism. If your app targets Android 12 and the user hasn't interacted with your app for a few months, the system automatically resets all permissions granted and puts your app to sleep.

A dormant application has the following characteristics:

  • Apps cannot run jobs or alerts from the background.
  • Apps cannot receive push notifications, including high-priority messages sent through Firebase Cloud Messaging.
  • The app's cache files will be deleted.

When the user next interacts with your app (including with widgets), your app will come out of hibernation and it can create jobs, reminders, and notifications again.

However, the system does not perform the following actions for your application:

  • Re-grant your app's runtime permissions. The user must re-grant your application these permissions.
  • Jobs, reminders and notifications will not be restored. You'll need to reschedule any jobs, alerts, and notifications that were scheduled before the application hibernated.

This behavior is similar to a user force-stopping your application manually from the system settings. To support this workflow more easily, use WorkManager. You can also add rescheduling logic in the ACTION_BOOT_COMPLETED broadcast receiver, which is called when your app comes out of hibernation and after the device boots.

For system-level applications, sleep will be exempted. If core use cases in your application are affected by hibernation, you can request the user to exempt the application from hibernation. For details, please refer to the official documentation , so I won’t introduce too much here.

Foreground service start limit

Apps targeting Android 12 or later cannot start foreground services while running in the background, with a few exceptions . If an app tries to start a foreground service while it is running in the background, and the foreground service does not satisfy one of these exception conditions, the system will raise the ForegroundServiceStartNotAllowedException.

You can execute the following ADB command to check if your app is performing background launch:

adb shell device_config put activity_manager \
  default_fgs_starts_restriction_notification_enabled true

Once the foreground service is found to be running in the background, a reminder will be pushed on the notification bar.

The adaptation method suggested by Google is to use it to plan and start expedited jobsWorkManager when the application is running in the background . Starting from 2.7.0, it can be called to declare that Worker uses expedited tasks.WorkManagerWorkManagersetExpedited()

Notify trampoline restrictions

When a user interacts with a notification, some apps respond to a notification tap by launching an app component that ultimately starts an Activity that the user ultimately sees and interacts with. This application component is called a notification mediator.

startActivity()That is to say, if you click the notification, start a broadcast or service, and then call the start activity in this broadcast or service . At this point the system prevents the activity from starting and displays the following message in Logcat:

Indirect notification activity start (trampoline) from PACKAGE_NAME, \
this should be avoided for performance reasons.

We can identify which application components act as notification trampolines by executing the following command:

adb shell dumpsys activity service \
  com.android.systemui/.dump.SystemUIAuxiliaryDumpService

After execution, click on your notification, if it is a notification trampoline. Log will output a log containing the text "NotifInteractionLog". This section contains the information needed to identify the component launched by tapping the notification.

The specific adaptation method is to use PendingIntentthe direct start target Activity.

bluetooth permission

If your application targets Android 12 or higher, please declare the following permission in the application's manifest file when using the Bluetooth function:

  • BLUETOOTH_SCAN: Allow Bluetooth devices to scan.
  • BLUETOOTH_CONNECT: Allow Bluetooth devices to connect.
  • BLUETOOTH_ADVERTISE: Allow the current Bluetooth device to be discovered by other Bluetooth devices.

insert image description here

If you do not apply for new permissions, the following error will be reported during scanning:

 java.lang.SecurityException: Need android.permission.BLUETOOTH_SCAN permission for android.content.AttributionSource@8825e139: GattService registerScanner

For previous bluetooth-related permission declarations, set android:maxSdkVersionto 30. This app compatibility step helps the system grant only the Bluetooth permissions your app needs to install on a device running Android 12.

<manifest>
    <!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH"
                     android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
                     android:maxSdkVersion="30" />

    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <!-- 只有当您的应用程序使用蓝牙扫描结果来获取物理位置时才需要 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
</manifest>

Declare if your application uses Bluetooth scan results to obtain physical location ACCESS_FINE_LOCATION. In previous versions (6.0 ~ 11), you must apply for location permission before you can scan Bluetooth.

On Android 12, if your app does not use Bluetooth scan results for physical location. You can add android:usesPermissionFlagsan attribute to your BLUETOOTH_SCANpermissions declaration and set the attribute's value to neverForLocation.

<manifest>
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
                     android:usesPermissionFlags="neverForLocation" />

    <!--可以删除定位权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
</manifest>

other

  • The default toast style changes, the upper limit of text is two lines, and the application icon will be displayed next to the text.

insert image description here

  • To protect private app data, Android 12 changes adb backupthe default behavior of the command. For apps that target Android 12 or higher, adb backupapp data is excluded from any other system data exported from the device when the user runs the command.
    If your testing or development workflow relies on using app data, you now have the option to export app data adb backupby setting to true in your app's manifest file .android:debuggable

There are so many adaptations about Android 12, and we still need to read the official documents for more changes. I also posted the link at the end of the article.

Regarding the adaptation of Android, I wrote from Android 6.0 to 12, which also includes the adaptation of individual features of the early 4.4 and 5.0. These contents are all in my Android adaptation column, I hope it can help you.

Finally, I look forward to your favorites, and give the author a support. So that I can continue to insist on bringing you my actual adaptation experience every year, thank you!

reference

Guess you like

Origin blog.csdn.net/qq_17766199/article/details/125376225