How to download a file in Xamarin

By: Admin

downloading files in Xamarin

File Download:

Get a file and filename from a table with the following code:

var filePath = projectAttachment.FileUrl.Replace("~/", "");

FileInfo info = new FileInfo(projectAttachment.FileUrl);

var filename = projectAttachment.Filename + info.Extension;

 

AzureApiService:

To get an Azure backend url from the AzureApiService:

string backendUrl = "https://mobilexapp.azurewebsites.net";
 
        static HttpClient client = new HttpClient();
 
        public AzureApiService()
        {
            if (client.BaseAddress == null)
            {
                client.BaseAddress = new Uri(backendUrl);
                client.DefaultRequestHeaders.Add("ZUMO-API-VERSION", "2.0.0");
            }
        }

 

Use the following code to pull data based on the ‘Get’ method, present in the AzureApiService.

var data = await service.GetFileAsync(filePath);

 

The code below is in AzureApiService:

public async Task<byte[]> GetFileAsync(string fileName)
      {
          string path = $"api/Files?fileName={fileName}";
          var response = await client.GetAsync(path);
          if (response?.Content != null && response.StatusCode == HttpStatusCode.OK)
          {
              return await response.Content.ReadAsByteArrayAsync();
          }
          return null;
      }

In this snippet code, we will get the file path and a response from the backend.

 

Backend Controller – ApiController:

In the Controller, we can get the response using the Get Method . This controller extends from ApiController.

public async Task Get(string fileName)
        {
            var data = await GetFileAsync(fileName);
            if (data == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            var response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content = new ByteArrayContent(data);
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            response.Content.Headers.ContentLength = data.Length;
            return response;
        }

We can use the GetFileAsync method with a filename parameter to call the AzureStorageService.

AzureStorageService:

Azure storage is a scalable cloud storage solution for unstructured, and structured data. We recommend using blob storage to store and access data.

Azure storage offers four storage services:

  • Blob Storage: used to store text or binary data, e.g. backups, virtual machines, media files or documents.
  • Table Storage: a NoSQL Key-attribute storage.
  • Queue Storage: a messaging service for workflow processing and communications between cloud services.
  • File Storage: a shared storage using the SMB protocol.

There are two types of storage accounts:

  • A general-purpose storage accounts provides access to Azure Storage services from a single account.
  • A Blob storage account is a special storage account, recommended only for use with blob data.

 

Blob storage consists of three components:

file download

All access to Azure Storage is through a storage account. A storage account can contain an unlimited number of containers, and a container can store an unlimited number of blobs, up to the capacity limit of the storage account.

A blob is a file of any type and size. Azure Storage supports three different blob types:

  • Block blobs are optimized for streaming and storing cloud objects, and are an excellent choice for storing backups, media files, documents etc. Block blobs can be up to 195Gb in size.
  • Append blobs are like block blobs but are optimized for append operations, such as logging. Append blobs can be up to 195Gb in size.
  • Page blobs are optimized for frequent read/write operations and are typically used for storing virtual machines and their disks. Page blobs can be up to 1Tb in size.

Creating a Container – GetContainer:

The GetContainer method is used to retrieve a reference to a named container. This can then be used to retrieve blobs from the container or to add blobs to the container. The following example shows the GetContainer method:

static CloudBlobContainer GetContainer(ContainerType containerType)
        {
            var appSettings = new AzureApiSettings();
            var account = CloudStorageAccount.Parse(appSettings.WindowsAzureStorageConnectionString);
            var client = account.CreateCloudBlobClient();
            return client.GetContainerReference(containerType.ToString().ToLower());
        }

Downloading data from a container – GetFileAsync:

The GetFileAsync method is used to download blob data from Azure storage, and is shown in the following code example:

public static async Task<byte[]> GetFileAsync(string fileName)
        {
            var container = GetContainer(ContainerType.FileContainer);
            var blob = container.GetBlockBlobReference(fileName);
 
            if (blob.ExistsAsync().Result)
            {
                await blob.FetchAttributesAsync();
                byte[] blobBytes = new byte[blob.Properties.Length];
                await blob.DownloadToByteArrayAsync(blobBytes, 0);
 
                return blobBytes;
            }
            return null;
        }

After retrieving a container reference, the method retrieves a blob reference for the stored data. If the blob exists, its properties are retrieved by the FetchAttributesAsync method. A byte array of the correct size is created, and the blob is downloaded as an array of bytes that gets returned to the calling method.

Platform Dependent:

  • Android
  • IOS

We can create a common call while creating a dependency with interface IStorageHelper. This should call the same function in different projects.

var storage = DependencyService.Get<IStorageHelper>();

 

To download a file in Android:

The following code demonstrates how to download a file based on its format:

 public void SaveandOpenFile(byte[] data, string fileName)
{
  string externalStorageState = global::Android.OS.Environment.ExternalStorageState;
  var externalPath = global::Android.OS.Environment.ExternalStorageDirectory.Path + "/" + global::Android.OS.Environment.DirectoryDownloads + "/" + fileName;
            File.WriteAllBytes(externalPath, data);
 
            Java.IO.File file = new Java.IO.File(externalPath);
            file.SetReadable(true);
 
            string application = "";
            string extension = Path.GetExtension(externalPath);
 
            // get mimeTye
            switch (extension.ToLower())
            {
                case ".txt":
                    application = "text/plain";
                    break;
                case ".doc":
                case ".docx":
                    application = "application/msword";
                    break;
                case ".pdf":
                    application = "application/pdf";
                    break;
                case ".xls":
                case ".xlsx":
                    application = "application/vnd.ms-excel";
                    break;
                case ".jpg":
                case ".jpeg":
                case ".png":
                    application = "image/jpeg";
                    break;
                default:
                    application = "*/*";
                    break;
            }
 
            //Android.Net.Uri uri = Android.Net.Uri.Parse("file://" + filePath);
            Android.Net.Uri uri = Android.Net.Uri.FromFile(file);
            Intent intent = new Intent(Intent.ActionView);
            intent.SetDataAndType(uri, application);
            intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask);
 
            Forms.Context.StartActivity(intent);
        }

To download a file in iOS:

Use the following code to download a file in iOS.

public void SaveandOpenFile(byte[] data, string fileName)
{
 var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), fileName);
 File.WriteAllBytes(path, data);
 var PreviewController = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(path));
 PreviewController.Delegate = new UIDocumentInteractionControllerDelegateClass(UIApplication.SharedApplication.KeyWindow.RootViewController);
 Device.BeginInvokeOnMainThread(() =>
     {
        PreviewController.PresentPreview(true);
     });
}

 

UIDocumentInteractionController:

This snippet supports the function of displaying, preview and opening files stored on an iOS device:

public class UIDocumentInteractionControllerDelegateClass : UIDocumentInteractionControllerDelegate
   {
       UIViewController ownerVC;
        public UIDocumentInteractionControllerDelegateClass(UIViewController vc)
       {
           ownerVC = vc;
       }
 
       public override UIViewController ViewControllerForPreview(UIDocumentInteractionController controller)
       {
           return ownerVC;
       }
        public override UIView ViewForPreview(UIDocumentInteractionController controller)
       {
           return ownerVC.View;
       }
   }

What are you looking for?

Join our newsletter list of over 5,000 innovators and receive an email update every other month
Copyright© 2018 alligatortek. All rights reserved.