19

UPDATE: I have to completely change my question since I found more details related to my problem.

The problem: My app that resolves Content Provider doesn't work in Emulator with API 30. The error:

java.lang.SecurityException: Failed to find provider com.a52.datafeeder01.MyProvider for user 0; expected to find a valid ContentProvider for this authority

If I use APIs 26,27,28 and 29 then there is no problem.

AndroidManifest.xml in app with ContentProvider:

<manifest>
    <permission
        android:name="MyProvider._READ_PERMISSION"
        android:protectionLevel="normal" />
    <application>
        <activity>
        ...
        </activity>
        <provider android:name=".MyProvider"
            android:authorities="com.a52.datafeeder01.MyProvider"
            android:enabled="true"
            android:exported="true"
            android:readPermission="MyProvider._READ_PERMISSION"/>
    </application>
</manifest>

AndroidManifest.xml in client app :

<manifest>
...
    <uses-permission android:name="MyProvider._READ_PERMISSION" />
...
</manifest>

If I try to resolve Content Provider in the same app, it works.

If I use packageManager.getInstalledPackages(PackageManager.GET_PROVIDERS) in my client code to get list of existing providers then for APIs [26,29] I can see my provider in the list. If I run this code in API 30 my provider is not in the list.

It seems that something was changed in API 30 related to registration of ContentProvider. However I can't find what.

StahlRat
  • 1,199
  • 13
  • 25
  • Please show complete provider definition from manifest. – blackapps Aug 24 '20 at 15:43
  • @blackapps, I've updated provider definition with my most recent changes – StahlRat Aug 24 '20 at 16:34
  • Isnt there a grand uri permission missing? – blackapps Aug 24 '20 at 16:40
  • @blackapps, I've tried with uri permission, doesn't make any difference. Still works fine on device and doesn't on simulator. – StahlRat Aug 24 '20 at 16:43
  • You did not show the statement/code of app-2 that causes that exception. – blackapps Oct 26 '20 at 09:30
  • How does app-2 know about the content provider of app-1? – blackapps Oct 26 '20 at 09:31
  • You are not reacting. A pitty. I can confirm the problem as it happened to me a few days ago too. If you meanwhile found a solution or have other info then please tell us. – blackapps Oct 27 '20 at 09:02
  • I am sorry for late respond. For the quick hack , I try to downgrade to API Level 29. – Arif Hidayat Oct 29 '20 at 09:00
  • @blackapps, see my answer below, the question about app2 find content of app1 is not related to problem, it was never a problem in my application. The problem is Package Visibility in API 30, just adding one line ```queries``` made my ContentProvider work in all APIs again. – StahlRat Nov 06 '20 at 15:52

4 Answers4

39

The reason my custom ContentProvider doesn't work on Emulator with API 30 is Package visibility in Android 11+

To Fix my issue I've added following <queries> element into client's AndroidManifest.xml:

<manifest>
...
    <queries>
        <package android:name="com.a52.datafeeder01" />
    </queries>
...
</manifest>

where com.a52.datafeeder01 is the package name where custom ContentProvider is defined.

StahlRat
  • 1,199
  • 13
  • 25
  • 1
    +1 wasted a lot of time on wondering why my content provider works on real device by not on emulator. Just figured out, emulator is based on API 30 and this package visibility was causing problem. This is the correct solution but I have to replace package with provider tag. – mallaudin Jul 04 '21 at 09:51
12

In case of my problem, simply add:

<manifest>
...
    <queries>
        <provider android:authorities="com.example.appcontainprovider" />
    </queries>
...
</manifest>

where authorities value is provider authorities.

Reference: https://developer.android.com/training/basics/intents/package-visibility#provider-authority

Dharman
  • 30,962
  • 25
  • 85
  • 135
Isato
  • 121
  • 1
  • 3
  • This solution didn't work for me, the only solution that worked for me is giving the package name inside package tag like this Can somebody please tell what is the difference in both of these approaches? – Ahmad Ayyaz May 26 '22 at 15:01
7

Please add the following permission in manifest

    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
                     tools:ignore="QueryAllPackagesPermission"/>

This resolved my problem in android 11

Farruh Habibullaev
  • 2,342
  • 1
  • 26
  • 33
Thriveni
  • 742
  • 9
  • 11
  • Thanks a Ton.. this working great – Shyam Sunder Feb 22 '22 at 22:11
  • Google Play restricts the use of high-risk or sensitive permissions, including the QUERY_ALL_PACKAGES permission, which gives visibility into the inventory of installed apps on a given device. For more details, you can read this article: https://support.google.com/googleplay/android-developer/answer/10158779?hl=en – Ahmad Ayyaz May 26 '22 at 15:21
0

From Android 11 , there are changes in package visibility. So need to add queries as below

https://developer.android.com/training/package-visibility

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="yourPackage">
    <queries>
         <provider android:authorities="providerAuthority" />
    </queries>
    //Add your content provider's permission
    <uses-permission android:name="com.example.permission" />
    <application ...../>
 </manifest>
Tarun Anchala
  • 2,232
  • 16
  • 15