There are a lot of potholes

The Android 11 adaptation has finally begun. Write it down for those who need it.

1. Preparation

As usual, first change the targetSdkVersion in our project to 30. Maybe debugging things with compatibility, which I’ll talk about later.

2. The storage mechanism is updated

Scoped Storage

The detailed adaptation is not much different from the Android 10 adaptation walkthrough last year.

Be careful, however, to enforce partitioned storage with targetSdkVersion >= 30. Before the AndroidManifest. Add android: XML requestLegacyExternalStorage = “true” adaptation method has no effect.

One more change: Android 11 allows you to use apis other than the MediaStore API to access media files in shared storage directly through the file path. This includes:

  • FileAPI.
  • Native libraries, for examplefopen().

This is good news for you, assuming you haven’t adapted to Android 10 before. Android 10 in AndroidManifest. Add Android: XML requestLegacyExternalStorage = “true” to adaptation, Android visit media File using the File directly on 11 API. Have to say, wait for the party to succeed?

However, using the raw file approach to directly access media files in shared storage redirects to the MediaStore API, which has a functional impact (random reads and writes are about twice as slow). And using raw files directly does not offer any advantage over using the MediaStore API, so it is strongly advocated by officials.

MANAGE_EXTERNAL_STORAGE

Of course, there is a simple and rough adaptation, access to external storage permissions. Assume that your use is mobile phone housekeeper, file manager this kind of demand to visit a large number of files of app, can beg MANAGE_EXTERNAL_STORAGE permission, the user is guided to the system Settings page open. The code is as follows:

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />

Copy the code
public static void checkStorageManagerPermission(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&! Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); }}Copy the code

