- Package visibility in Android 11
- Package visibility for url_launcher on Android 11 (API 30)
- Problem
- Solution
- Package visibility in android 11
- Query & Interact with Apps in Android 11 with Package Visibility
- Working with Package Visibility
- Querying and interacting with apps:
- Activity flags:
- FLAG_ACTIVITY_REQUIRE_NON_BROWSER
- Customizing a share sheet
- Debugging Package Visibility
- Next steps:
Package visibility in Android 11
On Android 10 and earlier, apps could query the full list of installed apps on the system using methods like queryIntentActivities() . In most cases, this is far broader access than is necessary for an app to implement its functionality. With our ongoing focus on privacy, we’re introducing changes on how apps can query and interact with other installed apps on the same device on Android 11. In particular, we’re bringing better scoped access to the list of apps installed on a given device.
To provide better accountability for access to installed apps on a device, apps targeting Android 11 (API level 30) will see a filtered list of installed apps by default. In order to access a broader list of installed apps, an app can specify information about apps they need to query and interact with directly. This can be done by adding a element in the Android manifest.
For most common scenarios, including any implicit intents started with startActivity() , you won’t have to change anything! For other scenarios, like opening a specific third party application directly from your UI, developers will have to explicitly list the application package names or intent filter signatures like this:
If you use Custom Tabs to open URLs, you might be calling resolveActivity() and queryIntentActivities() in order to launch a non-browser app if one is available for the URL. In Android 11 there’s a better way to do this, which avoids the need to query other apps: the FLAG_ACTIVITY_REQUIRE_NON_BROWSER intent flag. When you call startActivity() with this flag, an ActivityNotFoundException will be thrown if a browser would have been launched. When this happens, you can open the URL in a Custom Tab instead.
In rare cases, your app might need to query or interact with all installed apps on a device, independent of the components they contain. To allow your app to see all other installed apps, Android 11 introduces the QUERY_ALL_PACKAGES permission. In an upcoming Google Play policy update, look for guidelines for apps that need the QUERY_ALL_PACKAGES permission.
When targeting API level 30 and adding a element to your app, use the latest available release of the Android Gradle plugin. Soon we’ll be releasing updates to older Android Gradle plugin versions to add support for this element. You can find more information and use cases about Package Visibility in the developer documentation.
Источник
Package visibility for url_launcher on Android 11 (API 30)
TL;DR: You can skip if you don’t use the `url_launcher` package or your app doesn’t target Android 11 and above.
Problem
Android 11 introduced a tighter security when interacting with other apps — the package visibility concept.
If you have used the url_launcher package recently, you may have realized that canLaunch always returns false on Android 11 (API 30) and launchUrl will fail.
Solution
This can be fixed by configuring your application to make other applications that have the android.intent.action.VIEW intent filter using element in the AndroidManifest.xml.
For the element to work, it is recommended you upgrade your Android Gradle Plugin (AGP) to version 4.1.
In your project level gradle file, android/build.gradle, do as shown below:
There are other dot versions for earlier versions of the Android Gradle Plugins. Find out more from here.
After upgrading the gradle plugin and building the app, add this element block to your AndroidManifest.xml :
After doing this, rebuild the app and canLaunch should return true and launchUrl should also open the url on Android 11 (API 30).
That was pretty quick. Easy peasy ain’t it? 😁
The AGP v4.1.0+ requires v6.5+ of gradle and due to some issues, it may cause your release build to get stuck on the splash screen. Using AGP v3.5.4 fixed this issue for me. Like so:
Источник
Package visibility in android 11
Experiment of Package Visibility in Android 11
Purpose of this Experiment
Android 11 changes how apps can query and interact with other apps that the user has installed on a device.
I built several apps, and they share data between each other by using Content Provider in each app.
Recently, one of my apps moved to targetSdkVersion 30 , and I found that package visibility change in Android 11 makes apps are invisible to each other in some situation.
This experiment is to find out the simplest solution making my apps visible to each other , regardless the installation order, apps development targetSdkVersion, running Android OS version, or app signatures.
- app1 — targetSdkVersion 29
- app2 — targetSdkVersion 29
- app3 — targetSdkVersion 30
- running on device with Android 11 emulator
Regardless the installation order, app1 and app2 are invisible to app3 , until app1/app2 access Content Provider in app3.
Simplest solution is making sure every app defines which apps they would like to visit. So in AndroidManifest.xml , add package name (aka applicationId) under :
Tested in Android 10 emulator, no behaviour change in below setup regardless the installation order:
- app1 — targetSdkVersion 29
- app2 — targetSdkVersion 29
- app3 — targetSdkVersion 30
- running on device with Android 10 emulator
Result: apps are visible to each other
Apps visible automatically
Android automatically makes some apps visible to your app so that your app can interact with them without needing to declare the element. For example, any app that accesses a Content Provider in your app.
This explains app1 is invisible to app3 until app1 access the Content Provider in app3. If we don’t want to rely on user open and use app1, I would suggestion declare queries.
If your app targets Android 10 (API level 29) or lower, all apps are visible to your app automatically.
Источник
Query & Interact with Apps in Android 11 with Package Visibility
October 15th, 2020
Android 11 introduced several exciting updates for developers to integrate into their app experience including new device and media controls, enhanced support for foldables, and a lot more. In addition to new features there are also several privacy enhancements that developers need to integrate into their application when upgraded and re-targeting to Android 11. One of those enhancements is the introduction of package visibility that alters the ability to query installed applications and packages on a user’s device.
When you want to open a browser or send an email then your application will have to launch and interact with another application on the device through an Intent . Before calling StartActivity it is best practice to QueryIntentActivities or ResolveActivity to ensure there is an application that can handle the request. If you are using Xamarin.Essentials, then you may not have seen these APIs because the library handles all of the logic for you automatically for Browser(External), Email, and SMS.
Before Android 11 every app could easily query all installed applications and see if a specific Intent would open when StartActivity is called. That has all changed with Android 11 with the introduction of package visibility. You will now need to declare what intents and data schemes you want your app to be able to query when your app is targeting Android 11.
Once you retarget to Android 11 and run your application on a device running Android 11 you will receive zero results if you use QueryIntentActivities . If you are using Xamarin.Essentials you will receive a FeatureNotSupportedException when you try to call one of the APIs that needs to query activities. Let’s say you are using the Email feature of Xamarin.Essentials. Your code may look like this:
If your app targeted Android 10 and earlier, it would just work. With package visibility in Android 11 when you try to send an Email, Xamarin.Essentials will try to query for pacakges that support email and zero results will be return. This will result in a FeatureNotSupportedException to be thrown, which is not ideal. To enable your application to get visbility into the packages you will need to add a list of queries into your AndroidManifest.xml .
If you need query multiple intents or use multiple APIs you will need to add them all into the list.
And there you have it, with just a small amount of configuration you are app will continue to work flawless when you target Android 11.
Источник
Working with Package Visibility
In Android, we are making changes to enhance user privacy and platform security to provide our users with a safer experience. Apps targeting Android 11 (API level 30) or higher will only see a filtered list of apps that are installed on a device. In order to access apps beyond that filtered list, an app will need to declare the apps they need to interact with directly using a element in the Android manifest. This blog post will go through best practices of how to adapt to this feature.
Querying and interacting with apps:
There are different ways to query and interact with apps:
- If you know the specific set of apps that you want to query or interact with, include their package names in a set of
elements inside the element.
- If your app needs to query or interact with a set of apps that serve a particular purpose, but you might not know the specific package names to include, you can list intent filter signatures in your element. Your app can then discover apps that have matching elements.
- If you need to query a content provider but don’t know the specific package names, you can declare that provider authority in a
We encourage data minimization by querying only for the packages you need to interact with. QUERY_ALL_PACKAGES or equivalently broad elements should only be used by apps that need this level of information. Our new Package Visibility policy introduces an approval process for the new QUERY_ALL_PACKAGES permission which controls access to the complete inventory of installed apps on a device.
Activity flags:
Most common use cases don’t require your app to have package visibility at all. For many scenarios, you can use startActivity() and catch an exception if there is no app that can open this intent.
While you can start any activity without visibility of the target, you can’t query for the availability of that activity before starting it or learn which specific app will be launched because it is an implicit intent. Instead, you will be notified when you start if it doesn’t resolve. If you want to be more selective about what opens, you can use flags.
A common example that uses flags is Custom Tabs, which allow a developer to customize how a browser looks and feels and have more control over the web content experience. Links will correctly open in non-browser apps if available, but flags help in advanced cases when developers want to be selective about handling the content in a native application before using custom tabs. In short, this flag helps a developer determine if there’s a native app to navigate to and from there they can handle it how they want.
FLAG_ACTIVITY_REQUIRE_NON_BROWSER
This flag only launches the intent if it resolves to a result that is not a browser. If no such result exists, an ActivityNotFoundException will be thrown and your app can then open the URL in a custom tab.
If an intent includes this flag, a call to startActivity() causes an ActivityNotFoundException to be thrown when the call would have launched a browser app directly or the call would have shown a disambiguation dialog to the user, where the only options are browser apps. To read more about flags, see Configuring package visibility based on use cases.
Customizing a share sheet
We recommend using the system share sheet instead of a custom one. You can customize the system share sheet without needing app visibility. Refer to this documentation for more information.
Debugging Package Visibility
You can easily check your manifest to see all queries included. In order to do this, go to your manifest file and choose Merged Manifest.
You can also enable log messages for package filtering to see how default visibility affects your app:
Next steps:
For more information on Package Visibility, check out these resources:
Источник