How to write from byte array to both Android and iOS devices?

OnurERYILMAZOnurERYILMAZ USMember ✭✭
edited February 2018 in Xamarin.Forms

Hi,

I want to create a file(.pdf, .docx, .jpeg etc.) from byte array in my application. I'm getting the byte array from web service. But I couldn't write this byte array to a file.

Here is my code;

string directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string folderName = "BILPLASManagementSystem"; if (!File.Exists(Path.Combine(directory, folderName))) Directory.CreateDirectory(Path.Combine(directory, folderName)); string docName = "TempDoc" + ((Directory.GetFiles(Path.Combine(directory, folderName), "TempDoc*" + _selectedDocument.FileExtension).Length) + 1).ToString() + _selectedDocument.FileExtension; string tempDirectory = Path.Combine(directory, folderName, docName); File.WriteAllBytes(tempDirectory, _selectedDocument.DocumentBytes);

This code gets no error, but it doesn't create any file either.

What am I missing?

Thank you.

Answers

  • AndyFlisherAndyFlisher GBBeta, University ✭✭✭

    Not sure if this will help as old code, but it works (snipped from a process that pulls down a rest api and has images as base64 encoded strings. I have the code the split into Android and iOS specific, there may be better ways of doing it, and obviously adjust your paths to suit;

    iOS

    var imagePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    imagePath = Path.Combine(imagePath, bookId.ToString());
    if (!System.IO.Directory.Exists(imagePath.ToString()))
    {
        Directory.CreateDirectory(imagePath);
    }
    imagePath = Path.Combine(imagePath, momentResponse.filename);
    
    
    byte[] imageBytes = System.Convert.FromBase64String(momentResponse.imagedata);
    NSData data = NSData.FromArray(imageBytes);
    NSError err = null;
    data.Save(imagePath, false, out err);
    

    Android

    var imagePath = System.IO.Path.Combine(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).ToString(), "MyFolderName");
    imagePath = Path.Combine(imagePath, bookId.ToString());
    if (!System.IO.Directory.Exists(imagePath.ToString()))
    {
        Directory.CreateDirectory(imagePath);
    }
    imagePath = Path.Combine(imagePath, momentResponse.filename);
    
    
    byte[] imageBytes = System.Convert.FromBase64String(momentResponse.imagedata);
    System.IO.File.WriteAllBytes(imagePath, imageBytes);
    
  • OnurERYILMAZOnurERYILMAZ USMember ✭✭

    @AndyFlisher Thank you for reply. This codes didn't work either. I get AccessDenied error with this code. My application has write and read permissions.

  • AndyFlisherAndyFlisher GBBeta, University ✭✭✭

    Permissions on Android or iOS or both @OnurERYILMAZ ? If you post specific error messages we might be able to help?

    Thanks

  • OnurERYILMAZOnurERYILMAZ USMember ✭✭
    edited February 2018

    @AndyFlisher I cannot try on iOS because I don't have any Apple device. So, I'm currently trying only on Android device. I add the read and write permissions on Android manifest like this;


    When I execute this;

    File.WriteAllBytes(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "test" +         
        _selectedProblem.FileExtension), _selectedProblem.ProblemDocument);
    

    I get this error, but application doesn't break. (I checked my _selectedProblem object, file extension and byte array and all is fine.)

    Error while resolving expression: Object reference not set to an instance of an object.

    When I execute this;

            string directory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                        string folderName = "TestFolder";
                        if (!File.Exists(Path.Combine(directory, folderName)))
                            Directory.CreateDirectory(Path.Combine(directory, folderName));
                        string docName = "TempDoc" + ((Directory.GetFiles(Path.Combine(directory, folderName), "TempDoc*" +                 
                        _selectedProblem.FileExtension).Length) + 1).ToString() + _selectedProblem.FileExtension;
                        string tempDirectory = Path.Combine(directory, folderName, docName);
    
                        using (FileStream fStream = new FileStream(tempDirectory, FileMode.Create, FileAccess.ReadWrite))
                        {
                            using (BinaryWriter writer = new BinaryWriter(fStream))
                            {
                                writer.Write(_selectedProblem.ProblemDocument);
                            }
                        }
    

    I get no errors, but I don't see any created document.

    When I execute this;

            string directory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                        File.WriteAllBytes(Path.Combine(directory, "test" + _selectedProblem.FileExtension), 
                       _selectedProblem.ProblemDocument);
    

    I get this error;

    System.UnauthorizedAccessException: Access to the path '/data/data/BLPWCPV02.Android/files' is denied.
    Error while resolving expression: Object reference not set to an instance of an object.

    Thank you.

  • OnurERYILMAZOnurERYILMAZ USMember ✭✭
    edited February 2018

    After a lot of research and tryings, now I can save and open files via Android devices. Now I just need to figured it out how to do same things in iOS.

    Here is the final code;

    string directory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                            string docName = "TempDoc" + ((Directory.GetFiles(directory, "TempDoc*" + 
       _selectedWorkCommandProblem.FileExtension).Length) + 1).ToString() + 
       _selectedWorkCommandProblem.FileExtension;
    // In here we save the file but saved file doesn't shown for some reason! Thats why I'm struggling all day.
                            File.WriteAllBytes(Path.Combine(directory, docName), 
       _selectedProblem.ProblemDocument);
    
                            var bytes = File.ReadAllBytes(Path.Combine(directory, docName));
                            string externalStoragePath = 
       Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, docName);
                            File.WriteAllBytes(externalStoragePath, bytes);
    
                            Android.Net.Uri uri = Android.Net.Uri.Parse("file://" + externalStoragePath);
                            Intent intent = new Intent(Intent.ActionView);
                            intent.SetDataAndType(uri, "application/" + 
       _selectedProblem.FileExtension.Substring(_selectedProblem.FileExtension.IndexOf('.') + 1));
                            intent.SetFlags(ActivityFlags.NewTask);
                            Forms.Context.StartActivity(intent);
    
  • AndyFlisherAndyFlisher GBBeta, University ✭✭✭

    Glad you got further, what's the error on iOS, permissions?

  • NengPuthNengPuth Member

    Hi @OnurERYILMAZ What this '_selectedWorkCommandProblem.FileExtension' ? Can you give us the detail?

Sign In or Register to comment.