├── LICENSE ├── README.md ├── XamarinImageUploader.sln └── XamarinImageUploader ├── XamarinImageUploader.Droid ├── Assets │ └── AboutAssets.txt ├── ImageActivity.cs ├── ListImagesActivity.cs ├── MainActivity.cs ├── Properties │ ├── AndroidManifest.xml │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.designer.cs │ ├── drawable-hdpi │ │ └── Icon.png │ ├── drawable-mdpi │ │ └── Icon.png │ ├── drawable-xhdpi │ │ └── Icon.png │ ├── drawable-xxhdpi │ │ └── Icon.png │ ├── drawable-xxxhdpi │ │ └── Icon.png │ ├── layout │ │ ├── Image.axml │ │ ├── Main.axml │ │ └── TextViewItem.axml │ └── values │ │ └── Strings.xml ├── XamarinImageUploader.Droid.csproj ├── XamarinImageUploader.Droid.csproj.bak ├── XamarinImageUploader.Droid.csproj.user └── packages.config ├── XamarinImageUploader.WinPhone ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── Logo.scale-240.png │ ├── SmallLogo.scale-240.png │ ├── SplashScreen.scale-240.png │ ├── Square71x71Logo.scale-240.png │ ├── StoreLogo.scale-240.png │ └── WideLogo.scale-240.png ├── ImagePage.xaml ├── ImagePage.xaml.cs ├── ImagesPage.xaml ├── ImagesPage.xaml.cs ├── MainPage.xaml ├── MainPage.xaml.cs ├── Package.appxmanifest ├── Properties │ └── AssemblyInfo.cs ├── XamarinImageUploader.WinPhone.csproj ├── XamarinImageUploader.WinPhone.csproj.user └── packages.config ├── XamarinImageUploader.iOS ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Entitlements.plist ├── ImageListController.cs ├── ImageListController.designer.cs ├── Info.plist ├── LaunchScreen.storyboard ├── Main.cs ├── Main.storyboard ├── Resources │ └── AppDelegate.cs ├── ViewController.cs ├── ViewController.designer.cs ├── XamarinImageUploader.iOS.csproj └── packages.config └── XamarinImageUploader ├── Configuration.cs ├── ImageManager.cs ├── XamarinImageUploader.projitems └── XamarinImageUploader.shproj /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | services: storage 3 | platforms: xamarin 4 | author: pcibraro 5 | --- 6 | 7 | # Azure Storage Service - Photo Uploader Sample using Xamarin for Android, iOS and Windows. 8 | 9 | This sample demostrates how to upload photo images from the gallery in Android, iOS and Windows Phone into a Block blob in Azure Storage with Xamarin. It shows a button "Select Image" to select 10 | an image from the gallery, a button "Upload Image" to upload it to the Azure Storage, a button "List images" to list all the uploaded images. 11 | A Shared Asset Project is used for reusing all the common code for the platform specific projects. 12 | 13 | Note: This sample uses the Windows Azure Storage client library for .NET available through a Nuget package. 14 | 15 | If you don't have a Microsoft Azure subscription you can get a FREE trial account [here](http://go.microsoft.com/fwlink/?LinkId=330212). 16 | 17 | ## Running this sample in Windows with Visual Studio 18 | 19 | This sample can be run using either the Azure Storage Emulator that installs as part of the Windows Azure SDK - or by updating the StorageConnectionString variable defined at Configuration.cs file in the Shared Native Library Project. 20 | 21 | To run the sample using the Storage Emulator (Windows Azure SDK / Only on Windows): 22 | 23 | 1. Download and Install the Azure Storage Emulator [here](http://azure.microsoft.com/en-us/downloads/). 24 | 2. Start the Azure Storage Emulator (once only) by pressing the Start button or the Windows key and searching for it by typing "Azure Storage Emulator". Select it from the list of applications to start it. 25 | 3. Set breakpoints and run the project using F10. 26 | 27 | To run the sample using the Storage Service 28 | 29 | 1. Open the Configuration.cs file in the Shared Native Library Project "XamarinImageUploader". Replace the StorageConnectionString variable (UseDevelopmentStorage=True) with the connection string for the storage service (AccountName=[]...) 30 | 2. Create a Storage Account through the Azure Portal and provide your [AccountName] and [AccountKey] in the StorageConnectionString variable. 31 | 3. Set breakpoints and run the project using F10. 32 | 33 | > **WARNING:** 34 | > **Only use Shared Key authentication for testing purposes!** Your account name and account key, which give full read/write access to the associated Storage account, will be distributed to every person that downloads your app. This is **not** a good practice as you risk having your key compromised by untrusted clients. Please consult following documents to understand and use Shared Access Signatures instead. https://docs.microsoft.com/en-us/rest/api/storageservices/delegating-access-with-a-shared-access-signature and https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1 35 | > 36 | 37 | Note: You can also run the sample with Xamarin Studio, but only the Android and iOS samples will be available. For the Windows Phone sample, you can only use Visual Studio. 38 | 39 | ## More information 40 | - [What is a Storage Account](http://azure.microsoft.com/en-us/documentation/articles/storage-whatis-account/) 41 | - [How to use Blob Storage from iOS](https://azure.microsoft.com/en-us/documentation/articles/storage-ios-how-to-use-blob-storage/) 42 | - [Blob Service Concepts](http://msdn.microsoft.com/en-us/library/dd179376.aspx) 43 | - [Blob Service REST API](http://msdn.microsoft.com/en-us/library/dd135733.aspx) 44 | -------------------------------------------------------------------------------- /XamarinImageUploader.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamarinImageUploader.Droid", "XamarinImageUploader\XamarinImageUploader.Droid\XamarinImageUploader.Droid.csproj", "{9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamarinImageUploader.WinPhone", "XamarinImageUploader\XamarinImageUploader.WinPhone\XamarinImageUploader.WinPhone.csproj", "{06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}" 9 | EndProject 10 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "XamarinImageUploader", "XamarinImageUploader\XamarinImageUploader\XamarinImageUploader.shproj", "{20663075-BEA6-4747-875A-BAA0FC574043}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XamarinImageUploader.iOS", "XamarinImageUploader\XamarinImageUploader.iOS\XamarinImageUploader.iOS.csproj", "{269894DF-A29A-4CDD-BF66-86E81AD90599}" 13 | EndProject 14 | Global 15 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 16 | XamarinImageUploader\XamarinImageUploader\XamarinImageUploader.projitems*{06054d7b-ddf4-4da6-9456-8fe9e3be47f3}*SharedItemsImports = 4 17 | XamarinImageUploader\XamarinImageUploader\XamarinImageUploader.projitems*{20663075-bea6-4747-875a-baa0fc574043}*SharedItemsImports = 13 18 | XamarinImageUploader\XamarinImageUploader\XamarinImageUploader.projitems*{269894df-a29a-4cdd-bf66-86e81ad90599}*SharedItemsImports = 4 19 | XamarinImageUploader\XamarinImageUploader\XamarinImageUploader.projitems*{9af8a6fb-3b7f-4cbb-b9e4-f9aedb3b6511}*SharedItemsImports = 4 20 | EndGlobalSection 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Debug|ARM = Debug|ARM 24 | Debug|iPhone = Debug|iPhone 25 | Debug|iPhoneSimulator = Debug|iPhoneSimulator 26 | Debug|x86 = Debug|x86 27 | Release|Any CPU = Release|Any CPU 28 | Release|ARM = Release|ARM 29 | Release|iPhone = Release|iPhone 30 | Release|iPhoneSimulator = Release|iPhoneSimulator 31 | Release|x86 = Release|x86 32 | EndGlobalSection 33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 34 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 37 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|ARM.ActiveCfg = Debug|Any CPU 38 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|ARM.Build.0 = Debug|Any CPU 39 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|ARM.Deploy.0 = Debug|Any CPU 40 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|iPhone.ActiveCfg = Debug|Any CPU 41 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|iPhone.Build.0 = Debug|Any CPU 42 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|iPhone.Deploy.0 = Debug|Any CPU 43 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 44 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 45 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU 46 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|x86.ActiveCfg = Debug|Any CPU 47 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|x86.Build.0 = Debug|Any CPU 48 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Debug|x86.Deploy.0 = Debug|Any CPU 49 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|Any CPU.ActiveCfg = Release|Any CPU 50 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|Any CPU.Build.0 = Release|Any CPU 51 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|Any CPU.Deploy.0 = Release|Any CPU 52 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|ARM.ActiveCfg = Release|Any CPU 53 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|ARM.Build.0 = Release|Any CPU 54 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|ARM.Deploy.0 = Release|Any CPU 55 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|iPhone.ActiveCfg = Release|Any CPU 56 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|iPhone.Build.0 = Release|Any CPU 57 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|iPhone.Deploy.0 = Release|Any CPU 58 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 59 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 60 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU 61 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|x86.ActiveCfg = Release|Any CPU 62 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|x86.Build.0 = Release|Any CPU 63 | {9AF8A6FB-3B7F-4CBB-B9E4-F9AEDB3B6511}.Release|x86.Deploy.0 = Release|Any CPU 64 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 67 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|ARM.ActiveCfg = Debug|ARM 68 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|ARM.Build.0 = Debug|ARM 69 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|ARM.Deploy.0 = Debug|ARM 70 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|iPhone.ActiveCfg = Debug|Any CPU 71 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|iPhone.Build.0 = Debug|Any CPU 72 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|iPhone.Deploy.0 = Debug|Any CPU 73 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 74 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 75 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU 76 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|x86.ActiveCfg = Debug|x86 77 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|x86.Build.0 = Debug|x86 78 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Debug|x86.Deploy.0 = Debug|x86 79 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|Any CPU.ActiveCfg = Release|Any CPU 80 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|Any CPU.Build.0 = Release|Any CPU 81 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|Any CPU.Deploy.0 = Release|Any CPU 82 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|ARM.ActiveCfg = Release|ARM 83 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|ARM.Build.0 = Release|ARM 84 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|ARM.Deploy.0 = Release|ARM 85 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|iPhone.ActiveCfg = Release|Any CPU 86 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|iPhone.Build.0 = Release|Any CPU 87 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|iPhone.Deploy.0 = Release|Any CPU 88 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 89 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 90 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU 91 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|x86.ActiveCfg = Release|x86 92 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|x86.Build.0 = Release|x86 93 | {06054D7B-DDF4-4DA6-9456-8FE9E3BE47F3}.Release|x86.Deploy.0 = Release|x86 94 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator 95 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator 96 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|ARM.ActiveCfg = Debug|iPhoneSimulator 97 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|ARM.Build.0 = Debug|iPhoneSimulator 98 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|iPhone.ActiveCfg = Debug|iPhone 99 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|iPhone.Build.0 = Debug|iPhone 100 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator 101 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator 102 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|x86.ActiveCfg = Debug|iPhoneSimulator 103 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Debug|x86.Build.0 = Debug|iPhoneSimulator 104 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|Any CPU.ActiveCfg = Release|iPhone 105 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|Any CPU.Build.0 = Release|iPhone 106 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|ARM.ActiveCfg = Release|iPhone 107 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|ARM.Build.0 = Release|iPhone 108 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|iPhone.ActiveCfg = Release|iPhone 109 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|iPhone.Build.0 = Release|iPhone 110 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator 111 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator 112 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|x86.ActiveCfg = Release|iPhone 113 | {269894DF-A29A-4CDD-BF66-86E81AD90599}.Release|x86.Build.0 = Release|iPhone 114 | EndGlobalSection 115 | GlobalSection(SolutionProperties) = preSolution 116 | HideSolutionNode = FALSE 117 | EndGlobalSection 118 | EndGlobal 119 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.Droid/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.Droid/ImageActivity.cs: -------------------------------------------------------------------------------- 1 | /**---------------------------------------------------------------------------------- 2 | * Microsoft Developer & Platform Evangelism 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 7 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 8 | * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 9 | *---------------------------------------------------------------------------------- 10 | * The example companies, organizations, products, domain names, 11 | * e-mail addresses, logos, people, places, and events depicted 12 | * herein are fictitious. No association with any real company, 13 | * organization, product, domain name, email address, logo, person, 14 | * places, or events is intended or should be inferred. 15 | *---------------------------------------------------------------------------------- 16 | **/ 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Linq; 21 | using System.Text; 22 | 23 | using Android.App; 24 | using Android.Content; 25 | using Android.OS; 26 | using Android.Runtime; 27 | using Android.Views; 28 | using Android.Widget; 29 | using Android.Graphics; 30 | 31 | namespace XamarinImageUploader.Droid 32 | { 33 | [Activity(Label = "ImageActivity")] 34 | public class ImageActivity : Activity 35 | { 36 | protected async override void OnCreate(Bundle savedInstanceState) 37 | { 38 | base.OnCreate(savedInstanceState); 39 | 40 | SetContentView(Resource.Layout.Image); 41 | 42 | var image = this.Intent.Extras.GetString("image"); 43 | 44 | var imageBytes = await ImageManager.GetImage(image); 45 | 46 | var bitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length); 47 | 48 | var imageView = FindViewById(Resource.Id.ChildImageView); 49 | 50 | imageView.SetImageBitmap(bitmap); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.Droid/ListImagesActivity.cs: -------------------------------------------------------------------------------- 1 | /**---------------------------------------------------------------------------------- 2 | * Microsoft Developer & Platform Evangelism 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 7 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 8 | * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 9 | *---------------------------------------------------------------------------------- 10 | * The example companies, organizations, products, domain names, 11 | * e-mail addresses, logos, people, places, and events depicted 12 | * herein are fictitious. No association with any real company, 13 | * organization, product, domain name, email address, logo, person, 14 | * places, or events is intended or should be inferred. 15 | *---------------------------------------------------------------------------------- 16 | **/ 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Linq; 21 | using System.Text; 22 | 23 | using Android.App; 24 | using Android.Content; 25 | using Android.OS; 26 | using Android.Runtime; 27 | using Android.Views; 28 | using Android.Widget; 29 | 30 | 31 | namespace XamarinImageUploader.Droid 32 | { 33 | [Activity(Label = "ListImagesActivity")] 34 | public class ListImagesActivity : ListActivity 35 | { 36 | string[] images; 37 | 38 | protected async override void OnCreate(Bundle savedInstanceState) 39 | { 40 | base.OnCreate(savedInstanceState); 41 | 42 | images = await ImageManager.ListImages(); 43 | 44 | var adapter = new ArrayAdapter(this, Resource.Layout.TextViewItem, images); 45 | 46 | ListAdapter = adapter; 47 | } 48 | 49 | protected override void OnListItemClick(ListView l, View v, int position, long id) 50 | { 51 | this.Intent = new Intent(this, typeof(ImageActivity)); 52 | this.Intent.PutExtra("image", images[position]); 53 | 54 | StartActivity(this.Intent); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.Droid/MainActivity.cs: -------------------------------------------------------------------------------- 1 | /**---------------------------------------------------------------------------------- 2 | * Microsoft Developer & Platform Evangelism 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 7 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 8 | * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 9 | *---------------------------------------------------------------------------------- 10 | * The example companies, organizations, products, domain names, 11 | * e-mail addresses, logos, people, places, and events depicted 12 | * herein are fictitious. No association with any real company, 13 | * organization, product, domain name, email address, logo, person, 14 | * places, or events is intended or should be inferred. 15 | *---------------------------------------------------------------------------------- 16 | **/ 17 | 18 | using System; 19 | 20 | using Android.App; 21 | using Android.Content; 22 | using Android.Runtime; 23 | using Android.Views; 24 | using Android.Widget; 25 | using Android.OS; 26 | using System.Threading.Tasks; 27 | 28 | namespace XamarinImageUploader.Droid 29 | { 30 | [Activity (Label = "XamarinImageUploader.Droid", MainLauncher = true, Icon = "@drawable/icon")] 31 | public class MainActivity : Activity 32 | { 33 | public static readonly int PickImageId = 1000; 34 | private ImageView imageView; 35 | private Android.Net.Uri imageUri; 36 | private Button uploadButton; 37 | 38 | protected override void OnCreate (Bundle bundle) 39 | { 40 | base.OnCreate (bundle); 41 | 42 | SetContentView(Resource.Layout.Main); 43 | imageView = FindViewById(Resource.Id.RootImageView); 44 | Button selectButton = FindViewById 38 | 50 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.iOS/Resources/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using UIKit; 3 | 4 | namespace XamarinImageUploader.iOS.iOS 5 | { 6 | // The UIApplicationDelegate for the application. This class is responsible for launching the 7 | // User Interface of the application, as well as listening (and optionally responding) to application events from iOS. 8 | [Register("AppDelegate")] 9 | public class AppDelegate : UIApplicationDelegate 10 | { 11 | // class-level declarations 12 | 13 | public override UIWindow Window 14 | { 15 | get; 16 | set; 17 | } 18 | 19 | public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) 20 | { 21 | // Override point for customization after application launch. 22 | // If not required for your application you can safely delete this method 23 | 24 | return true; 25 | } 26 | 27 | public override void OnResignActivation(UIApplication application) 28 | { 29 | // Invoked when the application is about to move from active to inactive state. 30 | // This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) 31 | // or when the user quits the application and it begins the transition to the background state. 32 | // Games should use this method to pause the game. 33 | } 34 | 35 | public override void DidEnterBackground(UIApplication application) 36 | { 37 | // Use this method to release shared resources, save user data, invalidate timers and store the application state. 38 | // If your application supports background exection this method is called instead of WillTerminate when the user quits. 39 | } 40 | 41 | public override void WillEnterForeground(UIApplication application) 42 | { 43 | // Called as part of the transiton from background to active state. 44 | // Here you can undo many of the changes made on entering the background. 45 | } 46 | 47 | public override void OnActivated(UIApplication application) 48 | { 49 | // Restart any tasks that were paused (or not yet started) while the application was inactive. 50 | // If the application was previously in the background, optionally refresh the user interface. 51 | } 52 | 53 | public override void WillTerminate(UIApplication application) 54 | { 55 | // Called when the application is about to terminate. Save data, if needed. See also DidEnterBackground. 56 | } 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.iOS/ViewController.cs: -------------------------------------------------------------------------------- 1 | /**---------------------------------------------------------------------------------- 2 | * Microsoft Developer & Platform Evangelism 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 7 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 8 | * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 9 | *---------------------------------------------------------------------------------- 10 | * The example companies, organizations, products, domain names, 11 | * e-mail addresses, logos, people, places, and events depicted 12 | * herein are fictitious. No association with any real company, 13 | * organization, product, domain name, email address, logo, person, 14 | * places, or events is intended or should be inferred. 15 | *---------------------------------------------------------------------------------- 16 | **/ 17 | 18 | using System; 19 | using System.Threading.Tasks; 20 | using Foundation; 21 | using UIKit; 22 | 23 | namespace XamarinImageUploader.iOS.iOS 24 | { 25 | public partial class ViewController : UIViewController 26 | { 27 | UIImagePickerController imagePickerController; 28 | 29 | partial void SelectButton_TouchUpInside(UIButton sender) 30 | { 31 | imagePickerController = new UIImagePickerController(); 32 | imagePickerController.Delegate = this; 33 | 34 | imagePickerController.SourceType = UIImagePickerControllerSourceType.PhotoLibrary; 35 | imagePickerController.MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary); 36 | 37 | //https://developer.xamarin.com/recipes/ios/media/video_and_photos/choose_a_photo_from_the_gallery/ 38 | imagePickerController.FinishedPickingMedia += Handle_FinishedPickingMedia; 39 | imagePickerController.Canceled += Handle_Canceled; 40 | 41 | if (NavigationController != null) 42 | { 43 | this.PresentViewController(imagePickerController, true, null); 44 | } 45 | } 46 | 47 | //https://developer.xamarin.com/guides/cross-platform/advanced/async_support_overview/ 48 | [Action("UploadButton_TouchUpInside:")] 49 | async void UploadButton_TouchUpInside(UIButton sender) 50 | { 51 | var imageStream = ImageView.Image.AsPNG().AsStream(); 52 | 53 | var name = await ImageManager.UploadImage(imageStream); 54 | 55 | var alert = UIAlertController.Create( 56 | null, 57 | null, 58 | UIAlertControllerStyle.ActionSheet); 59 | alert.Title = "Image upload"; 60 | alert.Message = "The image was uploaded successully. Image Name:" + name; 61 | alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, (obj) => { })); 62 | this.NavigationController.PresentViewController(alert, true, null); 63 | } 64 | 65 | private void Handle_FinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs e) 66 | { 67 | // determine what was selected, video or image 68 | bool isImage = false; 69 | switch (e.Info[UIImagePickerController.MediaType].ToString()) 70 | { 71 | case "public.image": 72 | Console.WriteLine("Image selected"); 73 | isImage = true; 74 | break; 75 | case "public.video": 76 | Console.WriteLine("Video selected"); 77 | break; 78 | } 79 | 80 | // get common info (shared between images and video) 81 | NSUrl referenceURL = e.Info[new NSString("UIImagePickerControllerReferenceUrl")] as NSUrl; 82 | if (referenceURL != null) 83 | Console.WriteLine("Url:" + referenceURL.ToString()); 84 | 85 | // if it was an image, get the other image info 86 | if (isImage) 87 | { 88 | UploadButton.Enabled = true; 89 | 90 | // get the original image 91 | UIImage originalImage = e.Info[UIImagePickerController.OriginalImage] as UIImage; 92 | if (originalImage != null) 93 | { 94 | // do something with the image 95 | Console.WriteLine("got the original image"); 96 | ImageView.Image = originalImage; // display 97 | } 98 | } 99 | 100 | // dismiss the picker 101 | imagePickerController.DismissViewController(true, null); 102 | } 103 | 104 | private void Handle_Canceled(object sender, EventArgs e) 105 | { 106 | imagePickerController.DismissViewController(true, null); 107 | } 108 | 109 | public ViewController(IntPtr handle) : base(handle) 110 | { 111 | } 112 | 113 | public override void ViewDidLoad() 114 | { 115 | base.ViewDidLoad(); 116 | 117 | UploadButton.Enabled = false; 118 | 119 | } 120 | 121 | public override void DidReceiveMemoryWarning() 122 | { 123 | base.DidReceiveMemoryWarning(); 124 | // Release any cached data, images, etc that aren't in use. 125 | } 126 | 127 | public override void PrepareForSegue(UIStoryboardSegue segue, Foundation.NSObject sender) 128 | { 129 | base.PrepareForSegue(segue, sender); 130 | 131 | switch (segue.Identifier) { 132 | case "listImages": 133 | var vc = (ImageListController)segue.DestinationViewController; 134 | vc.Title = "Images"; 135 | break; 136 | 137 | } 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.iOS/ViewController.designer.cs: -------------------------------------------------------------------------------- 1 | // WARNING 2 | // 3 | // This file has been generated automatically by Xamarin Studio from the outlets and 4 | // actions declared in your storyboard file. 5 | // Manual changes to this file will not be maintained. 6 | // 7 | using Foundation; 8 | using System; 9 | using System.CodeDom.Compiler; 10 | using UIKit; 11 | 12 | namespace XamarinImageUploader.iOS.iOS 13 | { 14 | [Register ("ViewController")] 15 | partial class ViewController 16 | { 17 | [Outlet] 18 | UIKit.UIButton Button { get; set; } 19 | 20 | [Outlet] 21 | [GeneratedCode ("iOS Designer", "1.0")] 22 | UIKit.UIImageView ImageView { get; set; } 23 | 24 | [Outlet] 25 | [GeneratedCode ("iOS Designer", "1.0")] 26 | UIKit.UIButton ListButton { get; set; } 27 | 28 | [Outlet] 29 | [GeneratedCode ("iOS Designer", "1.0")] 30 | UIKit.UIButton SelectButton { get; set; } 31 | 32 | [Outlet] 33 | [GeneratedCode ("iOS Designer", "1.0")] 34 | UIKit.UIButton UploadButton { get; set; } 35 | 36 | [Action ("SelectButton_TouchUpInside:")] 37 | [GeneratedCode ("iOS Designer", "1.0")] 38 | partial void SelectButton_TouchUpInside (UIKit.UIButton sender); 39 | 40 | void ReleaseDesignerOutlets () 41 | { 42 | if (ImageView != null) { 43 | ImageView.Dispose (); 44 | ImageView = null; 45 | } 46 | 47 | if (ListButton != null) { 48 | ListButton.Dispose (); 49 | ListButton = null; 50 | } 51 | 52 | if (SelectButton != null) { 53 | SelectButton.Dispose (); 54 | SelectButton = null; 55 | } 56 | 57 | if (UploadButton != null) { 58 | UploadButton.Dispose (); 59 | UploadButton = null; 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.iOS/XamarinImageUploader.iOS.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | iPhoneSimulator 6 | {269894DF-A29A-4CDD-BF66-86E81AD90599} 7 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8 | Exe 9 | XamarinImageUploader.iOS.iOS 10 | XamarinImageUploader.iOS.iOS 11 | Resources 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\iPhoneSimulator\Debug 18 | DEBUG;ENABLE_TEST_CLOUD; 19 | prompt 20 | 4 21 | iPhone Developer 22 | true 23 | true 24 | true 25 | true 26 | None 27 | x86_64 28 | HttpClientHandler 29 | Default 30 | false 31 | 32 | 33 | pdbonly 34 | true 35 | bin\iPhone\Release 36 | 37 | 38 | prompt 39 | 4 40 | iPhone Developer 41 | true 42 | true 43 | true 44 | Entitlements.plist 45 | SdkOnly 46 | ARMv7, ARM64 47 | HttpClientHandler 48 | Default 49 | 50 | 51 | pdbonly 52 | true 53 | bin\iPhoneSimulator\Release 54 | 55 | 56 | prompt 57 | 4 58 | iPhone Developer 59 | true 60 | true 61 | None 62 | i386 63 | HttpClientHandler 64 | Default 65 | 66 | 67 | true 68 | full 69 | false 70 | bin\iPhone\Debug 71 | DEBUG;ENABLE_TEST_CLOUD; 72 | prompt 73 | 4 74 | iPhone Developer 75 | true 76 | true 77 | true 78 | true 79 | true 80 | true 81 | Entitlements.plist 82 | SdkOnly 83 | ARMv7, ARM64 84 | HttpClientHandler 85 | Default 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | ..\..\packages\Microsoft.Data.Edm.5.7.0\lib\portable-net45+wp8+win8+wpa\Microsoft.Data.Edm.dll 97 | False 98 | 99 | 100 | ..\..\packages\System.Spatial.5.7.0\lib\portable-net45+wp8+win8+wpa\System.Spatial.dll 101 | False 102 | 103 | 104 | ..\..\packages\Microsoft.Data.OData.5.7.0\lib\portable-net45+wp8+win8+wpa\Microsoft.Data.OData.dll 105 | False 106 | 107 | 108 | ..\..\packages\Microsoft.Data.Services.Client.5.7.0\lib\portable-net45+wp8+win8+wpa\Microsoft.Data.Services.Client.dll 109 | False 110 | 111 | 112 | ..\..\packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll 113 | 114 | 115 | ..\..\packages\WindowsAzure.Storage.7.2.1\lib\netstandard1.3\Microsoft.WindowsAzure.Storage.dll 116 | 117 | 118 | 119 | 120 | false 121 | 122 | 123 | false 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | ViewController.cs 143 | 144 | 145 | 146 | ImageListController.cs 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader.iOS/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader/Configuration.cs: -------------------------------------------------------------------------------- 1 | /**---------------------------------------------------------------------------------- 2 | * Microsoft Developer & Platform Evangelism 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 7 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 8 | * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 9 | *---------------------------------------------------------------------------------- 10 | * The example companies, organizations, products, domain names, 11 | * e-mail addresses, logos, people, places, and events depicted 12 | * herein are fictitious. No association with any real company, 13 | * organization, product, domain name, email address, logo, person, 14 | * places, or events is intended or should be inferred. 15 | *---------------------------------------------------------------------------------- 16 | **/ 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.Text; 21 | 22 | namespace XamarinImageUploader 23 | { 24 | public static class Configuration 25 | { 26 | /// 27 | /// Azure Storage Connection String. UseDevelopmentStorage=true points to the storage emulator. 28 | /// “Only use Shared Key authentication for testing purposes! Your account name and account key, which give full read/write access to the associated Storage account, 29 | /// will be distributed to every person that downloads your app. This is not a good practice as you risk having your key compromised by untrusted clients. 30 | /// Please consult following documents to understand and use Shared Access Signatures instead. 31 | /// https://docs.microsoft.com/en-us/rest/api/storageservices/delegating-access-with-a-shared-access-signature 32 | /// https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1 33 | /// 34 | public const string StorageConnectionString = "UseDevelopmentStorage=true"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader/ImageManager.cs: -------------------------------------------------------------------------------- 1 | /**---------------------------------------------------------------------------------- 2 | * Microsoft Developer & Platform Evangelism 3 | * 4 | * Copyright (c) Microsoft Corporation. All rights reserved. 5 | * 6 | * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 7 | * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 8 | * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 9 | *---------------------------------------------------------------------------------- 10 | * The example companies, organizations, products, domain names, 11 | * e-mail addresses, logos, people, places, and events depicted 12 | * herein are fictitious. No association with any real company, 13 | * organization, product, domain name, email address, logo, person, 14 | * places, or events is intended or should be inferred. 15 | *---------------------------------------------------------------------------------- 16 | **/ 17 | 18 | using System; 19 | using System.IO; 20 | using Microsoft.WindowsAzure.Storage; 21 | using System.Threading.Tasks; 22 | using System.Linq; 23 | using Microsoft.WindowsAzure.Storage.Blob; 24 | using System.Collections.Generic; 25 | 26 | namespace XamarinImageUploader 27 | { 28 | /// 29 | /// The image manager is responsible for uploading/downloading and listing images from the Blob Azure Storage 30 | /// 31 | public class ImageManager 32 | { 33 | public ImageManager () 34 | { 35 | } 36 | 37 | /// 38 | /// Gets a reference to the container for storing the images 39 | /// 40 | /// 41 | private static CloudBlobContainer GetContainer() 42 | { 43 | // Parses the connection string for the WindowS Azure Storage Account 44 | var account = CloudStorageAccount.Parse(Configuration.StorageConnectionString); 45 | var client = account.CreateCloudBlobClient(); 46 | 47 | // Gets a reference to the images container 48 | var container = client.GetContainerReference("images"); 49 | 50 | return container; 51 | } 52 | 53 | /// 54 | /// Uploads a new image to a blob container. 55 | /// 56 | /// 57 | /// 58 | public static async Task UploadImage(Stream image) 59 | { 60 | var container = GetContainer(); 61 | 62 | // Creates the container if it does not exist 63 | await container.CreateIfNotExistsAsync(); 64 | 65 | // Uses a random name for the new images 66 | var name = RandomString(10); 67 | 68 | // Uploads the image the blob storage 69 | var imageBlob = container.GetBlockBlobReference(name); 70 | await imageBlob.UploadFromStreamAsync(image); 71 | 72 | return name; 73 | } 74 | 75 | /// 76 | /// Lists of all the available images in the blob container 77 | /// 78 | /// 79 | public static async Task ListImages() 80 | { 81 | var container = GetContainer(); 82 | 83 | // Iterates multiple times to get all the available blobs 84 | var allBlobs = new List(); 85 | BlobContinuationToken token = null; 86 | 87 | do 88 | { 89 | var result = await container.ListBlobsSegmentedAsync(token); 90 | if (result.Results.Count() > 0) 91 | { 92 | var blobs = result.Results.Cast().Select(b => b.Name); 93 | allBlobs.AddRange(blobs); 94 | } 95 | 96 | token = result.ContinuationToken; 97 | } while (token != null); // no more blobs to retrieve 98 | 99 | return allBlobs.ToArray(); 100 | } 101 | 102 | /// 103 | /// Gets an image from the blob container using the name 104 | /// 105 | /// 106 | /// 107 | public static async Task GetImage(string name) 108 | { 109 | var container = GetContainer(); 110 | 111 | //Gets the block blob representing the image 112 | var blob = container.GetBlobReference(name); 113 | 114 | if(await blob.ExistsAsync()) 115 | { 116 | // Gets the block blob length to initialize the array in memory 117 | await blob.FetchAttributesAsync(); 118 | 119 | byte[] blobBytes = new byte[blob.Properties.Length]; 120 | 121 | // Downloads the block blob and stores the content in an array in memory 122 | await blob.DownloadToByteArrayAsync(blobBytes, 0); 123 | 124 | return blobBytes; 125 | } 126 | 127 | return null; 128 | } 129 | 130 | /// 131 | /// Generates a random string 132 | /// 133 | private static Random random = new Random(); 134 | private static string RandomString(int length) 135 | { 136 | const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 137 | return new string(Enumerable.Repeat(chars, length) 138 | .Select(s => s[random.Next(s.Length)]).ToArray()); 139 | } 140 | } 141 | } 142 | 143 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader/XamarinImageUploader.projitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 20663075-bea6-4747-875a-baa0fc574043 7 | 8 | 9 | XamarinImageUploader 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /XamarinImageUploader/XamarinImageUploader/XamarinImageUploader.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20663075-bea6-4747-875a-baa0fc574043 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | --------------------------------------------------------------------------------