I am trying to create PDF with the nuget Syncfusion.Xamarin.Pdf version 19.3.0.47 and with Xamarin.Forms version 5.0.0.2196, I am using an emulator with Android 11.0 (API 30) and I have used the following documentation to develop an example: https://www.syncfusion.com/kb/9174/how-to-create-a-pdf-file-in-xamarin The problem arises when I try to create the PDF in Android 11 as it shows me the following error: /storage/emulated/0/Download/Syncfusion/Output.pdf:
open failed: EACCES (Permission denied)
In the AndroidManifest.xml I have added in the application tag the property: android:requestLegacyExternalStorage="true" so I have read this is necessary in new versions of Android.
I am aware of the new runtime permission model for Android SDK version 23 and above so I have added the provider_paths.XML file in the Android resources folder:
<?xml version="1.0" encoding="UTF-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
And I have updated the AndroidManifest.xml as indicated in your documentation:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.syncfusionpdf">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<application android:label="SyncfusionPdf.Android" android:theme="@style/MainTheme" android:requestLegacyExternalStorage="true">
<provider android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
The problem is that when I add the provider_paths.xml file the project does not compile showing the following error:
invalid file path 'C:\Users\sample\source\repos\SyncfusionPdf\SyncfusionPdf\SyncfusionPdf.Android\obj\Debug\110\res\provider_paths.xml'. SyncfusionPdf.Android
I'm stuck since I can't get this to work on Android 11, could you provide a functional repository for Android 11 generating PDF?
I published the repository where I am doing all these tests on GitHub in case you need it: https://github.com/nacompllo/SyncfusionPdf
<application android:label=" PDFXamarinSample.Android" android:requestLegacyExternalStorage="true"> |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
</uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
if (Android.OS.Environment.IsExternalStorageEmulated)
{
root = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
} |
Your example throws an exception, to replicate it do the following:
-Install the sample application and create a PDF.
-Install the application a second time but with a different package name, for example:
com.mycompany.pdfxamarinsample -> app installed for the first time
com.sample -> application installed for the second time
-You tried to create a PDF in the application that you installed the second time with a different package name and the following exception occurred:
-The crash occurs on the line:
FileOutputStream outs = new FileOutputStream(file);
Message:
"/storage/emulated/0/Download/Syncfusion/Output.pdf: open failed: EACCES (Permission denied)"
StackTrace:
at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <bd6bd528a8784b7caf03e9f25c9f0d7b>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.FinishCreateInstance (System.String constructorSignature, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0004f] in <bd6bd528a8784b7caf03e9f25c9f0d7b>:0
at Java.IO.FileOutputStream..ctor (Java.IO.File file) [0x00071] in /Users/builder/azdo/_work/1/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-30/mcw/Java.IO.FileOutputStream.cs:64
at SaveAndroid.SaveAndView (System.String fileName, System.String contentType, System.IO.MemoryStream stream) [0x000da] in D:\Descargas\PDFXamarinSample1888920970\PDFXamarinSample\PDFXamarinSample.Android\SaveAndroid.cs:43
--- End of managed Java.IO.FileNotFoundException stack trace ---
java.io.FileNotFoundException: /storage/emulated/0/Download/Syncfusion/Output.pdf: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:492)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at crc64ee486da937c010f4.ButtonRenderer.n_onClick(Native Method)
at crc64ee486da937c010f4.ButtonRenderer.onClick(ButtonRenderer.java:104)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7542)
at libcore.io.IoBridge.open(IoBridge.java:478)
... 15 more
if (Android.OS.Environment.IsExternalStorageEmulated)
{
root = Android.App.Application.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
}
else
root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); |