[

Note that even if you have MANAGE_EXTERNAL_STORAGE, you cannot access files in the Android/data/ directory.

Domestic use of the MANAGE_EXTERNAL_STORAGE permission should have no impact. However, in Google Play, the requirements explain why the existing SAF or MediaStore does not meet your application requirements, and the application is allowed after review. So in general, I personally do not recommend that you use MANAGE_EXTERNAL_STORAGE permission directly in order to adapt to a brief.

Other details of the changes can be found in the documentation: Storage mechanism updates in Android 11.

New features for Android 11, Scoped Storage

Storage visit structure (SAF) changed

Android 11 adds the following constraints to SAF:

  • usingACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT, cannot readAndroid/data/ 和 Android/obb/ Catalog and all subdirectories.
  • usingACTION_OPEN_DOCUMENT_TREEUnable to authorize access to the root directory, Download folder.

REQUEST_INSTALL_PACKAGES

In 8.0 adaptation, our equipment APK package before the demand begged “equipment do not know the origin of the use of” permission. Generally speaking, the first step is to jump to the authorization page for the user to manually open, and then come back to the APP for equipment.

In Android 11, apps are killed when users turn on the “device-unknown” permission. This behavior is related to forcing partitioned storage, because applications with REQUEST_INSTALL_PACKAGES permissions can visit other applications’ Android/ OBB directories.

Fortunately, after the user discloses the permissions, the app will be killed, but the device page will still pop up.

Now I have not found a suitable way to deal with this change. For details, see: Android 11 feature adjustment: Device external background application requirements restart APP

3. Change the permission

Single permission authorization

Starting with Android 11, whenever you use begged permission related to location information, microphone or camera, the user-facing permission dialog box will include this once option. Assuming the user selects this option in the dialog box, the system will publish a temporary single authorization to the application.

[

The use of single permission authorization can visit relevant data within a period of time, depending on the behavior of the user and the operation of the user:

  • When the applied Activity is visible, the application can visit the relevant data.
  • Assuming the user moves the application into the background, the application can continue to visit relevant data for a short period of time.
  • Suppose you claim a foreground service when your Activity is visible, and the user then moves your application to the background, your application can continue to visit the relevant data until the foreground service terminates.
  • Assuming that the user revokes a single authorization (such as in an architecture setting), the application cannot access the relevant data, whether or not you claim the front-end service. As with any permission, the application process is aborted if the user revokes the application’s single authorization.

When the user opens the next use and use of a function begged visit azimuth information, microphone or camera, the system will again prompt users to announce permissions.

Assume that you are before the use of permission to beg the relevant permission, then this change about your use of no impact.

Begged azimuth permission

This part has been adjusted in Android 10, and the rules are as follows:

Begged ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission indicate in the foreground with access to equipment location information. In begged box, choose “always allow” indicates the front and back can obtain azimuth information, choose “only in the use of the process of allowing” only indicate the front of the permission.

In Android 11, the “always allow” option is removed from the begging box. In other words, acquiescence will not publish your background access to device location information. Assume that the inspection begged ACCESS_BACKGROUND_LOCATION permission together begged any other permissions, the system will throw out of order, will not be published to use any of the permissions.

The official adaptation proposal and reasons are as follows:

Advocate the use of the other side of the authority to implement incremental begged, begged the front desk azimuth information visit permission, then begged background azimuth information visit permission. The implementation of incremental begged can provide users with greater control and transparency, because they can better understand the use of what function demand background location information visit permissions.

Two points can be summarized:

  • First begged the reception azimuth information visit permissions, and then begged the background azimuth information visit permissions.
  • Alone begged background location information visit permissions, do not beg with other permissions.

Here’s another thing to watch out for when different approaches are applied to Android 11:

  • The Android 10 approach allows access to both front and back location information permissions, but also does not have the “always allow” option.
  1. When there is no front and background azimuth information permission:

[

  1. With the location information permission of the front desk:

[

  • Android 11 is the application of policy approach
  1. There is no front and back azimuth information permission, can only beg the front azimuth information permission:

[

  1. Have the front desk azimuth information permission, begged background azimuth information system will jump to the following Settings page.

[Choose “always allow” marked with front and background azimuth information visit permission, assume that the user rejected two use of positioning visit begged (directly back), behind begged the same permission will be directly prompted begged failure. (Here we need to guide the user)

To explain “reject twice”, this is the added visibility of the Permissions dialog on Android 11. Previously, we clicked “Ask no more” to indicate that we reject permissions. Now it also includes the same kind of go to system Settings, then click back button, also to deny authorization. Of course, if the user presses the back button to close the permissions dialog box, this operation does not count.

To sum up, the difference with Android 10 is to separate the background permission begged, increased the user “rejected” conditions, to avoid the use of repeated begged users have rejected permission.

Package visibility

Package visibility is a new feature on Android 11 that improves system privacy security. It has the effect of restricting the app’s access to other apps’ information and device status. Avoid the use of virus software, spyware, network fishing, user equipment information leakage and other security issues.

Obtain a list of active visible applications that can be implemented using the adb shell Dumpsys package queries command to locate the Element yable. Here is the implementation effect of the Vivo IQoo phone.

Queries: system apps queryable: false forceQueryable: [com.android.BBKCrontab,com.vivo.fingerprint,com.vivo.epm,com.vivo.abe,com.vivo.fingerprintengineer,com.vivo.contentcatc her,com.vivo.floatingball,com.vivo.agent,com.vivo.nightpearl,android,com.wapi.wapicertmanage,com.vivo.vms,co m.android.providers.settings,com.vivo.upslide,com.vivo.assistant,com.vivo.vivokaraoke,com.vivo.fingerprintui,com.android .wallpaperbackup,com.bbk.facewake,com.vivo.faceunlock,com.vivo.doubleinstance,com.vivo.audiofx,com.iqoo.powersav ing,com.bbk.SuperPowerSave,com.vivo.vibrator4d,com.vivo.smartunlock,com.vivo.globalanimation,com.vivo.appfilter,com.vivo .voicewakeup,com.vivo.minscreen,com.android.bbklog,com.mobile.cos.iroaming,com.vivo.networkstate,com.vivo.daemon Service,com.vivo.smartshot,com.vivo.vtouch,com.android.networkstack.tethering.inprocess,com.android.localtransport,com.v ivo.pem,com.vivo.wifiengineermode,com.android.server.telecom,com.vivo.gamecube,com.vivo.aiengine,com.vivo.multin lp,com.vivo.smartmultiwindow,com.vivo.permissionmanager,com.qti.diagservices,com.vivo.bsptest,com.qti.snapdragon.qdcm_ff ,com.vivo.dr,com.vivo.sps,com.android.dynsystem,com.vivo.setupwizard,com.vivo.gamewatch,com.android.keychain,com .vivo.faceui,com.android.networkstack.inprocess,com.android.location.fused,com.android.inputdevices,com.android.settings ,com.iqoo.engineermode,com.vivo.fuelsummary] [com.qualcomm.uimremoteserver,com.vivo.devicereg,com.qti.qualcomm.deviceinfo,com.volte.config,com.android.mms.service,co m.android.ons,com.qualcomm.qcrilmsgtunnel,com.vivo.sim.contacts,com.qualcomm.qti.uimGbaApp,com.qualcomm.qti. modemtestmode,com.android.stk,com.android.vendors.bridge.softsim,com.qualcomm.uimremoteclient,com.qti.qualcomm.datastatu snotification,com.qualcomm.qti.uim,com.android.phone,com.qualcomm.qti.dynamicddsservice,com.qualcomm.qti.telepho nyservice,com.android.cellbroadcastservice,com.android.providers.telephony,com.qti.dpmserviceapp,com.android.incallui] [com.android.vivo.tws.vivotws,com.android.bluetooth] com.android.nfc com.android.se com.android.networkstack.permissionconfig com.android.shell com.android.providers.media.module com.android.wifi.resources.overlay.common com.android.theme.icon_pack.filled.themepicker com.android.theme.icon_pack.circular.themepicker com.android.server.telecom.overlay.common ......Copy the code

Can see is the system use package name, so our tripartite use of tacit approval is not seen. Most of the changes affect the interaction between demand for shared payment and other applications. Here’s a brief example:


private static boolean hasActivity(Context context, Intent intent) {
PackageManager packageManager = context.getPackageManager();
return packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
}
public void test() {
Intent intent = new Intent();
intent.setClassName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareImgUI");
Log.d("hasActivity:", hasActivity(this, intent) + "");
}

Copy the code

The hasActivity method uses queryIntentActivities to check whether the page exists. However, in targetSdkVersion >= 30, these tripartite acquiescence is not allowed. So they’ll all come back false. Similar methods getInstalledPackages and getPackageInfo are also constrained accordingly.

The solution is simple: add the queries element to androidmanifest.xml and add the package name visible to the requirements.

<manifest package="com.example.app"> <queries> <package android:name="com.tencent.mm" /&gt; <- Specify wechat package name </queries>... </manifest>Copy the code

I also used the following package names in the adaptation, which we can add as needed:

<queries>
<!-- 微博 -->
<package android:name="com.sina.weibo" />
<!-- QQ -->
<package android:name="com.tencent.mobileqq" />
<!-- 支付宝 --&gt;
<package android:name="com.eg.android.AlipayGphone" />
<!-- AlipayHK -->
<package android:name="hk.alipay.wallet" />
</queries>

Copy the code

Instead of adding the package name directly, we can add the package name by intent and provider:

<manifest package="com.example.app"> &lt; queries> <intent> <action android:name="android.intent.action.SEND" /> <data android:mimeType="image/jpeg" /> </intent&gt; <provider android:authorities="com.example.settings.files" /> </queries> ... </manifest>Copy the code

Detailed rules visit: Handling package visibility

Of course, there is a crude way to ask permission QUERY_ALL_PACKAGES directly. Assuming that your app needs to be on Google Play, you might want to watch out for guidelines. In order to respect user privacy, it is recommended that our application be adapted to the minimum package visibility required for normal operations.

The startActivity method is not affected by the visibility of the software package, even if hasActivity is false. If we do a similar hasActivity check before the jump, it will be affected.

The final need is careful, use queries element needs Android Gradle plug-in version is 4.1 and above, due to the old version of other plug-ins are not compatible with this element, appeared merge manifest fault.

Front Desk Service Type

In Android 10, the location service type needs to be added to the corresponding service in the foreground service visit location information.

Similarly, in Android 11, camera or microphone service is visited in the foreground service, and camera or microphone service type needs to be added in the corresponding service.

<manifest>
...
<service
android:name="MyService"
android:foregroundServiceType="microphone|camera" /&gt;
</manifest>

Copy the code

This bound change makes it impossible for the application to call the camera and microphone in the background. If need to use, can only be the front desk open the front desk service. Unless:

  • Services are advocated by architecture components.
  • The service is through the use of widget propositions.
  • Services are interclaimed with notifications.
  • A service isPendingIntentIt is sent from another visible application.
  • The service is claimed by an application that is a DPC and operates in full device form.
  • The service is supplied by oneVoiceInteractionServiceThe use of propositions.
  • The service consists of one withSTART_ACTIVITIES_FROM_BACKGROUNDAssertion of use of authority.

Active Permission Reset

Assuming that Android 11 or higher is used as the guideline and has not been used for several months, the system will protect user data by actively resetting the active permissions of the user’s published work. As shown below:

[

Watch out for an active reset switch in the image above. Let’s say our application has special needs that lead users to close it. Example code is as follows:

Public void checkAutoRevokePermission Context (Context) {/ / judging whether to open the if (Build) VERSION) SDK_INT > = Build. VERSION_CODES. The R && ! Context. GetPackageManager (). IsAutoRevokeWhitelisted ()) {/ / jump Settings page Intent Intent = new Intent(Intent.ACTION_AUTO_REVOKE_PERMISSIONS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setData(Uri.fromParts("package", context.getPackageName(), null)); context.startActivity(intent); }}Copy the code

SYSTEM_ALERT_WINDOW permissions

I did not use this part in the adaptation, and directly copied the document:

In Android 11, the system will publish SYSTEM_ALERT_WINDOW permissions for certain types of applications depending on the request:

  • The system will have the idea to have ROLE_CALL_SCREENING and begged SYSTEM_ALERT_WINDOW all use published permissions. If you lose ROLE_CALL_SCREENING, you lose this permission.

  • The system will try to publish permissions to all applications that have screen intercepts from MediaProjection and request SYSTEM_ALERT_WINDOW, unless the user has clearly declined to do so. This permission is lost when an abort capture screen is applied. This use case is primarily used for live games.

These applications do not need to send ACTION_MANAGE_OVERLAY_PERMISSION to get SYSTEM_ALERT_WINDOW permission, they only need to directly beg SYSTEM_ALERT_WINDOW.

MANAGE_OVERLAY_PERMISSION Intent always directs the user to the system permission screen

Starting with Android 11, ACTION_MANAGE_OVERLAY_PERMISSION Intent always takes the user to the top-level Settings screen, where the user can declare or revoke the SYSTEM_ALERT_WINDOW permission applied. Any package: data in the intent is ignored.

On lower versions of Android, the ACTION_MANAGE_OVERLAY_PERMISSION Intent specifies a package that directs the user to a dedicated screen for permissions. Starting with Android 11, this functionality will no longer be supported, but it will be necessary for users to first pick which permissions to publish or revoke. This change makes the disclosure of permissions more purposeful and protects users.

Read the phone number

Suppose you get the phone number through getLine1Number in TelecomManager or getMsisdn in TelephonyManager. Add READ_PHONE_NUMBERS to Android 11. The use of other methods is not restricted.

<manifest> <! -- Assuming the application only applies this permission to Android 10 and below, MaxSdkVersion ="29" --> <uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="29" /> <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" /&gt; </manifest>Copy the code

4. Other behavior changes

Customize the Toast of the view

Android 11 is used as a policy approach, and the Toast audio system that sends custom views from the background will be blocked. The front desk is not affected. Toast corresponding setView and getView have also been thrown away and are not recommended for use.

Assuming it is to be used in the background, we recommend using tacit toast or Snackbar instead.

APK signature

Android 11 is a policy approach, only through the use of V1 signature can not be used on Android 11 devices or update. It is necessary to sign in format V2 or higher.

Android 11 adds support for THE APK signature scheme V4.

AsyncTask

AsyncTask is now deprecated in Android 11 and is migrated to Kotlin’s coroutine.

In additionHandlerIs not specifiedLooperThe structural approach of the. [

Advocate clearly specifying Looper:

private Handler handler = new Handler(Looper.myLooper()); // Private Handler Handler = new Handler(looper.getMainLooper ());Copy the code

5. Add something new

Compatibility debug stuff

In the past, when we do adaptation, we need to first modify the targetSdkVersion in our project to the corresponding version. As a result, your adaptation process may be affected by other changes, and this new compatibility debug thing allows you to turn over adaptations for each change without upgrading targetSdkVersion.

Application method:

  • Find the application compatibility change option in developer options.
  • Click in to find the debugging application you need
  • In the list of changes, find the change you want to open or close, and click the corresponding switch.

[Top rowDEFAULT_SCOPED_STORAGEFor details, see the Android 11 change list.

About compatibility debugging things detailed use of the way to see: compatibility structure things, here is limited to space will not open said.

Wireless debugging

A wireless debugging feature has been added to Android 11’s developer options. Similar to the function of connecting bluetooth headset, it can be used for daily development and debugging without USB connection. (Unlike the old Android WIFI ADB, this is real wireless, ha ha)

[

Application method:

  • Find wireless Debugging in developer options and open it.
  • For the first time, click “Match device with Matching code”.
  • homeworkadb pair ipaddr:portThen enter the matching code for connection.

Caution:

  • Keep your computer and phone on the same network.
  • Platform Tools format must be larger than 30.0. Can be usedadb --versionCheck.

[

However, after I understand, I feel that the connection is not very stable. I wonder if it is the problem of AS or the mobile phone. The connection will also be disconnected after locking the screen together, not very well understood… Wait for the subsequent optimization.


This article is a bit too much. To sum up, Android 11 changes on permissions are more, but assume that you always abide by begged permission related best practices, so fundamentally do not need rated adaptation.

Finally, the single authorization, visibility of the permissions dialog, SYSTEM_ALERT_WINDOW permissions, and device APK are all changes that will work on Android 11, whether or not you’re an Android 11 adapter. As for other changes and APIS (camera, 5G, waterfall screen, keyboard, etc.), I haven’t encountered them yet, so I haven’t listed them. If you have any requirements, you can click the official document link at the end of the article to check.

At the time of writing this blog, ALL I found on my phone was that Bilibili is now available for Android 11. Most are stuck at 28, 29, and even 26 (the minimum fit for Android 8.0 in China).