I've asked a similar question to this before, however, I have done some more research and I am still struggling to figure out what my problem is. Essentially, what I am trying to do is create a form of receipt in a PDF
format after a customer has completed their purchase. This newly created PDF
needs to then be sent to a separate emailing client (such as Gmail) through an Intent
. Compared to my previous question I have now implemented a FileProvider
, however I keep getting two different errors. The first one is:
java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content...requires the provider be exported, or grantUriPermission()
This causes the file to not be attached to the email at all. And the second error I can sometimes get is, that it will place the actual URI path into the Recipients section of the email, which you can see below (also causing the file to not be attached)
I have tried quite a few different solutions upon doing my research, such using setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
or addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
, which can be seen here
I've also seen that some posts that said to use android:requestLegacyExternalStorage="true"
in the manifest, however, this will then limit my minimum APK level quite a lot.
I even tried what this post suggests, whereby you manually go through and give permissions to all the packages, which still didn't solve my problem.
I've also tried using the grantUriPermission()
method, which still didn't work either.
Below, you will see that I have placed some code:
Manifext.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.fabricanddecor">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:largeHeap="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LoginActivity"
android:configChanges="orientation|screenSize"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan">
</activity>
<provider
android:authorities="com.example.fabricanddecor"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
</manifest>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="."/>
</paths>
Method that creates the email and fires Intent (EDIT)
try {
String directory = Environment.getExternalStorageDirectory().getPath();
File file = new File(directory);
if (file.mkdirs()) {
String filePath = directory + "/sale.pdf";
File file2 = new File(filePath);
Uri contentUri = FileProvider.getUriForFile(getContext(), "com.example.fabricanddecor", file2);
Intent intent = new Intent(Intent.ACTION_SEND);
getContext().grantUriPermission("com.example.fabricanddecor", contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_EMAIL, recipient);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_STREAM, contentUri);
intent.setDataAndType(contentUri, "application/pdf");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, "Choose an Email Service"));
}
} catch (Exception e) {
e.printStackTrace();
}
Any help or suggestion will be highly appreciated, and thank you for your time. If any further code is required, I will be happy to oblige.