Search code examples
androidandroid-contentproviderandroid-securityexception

Android Content Provider Security Exception


I am trying to open a PDF or Text file from my app with other reader application like Google Drive PDF viewer etc. But it is showing the following error.

java.lang.SecurityException: Permission Denial: opening provider com.my.app.provider.GenericFileProvider from ProcessRecord{87fdcbb 31761:com.google.android.apps.docs/u0a37} (pid=31761, uid=10037) that is not exported from uid 10081

Manifest file:

<provider
        android:name="com.my.app.provider.GenericFileProvider"
        android:authorities="${applicationId}.my.package.name.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

provider_paths file:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

Code:

Intent intent = new Intent(Intent.ACTION_VIEW);
String mimeType = myMime.getMimeTypeFromExtension(ChatAdapterHelper.Document.getDocumentExtension(message.content));

String authority = AppContext.getAccess().getContext().getPackageName() + ".my.package.name.provider";

Uri fileUri = GenericFileProvider.getUriForFile(AppContext.getAccess().getContext(), authority, file);
Log.d("fileUri", "openDocument: fileUri " + fileUri);

intent.setDataAndType(fileUri, mimeType);
Intent chooser = Intent.createChooser(intent, context.getString(R.string.open_file_with));

chooser.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
chooser.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
chooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

AppContext.getAccess().getContext().startActivity(chooser);

SDK versions:

minSdkVersion 16
targetSdkVersion 27

I am trying to follow the procedure of using content provider explained in Android Developer website and other forum posts but can't get what is wrong here!


Solution

  • The FLAG_GRANT_*_URI_PERMISSION flags need to be set on the Intent passed into createChooser(); in this case, intent.

    Also, be aware that setFlags() will supersede any previous call to it. That is, the last call's flag(s) will wholly replace any previous call's. You can combine multiple flags in one call with |, or use the addFlags() method with them individually. For example:

    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    

    Alternatively:

    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    

    Also, make sure to use addFlags() for the FLAG_ACTIVITY_NEW_TASK on the chooser Intent, as the grant permission flags will have been added to that as well when it was constructed in the createChooser() method.

    chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);