kralvarado
kralvarado

Reputation: 530

ContentProvider throws Permission Denial when permission is present in manifest

The Idea:

I've got two Android applications, one has a service that will grab file assets to display (service_app). The other application has a ContentProvider and file assets (content_app). The content_app will bind to the service_app's service. At which point the the content_app makes a call into the service_app, which starts the service to pull the content from content_app using the defined ContentProvider. A side note, the service_app will bind to the defined service and extract the default content upon startup using the same idea above, and both applications are in different apk files.

I'm trying to create a suite of applications that I can add new applications that all use the same service and provide application specific content files.

The problem:

Currently I'm getting java.lang.SecurityException: Permission Denial: reading com.test.assets.provider.ContentProvider uri content://com.test.contentapp.ContentProviderAuth/AssetList from pid=17311, uid=10286 requires com.test.assets.READ_ASSETS, or grantUriPermission()

However, I've declared within my manifest <uses-permission android:name="com.test.assets.READ_ASSETS" />

The setup

I'm sure I've declared and defined the service and providers correctly service_app AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<!-- declaring the use of permission from content_app -->
<uses-permission android:name="com.test.assets.READ_ASSETS" />

<application android:label="Service App"
    android:icon="drawable/app_logo">
    <activity android:name=".ServiceApp"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:name="com.test.serviceapp.service.ContentService"
        android:enabled="true"
        android:exported="true"
        android:process=":service">
            <intent-filter>
                <action android:name="com.test.serviceapp.ContentServiceAction" />
            </intent-filter>
    </service>

    <!-- main application is also is a provider for the service -->
    <provider android:name="com.test.assets.provider.ContentProvider"
        android:authorities="com.test.serviceapp.ContentProviderAuth"
        android:readPermission="com.test.assets.READ_ASSETS"
        android:enabled="true"
        android:exported="true">
    </provider>
</application>
</manifest>

content_app AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/Content App"
    android:supportsRtl="true">
    <activity
        android:name=".ContentApp"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <meta-data
            android:name="android.app.lib_name"
            android:value="" />
    </activity>
    
    <provider android:name="com.test.assets.provider.ContentProvider"
        android:authorities="com.test.contentapp.ContentProviderAuth"
        android:readPermission="com.test.assets.READ_ASSETS"
        android:enabled="true"
        android:exported="true">
    </provider>
</application>
</manifest>

Within the service, I've got a manager class that creates a ContentProviderClient

public AssetFileDescriptor getAssetFileDescriptor( String package ) {
    AssetFileDescriptor fileDescriptor = null;
    String provider = package + ".ContentProviderAuth";
    Uri fileUri = Uri.parse( "content://" + provider + "/AssetList" );
    try {
        ContentProviderClient client = mContext.getContentResolver().acquireContentProviderClient( provider );
        if ( client != null ) {
            // the following line throws the security exception permission denial
            // even when the service_app has the correct permission in the AndroidManifest.xml
            fileDescriptor = client.openAssetFile( fileUri, "r" );
            client.close();
        }
    }
    catch (FileNotFoundException e) {
        Log.e( "AssetManager", "getAssetFileDescriptor" + e.toString();
    }
    return fileDescriptor;
}

So this exception has got me stumped. I'm not sure why Android is complaining about a permission that has been declared to be used within the requesting service_app.

Thank you in advance for any insight to this issue.

Upvotes: 0

Views: 158

Answers (0)

Related Questions