We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Error when saving document with dependency service

Hi!

I'm trying to work on a document generator and finding some error while saving some simple files. I've done everything according to the Xamarin DocIO tutorial from Syncfusion (https://help.syncfusion.com/file-formats/docio/xamarin?cs-save-lang=1&cs-lang=csharp), but those errors keep pestering me. I can't see what could be wrong. Here's my command to perform the generation:

async void GerarArquivoWord(ArquivoModel localarquivo)
        {
            WordDocument localdocumento = new WordDocument();

            IWSection localSection = localdocumento.AddSection();

            IWParagraph localparagraph = localSection.AddParagraph();

            //CachedImage localimagem = new CachedImage();
            //localimagem.Source = "ESFJPDocumento";
            
            //var localbyte = await localimagem.GetImageAsJpgAsync();
            //IWPicture localpicture = localparagraph.AppendPicture(localbyte);

            for (int i = 0; i < ListaTopicosElemento.Count; i++)
            {
                IWTextRange localtexto = localparagraph.AppendText(ListaTopicosElemento[i].Texto + " ; ");

                localtexto.CharacterFormat.FontSize = 14;

                localtexto.CharacterFormat.TextColor = Syncfusion.Drawing.Color.Black;
            }

            MemoryStream arquivostream = new MemoryStream();

            localdocumento.Save(arquivostream, Syncfusion.DocIO.FormatType.Docx);

            localdocumento.Close();

            await DependencyService.Get<ISave>().Save("TesteESFJPDocumento.docx", "application/msword", arquivostream);  //************************

            Stream docStream = typeof(App).GetTypeInfo().Assembly.GetManifestResourceStream("TesteESFJPDocumento.docx");

            localdocumento.Open(docStream, Syncfusion.DocIO.FormatType.Docx);
        }

The compiler stops at:

await DependencyService.Get<ISave>().Save("TesteESFJPDocumento.docx", "application/msword", arquivostream);  //************************

with the unhandled exception: 

System.NullReferenceException: Object reference not set to an instance of an object.

The DependencyService are done how the tutorial tells to, but I can provide the code as well if you wish. Any help is appreaciated! Also, here's my stack trace:

07-23 11:07:02.019 D/Mono    (18998): DllImport attempting to load: '/system/lib/liblog.so'.
07-23 11:07:02.020 D/Mono    (18998): DllImport loaded library '/system/lib/liblog.so'.
07-23 11:07:02.020 D/Mono    (18998): DllImport searching in: '/system/lib/liblog.so' ('/system/lib/liblog.so').
07-23 11:07:02.021 D/Mono    (18998): Searching for '__android_log_print'.
07-23 11:07:02.021 D/Mono    (18998): Probing '__android_log_print'.
07-23 11:07:02.021 D/Mono    (18998): Found as '__android_log_print'.
07-23 11:07:02.025 I/MonoDroid(18998): UNHANDLED EXCEPTION:
07-23 11:07:02.089 I/MonoDroid(18998): System.NullReferenceException: Object reference not set to an instance of an object.
07-23 11:07:02.090 I/MonoDroid(18998):   at ESFAtas.HomeVM+<GerarArquivoWord>d__76.MoveNext () [0x0006b] in C:\Users\raels\Dropbox\Engenharia\Projetos\ESF\Aplicativos\ESFAtas\ESFAtas\ViewModel\HomeVM.cs:276 
07-23 11:07:02.090 I/MonoDroid(18998): --- End of stack trace from previous location where exception was thrown ---
07-23 11:07:02.090 I/MonoDroid(18998):   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 
07-23 11:07:02.090 I/MonoDroid(18998):   at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 
07-23 11:07:02.090 I/MonoDroid(18998):   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <25661073a35344a89f215a4cf81af37c>:0 
07-23 11:07:02.090 I/MonoDroid(18998):   at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <25661073a35344a89f215a4cf81af37c>:0 
07-23 11:07:02.090 I/MonoDroid(18998):   at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <25661073a35344a89f215a4cf81af37c>:0 
07-23 11:07:02.090 I/MonoDroid(18998):   at (wrapper dynamic-method) System.Object.80f1c986-c841-4afc-814f-0714131bcfe9(intptr,intptr)
07-23 11:07:02.109 W/art     (18998): JNI RegisterNativeMethods: attempt to register 0 native methods for android.runtime.JavaProxyThrowable
07-23 11:07:02.115 D/Mono    (18998): DllImport searching in: '__Internal' ('(null)').
07-23 11:07:02.115 D/Mono    (18998): Searching for 'java_interop_jnienv_throw'.
07-23 11:07:02.115 D/Mono    (18998): Probing 'java_interop_jnienv_throw'.
07-23 11:07:02.115 D/Mono    (18998): Found as 'java_interop_jnienv_throw'.
An unhandled exception occured.

Thread finished: <Thread Pool> #5
Thread finished: <Thread Pool> #2
Thread finished: <Thread Pool> #3
Thread finished: <Thread Pool> #4

18 Replies

DB Dilli Babu Nandha Gopal Syncfusion Team July 24, 2018 12:53 PM UTC

Hi Raelson, 

Thank you for contacting Syncfusion support. 

We have tried to reproduce the reported exception from our side. We are unable to reproduce it and shared a sample which saves the Word document stream using DependencyService. The sample can be downloaded from the following link  

Kindly provide us your issue reproducing sample or complete code example along with DepedencyService classes with respective to different Xamarin.Forms platforms which will be helpful to provide you the prompt solution at the earliest. 

Regards, 
Dilli babu. 



RC Raelson Craftz July 30, 2018 12:18 PM UTC

Hi!

Sorry for the delay. The sample you gave me has helped me, it was only an issue with the line

[assembly: Dependency(typeof(SaveAndroid))]

before the SaveAndroid namespace that I've forgotten. However, I'm still facing issues. Here's my current Command to generate the document:

async void GerarArquivoWord(ArquivoModel localarquivo)
        {
            WordDocument localdocumento = new WordDocument();

            IWSection localSection = localdocumento.AddSection();
            
            IWParagraph localparagraph = localSection.AddParagraph();

            var auxiliartexto = string.Empty;
            for (int i = 0; i < ListaTopicosElemento.Count; i++)
            {
                if (i == 0) auxiliartexto = ListaTopicosElemento[i].Texto;
                else auxiliartexto = auxiliartexto + ListaTopicosElemento[i].Texto + " ; ";
            }
            IWTextRange localtexto = localparagraph.AppendText(auxiliartexto);
            localtexto.CharacterFormat.FontSize = 14;
            localtexto.CharacterFormat.TextColor = Syncfusion.Drawing.Color.Black;
            
            MemoryStream arquivostream = new MemoryStream();
            arquivostream.Position = 0;
            
            localdocumento.Save(arquivostream, Syncfusion.DocIO.FormatType.Docx);

            localdocumento.Close();

            await DependencyService.Get<ISave>().Save("TesteESFJPDocumento.docx", "application/msword", arquivostream);
        }

Here's my ISave interface:

public interface ISave
    {

        Task Save(string filename, string contentType, MemoryStream stream);

    }

Here's my SaveAndroid class, which's my dependency target:

[assembly: Dependency(typeof(SaveAndroid))]
namespace ESFAtas.Droid
{
    public class SaveAndroid : ISave
    {

        public async Task Save(string fileName, String contentType, MemoryStream stream)
        {
            string exception = string.Empty;
            string root = null;

            if (Android.OS.Environment.IsExternalStorageEmulated)
            {
                root = Android.OS.Environment.ExternalStorageDirectory.ToString();
                //This address gives an error that the file cannot be found
            }
            else
                root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                //This address works, but the file remains eternally loading the content, as shown in the attached picture

            Java.IO.File myDir = new Java.IO.File(root + "/ESFAtas");
            myDir.Mkdir();
            Java.IO.File file = new Java.IO.File(myDir, fileName);

            if (file.Exists()) file.Delete();

            try
            {
                FileOutputStream outs = new FileOutputStream(file);
                outs.Write(stream.ToArray());
                outs.Flush();
                outs.Close();
            }

            catch (Exception e)
            {
                exception = e.ToString();
            }
            finally
            {
                stream.Dispose();
            }

            if (file.Exists())
            {
                Android.Net.Uri path = Android.Net.Uri.FromFile(file);
                string extension = Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(Android.Net.Uri.FromFile(file).ToString());
                string mimeType = Android.Webkit.MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
                Intent intent = new Intent(Intent.ActionView);
                intent.SetDataAndType(path, mimeType);
                
                Forms.Context.StartActivity(Intent.CreateChooser(intent, "Choose App"));
            }

        }

    }

}

My device keeps getting this line:

Android.OS.Environment.IsExternalStorageEmulated

as true, and therefore if I let the code as it is, the root will be that first option. However, the file cannot be found in this address, for some reason, and I cannot figure out what's the cause of that. If I remove that line and set the root directly to Environment.SpecialFolder.MyDocuments, the code actually works. However, the document opens but it never actually loads the content, as shown in the attached file. I can't save the file as well.

Any help is appreciated!

Attachment: DocIO_Report_1_ceaf8a22.rar


DB Dilli Babu Nandha Gopal Syncfusion Team August 1, 2018 10:52 AM UTC

Hi Raelson, 

Thank you for your update. 

We suspect that the reported saving issue in Xamarin.Forms Android project might be due to disabled write permission for the application. Please refer the following code example which illustrates how to enable write permission in the AndroidManifest.xml 
<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto"> 
            <uses-sdk android:minSdkVersion="16" /> 
                        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
            <application android:label="$safeprojectname$" android:icon="@drawable/icon"></application> 
</manifest> 

To know more about this, please refer the following documentation link. 

Kindly share us your issue reproducing sample if the issue isn’t resolved after above suggestions which will be helpful for us to provide you the prompt solution at the earliest. Please let us know if you have any questions. 

Regards, 
Dilli babu. 



RC Raelson Craftz August 1, 2018 05:28 PM UTC

Hi!


Thank you so much for the support. I've uploaded a sample on github.

https://github.com/RaelsonCraftz/DocIOSample

The exact same issue happens on my device, even with the permission granted.


RC Raelson Craftz August 7, 2018 07:46 PM UTC

Hi!

Is there any update on the matter? The always loading problem still happens. The sample I've uploaded also has this issue even when I've added the writing permission. Any help is appreciated!


DB Dilli Babu Nandha Gopal Syncfusion Team August 8, 2018 01:21 PM UTC

Hi Raelson, 
 
Sorry for the delay. 

We have modified the given sample application to save the Word document as per your requirement. Please find the modified sample from the below link.
 
 
Please let us know if the sample fulfills your requirement. 
 
Regards, 
Dilli babu.




RC Raelson Craftz August 9, 2018 02:50 PM UTC

Thank you SO MUCH!

I've been struggling with this for quite some time. According to my tests, the issue was resolved when this tag marked in yellow...

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.DocIOSample" android:installLocation="auto">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="27"/>
<application android:label="DocIOSample.Android"></application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>


...was removed from the AndroidManifest.xml. The reason for that still eludes me, though. Anyways, thanks for the support!


DB Dilli Babu Nandha Gopal Syncfusion Team August 10, 2018 05:13 AM UTC

Hi Raelson, 

We are glad to know that the reported issue has been resolved at your end. Please let us know if you need any further assistance on this. 

Regards, 
Dilli babu. 



LE LEO August 10, 2018 08:31 PM UTC

Hello,

I changed this project to generate a simple PDF, but I'm having a exception.

I used the code at:
https://help.syncfusion.com/file-formats/pdf/getting-started

I changed the method "async void GerarArquivoWord()" to create a simple PDF, but I got an exception at line:

PdfGraphics graphics = page.Graphics;

-------------------------------------------------------------
{System.TypeLoadException: Invalid type Syncfusion.Pdf.Graphics.PdfGraphics for instance field Syncfusion.Pdf.PdfPageLayer:m_graphics
  at Syncfusion.Pdf.PdfPageLayerCollection..ctor (Syncfusion.Pdf.PdfPageBase page) [0x00036] in <95a855e10a614850848c9df706c7562a>:0
  at Syncfusion.Pdf.PdfPageBase.get_Layers () [0x00008] in <95a855e10a614850848c9df706c7562a>:0
  at Syncfusion.Pdf.PdfPageBase.get_DefaultLayer () [0x00000] in <95a855e10a614850848c9df706c7562a>:0
  at Syncfusion.Pdf.PdfPageBase.get_Graphics () [0x00000] in <95a855e10a614850848c9df706c7562a>:0
  at DocIOSample.SampleViewModel+<GerarArquivoWord>d__5.MoveNext () [0x0003c] in C:\lixo\DocIOSample-master_modified-618703944\DocIOSample-master\DocIOSample\DocIOSample\SampleViewModel.cs:45 }
-------------------------------------------------------------

I need to generate a simple PDF in Xamarin.Forms, can you help me ?



DB Dilli Babu Nandha Gopal Syncfusion Team August 13, 2018 11:41 AM UTC

Hi Leo, 

Thank you for contacting Syncfusion support. 

We have prepared a sample for creating a PDF document and manipulating it in Xamarin Forms platform. The sample can be downloaded from the following link. 

Kindly refer the following UG documentation link, to know more about creating and saving a PDF document in Xamarin. 

Please let us know if your requirement is fulfilled or not.                   

Regards, 
Dilli babu. 



RC Raelson Craftz September 16, 2018 11:34 PM UTC

Hi!

Unfortunately I'll have to bother you guys again. The issue is resolved by removing the 'android:targetSdkVersion="27"' from the AndroidManifest.xml, but it happens that I'm not being able to publish the app on the Play Store because Google demands the app to target a 26 level API at least. And when I try to target to level 26 or 27 API the Word file won't be generated. If the Word is already generated, it works; but if the file doesn't exists yet, then it won't work.

Any help is appreciated!


DB Dilli Babu Nandha Gopal Syncfusion Team September 17, 2018 01:16 PM UTC

Hi Raelson, 
 
Thank you for your patience.

On analyzing further, the reported issue is related to Xamarin Android SDK version. So, we have raised the query in the Xamarin forum. Please find the forum from below:
https://forums.xamarin.com/discussion/135079/exception-throws-when-saving-file-in-android-device-in-externalstoragedirectory

We request to follow the above forum to get resolve the reported issue from Xamarin CORE team.

Regards,
 
Dilli babu.  



RC Raelson Craftz December 26, 2018 07:15 PM UTC

Hi!

I've been returning to this issue, trying to figure a way out. I don't know how to fix it and this is the only problem that stops me from publishing my app.

I tried a different way of referencing the document, by using File Provider class instead. Another error appears to me, as follows:

Java.Lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference

The code I'm using is as follows:

The AndroidManifest.xml contains:


     android:name="android.support.v4.content.FileProvider" 
            android:authorities="com.ESFJP.ESFAtas.fileprovider" 
            android:grantUriPermissions="true"
            android:exported="false">
         android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/>
    

The provider_paths.xml, which lies in the folder Resources/xml, is:

 xmlns:android="http://schemas.android.com/apk/res/android">
   name="external_files" path="/Atas"/>
   name="files" path="/Atas"/>

The async method to save the file and open:

public async Task Save(string fileName, string contentType, MemoryStream stream)
{

    string exception = string.Empty;
    string root = null;
    if (Android.OS.Environment.IsExternalStorageEmulated)
    {
        root = Android.OS.Environment.ExternalStorageDirectory.ToString();
    }
    else
        root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

    Java.IO.File myDir = new Java.IO.File(root + "/Atas");
    myDir.Mkdir();
    Java.IO.File file = new Java.IO.File(myDir, fileName);

    if (file.Exists()) file.Delete();


    try
    {
        //The permission failure happens in this line when the target version is set to API Level 27 Nougat
        FileOutputStream outs = new FileOutputStream(file);
        stream.Position = 0;
        outs.Write(stream.ToArray());
        outs.Flush();
        outs.Close();
    }

    catch (Exception e)
    {
        //The permission failure can be seen here if the target version is set to API level 27 Nougat
        exception = e.ToString();
    }
    finally
    {
        stream.Dispose();
    }

    if (file.Exists())
    {
        string auth = "com.ESFJP.ESFAtas.fileprovider";
        string extension = Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(Uri.FromFile(file).ToString());
        string mimeType = Android.Webkit.MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
        if (mimeType == null)
            mimeType = "*/*";

        //The Java.Lang.NullPointerException is thrown from this line \/\/\/
        Uri uri = FileProvider.GetUriForFile(Forms.Context, auth, file);

        Intent intent = new Intent(Intent.ActionView);
        intent.SetDataAndType(uri, mimeType);
        intent.AddFlags(ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission);
        intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.NoHistory);

        var resInfoList = Forms.Context.PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
        foreach (var resolveInfo in resInfoList)
        {
            var packageName = resolveInfo.ActivityInfo.PackageName;
            Forms.Context.GrantUriPermission(packageName, uri, ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantPrefixUriPermission | ActivityFlags.GrantReadUriPermission);
        }

        Forms.Context.StartActivity(intent);
    }

}

