Статьи

Расширение границ Windows Phone SDK и отправка файлов через EmailComposeTask

Я думал, что это позор, что я не могу прикрепить файлы к электронному письму через EmailComposeTask — и действительно, я не единственный, кто думает об этом:

образ

EmailComposeTask не позволит вам отправлять вложения, но это не означает, что вы не можете отправлять файлы через него. В .NET Framework есть два замечательных метода: Convert.ToBase64String и Convert.FromBase64String . Первый позволит разработчику преобразовать байтовый массив ( byte [] ) в строку, кодированную Base64 , другой будет выполнять ту же операцию в обратном порядке.

Допустим, я хочу отправить фотографию со своего телефона. Я собираюсь использовать CameraCaptureTask :

Microsoft.Phone.Tasks.CameraCaptureTask task = new Microsoft.Phone.Tasks.CameraCaptureTask();
task.Completed += new EventHandler(task_Completed);
task.Show();

Всякий раз, когда фотография сделана, у меня есть прямой доступ к полученному потоку. На этом этапе я могу получить из него байтовый массив, преобразовать его в Base64 и установить в качестве тела для EmailComposeTask :

void task_Completed(object sender, Microsoft.Phone.Tasks.PhotoResult e)
{
    int read = 0;
    int part = 0;
    byte[] buffer = new byte[22000];

    while ((read = e.ChosenPhoto.Read(buffer,0,buffer.Length)) > 0)
    {
        Thread.Sleep(10000);

        part++;
        string bsfData = Convert.ToBase64String(buffer);

        Debug.WriteLine(bsfData.Length);

        EmailComposeTask task = new EmailComposeTask();
        task.To = "[email protected]";
        task.Subject = "Part " + part.ToString();
        task.Body = bsfData;
        task.Show();
    }

}

Пара стрессовых моментов здесь:

  • Существует ограничение длины содержимого, в настоящее время установленное на 64 КБ (для тела сообщения), поэтому я должен разбить весь захваченный байтовый массив на куски, которые готовы к отправке. Если игнорируется, выдается следующее исключение:

    образ

  • В конечном итоге это создает электронное письмо из нескольких частей (читай: 22 части для 2-мегапиксельной фотографии).
  • Thread.Sleep (10000) создает задержку в 10 секунд между EmailComposeTask вызовами, потому что нет завершения уведомителя обработчика событий для этого конкретного типа задачи. Пользователь должен быстро нажать отправить в этом случае.
  • Без спящей нити я получаю это:

    образ

Как только все части отправлены, на принимающей стороне простое консольное приложение, подобное этому, выполнит преобразование Base64 в контент:

using System;
using System.IO;

namespace AttachFileReader
{
    class Program
    {
        static void Main(string[] args)
        {
            string customParameter = args[0];
            string inputPath = args[1];
            string outputPath = args[2];

            switch (customParameter)
            {
                case "c":
                    {
                        if (!string.IsNullOrWhiteSpace(inputPath))
                        {
                            if (!string.IsNullOrWhiteSpace(outputPath))
                            {
                                try
                                {
                                    using (MemoryStream stream = new MemoryStream())
                                    {
                                        string data = File.ReadAllText(inputPath);
                                        string[] content = data.Split(new char[] { '=' });

                                        foreach (string d in content)
                                        {
                                            string unit = d;
                                            unit = d.Replace("=", "");
                                            unit += "=";

                                            Console.WriteLine(unit.Length);
                                            if (unit.Length > 1)
                                            {
                                                byte[] byteData = Convert.FromBase64String(unit);
                                                stream.Write(byteData, 0, byteData.Length);
                                            }
                                        }
                                        File.WriteAllBytes(outputPath, stream.ToArray());
                                        Console.WriteLine("Successfully saved to " + outputPath);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine("Oh snap! Something went wrong. Will this message help you?");
                                    Console.WriteLine(ex.Message);
                                }
                            }
                            else
                            {
                                Console.WriteLine("Missing parameter - index 1");
                            }
                        }
                        else
                        {
                            Console.WriteLine("Missing parameter - index 0");
                        }
                        break;
                    }
                default:
                    {
                        Console.WriteLine("Windows Phone Attached Email Reader v.1.0\nDeveloped by Den Delimarsky.");
                        break;
                    }
            }
        }
    }
}

Первый аргумент, передаваемый приложению, — c для преобразования . Второй аргумент — это путь к текстовому файлу, который содержит сцепленные строки Base64. Это, очевидно, может быть автоматизировано или сделано вручную. Третий и последний аргумент показывает выходной путь.

Составная строка снова разбивается на куски, и каждый из них декодируется и записывается в экземпляр MemoryStream , который хорошо работает для объединения байтовых массивов, особенно в ситуации, когда я пишу их последовательно.

Массив байтов, полученный из MemoryStream, позже сохраняется в файл.

ПРИМЕЧАНИЕ: JPG используется в качестве расширения образца. Это может быть любое другое расширение, если отправляется правильный формат файла.

Это скорее забавное наблюдение, чем жизнеспособный вариант отправки файлов. Возможно, вы захотите рассмотреть эти варианты для приложений, которые становятся общедоступными:

  • отправить данные в веб-службу, которая пересылает файл на адрес электронной почты
  • использовать облачную систему хранения и загружать туда файлы напрямую
  • реализовать протокол передачи электронной почты самостоятельно (подумайте о System.Net.Mail)