resolveActivity return null but startActivity works if not checking

The resolveActivity() method is very important and API dependent. If we are targeting API 29 (Android 10) or lower, then we can view what other apps exist on the device. Starting with API 30 (Android 11) and newer, the principle of least privilege applies and we need to tell the system what other packages to make visible to our app.

Here is the documentation page describing Package Visibility beginning in Android 11.

https://developer.android.com/about/versions/11/privacy/package-visibility

We must request permission to access anything outside of our app. Any interaction between our app and the OS goes in to the Manifest to register. In the AndroidManifest.xml, we need to tell the OS that we plan to query the Contacts package in order to pick a contact. The Contacts app should be part of the list of apps that automatically visible to our app.

https://developer.android.com/training/basics/intents/package-visibility#automatic

But as soon as we add the data field to the intent, we now need to make an explicit query request. I was able to gain proper access using the following query in the manifest:

<!-- AndroidManifest.xml -->
<manifest ...>
    <queries>
        <package android:name=”com.android.contacts”/>
    </queries>
    <application ...>
        ...
    </application>
</manifest>

I would have thought from reading the documentation that the query could have been structured as an intent, such as

<queries>
    <intent>
        <action android:name="com.androind.action.PICK"/>
        <data android:scheme="content" android:host="com.android.contacts"/>
    </intent>
</queries>

But no combination of attributes gave proper access. Only by using the package query did the intent with the data URI resolve. I feel there should be an alternate way, but I haven’t found it yet.

2 Likes