If you set the Targed Android version to Use Compile using SDK version the app manages to at least create the file, but it won't open, giving the Java.Lang.NullPointerException mentioned above. IF you set it to Android 8.1 (API Level 27 - Oreo), it won't manage to create the file. It says that the permission has not been granted at this line exception = e.ToString();. I've marked the line where that happens, it's on the public async Task Save(string fileName, string contentType, MemoryStream stream).

So, is there any chance we might solve that? I've seen some libraries that follows this kind of solution to create and open files, like this one:

https://github.com/jamesmontemagno/MediaPlugin

I've uploaded a sample on my github to reproduce this issue, which's as follows:

https://github.com/RaelsonCraftz/XamarinFileProviderSample

This is the only thing that restricts my app to going live, since I cannot publish to play store applications lesser than API level 27. Any help on this issue is appreciated!



DB Dilli Babu Nandha Gopal Syncfusion Team January 11, 2019 12:28 PM UTC

Hi Raelson,  
 
We have analyzed the reported problem in your sample application and modified the sample to meet your requirement. Please find the modified sample from the below link:
http://www.syncfusion.com/downloads/support/forum/138871/ze/Modified_sample565957439-1918022431
 

Please find the modification that we have done in your sample to resolve the reported problem.
  
 
Screenshot of modified file   
Details   
AndroidManifest.xml   
   
   
   
   
In the given sample, we have found that you showed two application tag (AdroidManifest.xml). We suspect that the issue might be due that application tags, we have modified the codes and also done the configuration changes to provide access to android file provider in AndroidManifest.xml file.

  
 
SaveAndroid.cs
  
 
   
We have modified the SaveAndroid.cs file to save and open the file from the device.    
provider_paths.xml   
   
    
Also, we  have changed the file provider options in provider_paths.xml to resolve the issue in application   
MainActivity.cs    
   
   
   
To resolve the permission exception when deploying application in Android 8.1 (API Level 27 - Oreo) target, it is need to grant permission for the application to access storage. We have done the changes in MainActivity.cs to grant permission when opening the application.   
 
Please let us know if you have any questions. 
 
Regards,  
Dilli babu. 




RC Raelson Craftz January 17, 2019 02:06 PM UTC

Hi! I really appreciate the extent of the support. The issue has been fixed once and for all. My application is running well and no issues have been reported. Thank you so much!


DB Dilli Babu Nandha Gopal Syncfusion Team January 18, 2019 06:40 AM UTC

Hi Raelson, 
  
We are glad to know that the reported issue has been resolved. Please let us know if you need any further assistance. 
  
Regards, 
Dilli babu 



ZK Zeeshan Khan March 3, 2023 08:22 PM UTC

This latest sample provided by you worked for me after replacing following deprecated line:

Android.OS.Environment.ExternalStorageDirectory.ToString();

with

Android.App.Application.Context.GetExternalFilesDir(null).AbsolutePath;


Just posting, in case anybody interested in future.



SB Suriya Balamurugan Syncfusion Team March 6, 2023 12:35 PM UTC

Zeeshan, Thanks for sharing.


Loader.
Live Chat Icon For mobile
Up arrow icon