Ниже я покажу на последовательных примерах, что даёт разработчику эта возможность, как с ней работать, а заодно поделюсь информацией о небольшом баге этой платформы.
Эта статья написана для тех, кто только начал изучать платформу WP, поэтому здесь будет много подробностей, о которых меня часто спрашивают. Всю необходимую информацию в сжатом виде можно найти в статье MSDN, а данный пост является просто более подробной, пошаговой инструкцией для новичков.
1. Регистрация приложения-«приемщика»
В первую очередь, необходимо в манифесте приложения прописать, что мы поддерживаем возможность расшаривания фотографий, с помощью небольшого расширения:
<Extension ExtensionName="Photos_Extra_Hub" ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5632}" TaskID="_default" />
Для демонстрации создадим приложение (в моем случае это будет WPShareDemo) и открываем файл WMAppManifest.xml через xml-редактор. Для этого в контекстом меню выбираем пункт XML (Text) editor:

Далее нужна небольшая хитрость. В первую очередь необходимо прописать расширение внутри тега Deployment\App, и так как в манифесте строго прописана последовательность тегов, то добавить это расширение следует только после тега <Tokens />.
Это расширение, как и любые другие, должно быть прописано внутри тега .
<Extensions> <Extension ExtensionName="Photos_Extra_Share" ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5632}" TaskID="_default" /> </Extensions>
Далее у нас есть небольшое различие между WP7 и WP8.
В разделе Capabilities необходимо прописать следующий тег для WP7:
<Capability Name="ID_CAP_MEDIALIB"/>
И для WP8:
<Capability Name="ID_CAP_MEDIALIB_PHOTO" />
Их также можно проставить галочками в графическом интерфейсе, которая открывается двойным щелчком по файлу манифеста.
В итоге у вас должен получиться примерно такой код манифеста:
<?xml version="1.0" encoding="utf-8"?> <Deployment xmlns="http://schemas.microsoft.com/windowsphone/2012/deployment" AppPlatformVersion="8.0"> <DefaultLanguage xmlns="" code="en-US" /> <App xmlns="" ProductID="{dcef4a48-7464-43cf-a4f7-157debfe6447}" Title="WPShareDemo" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="WPShareDemo author" Description="Sample description" Publisher="WPShareDemo" PublisherID="{7f1b10ab-ad1e-4d51-9c30-5b893453ace7}"> <IconPath IsRelative="true" IsResource="false">Assets\ApplicationIcon.png</IconPath> <Capabilities> <Capability Name="ID_CAP_NETWORKING" /> <Capability Name="ID_CAP_MEDIALIB_AUDIO" /> <Capability Name="ID_CAP_MEDIALIB_PLAYBACK" /> <Capability Name="ID_CAP_SENSORS" /> <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" /> <Capability Name="ID_CAP_MEDIALIB_PHOTO" /> </Capabilities> <Tasks> <DefaultTask Name="_default" NavigationPage="MainPage.xaml" /> </Tasks> <Tokens> <PrimaryToken TokenID="WPShareDemoToken" TaskName="_default"> <TemplateFlip> <SmallImageURI IsRelative="true" IsResource="false">Assets\Tiles\FlipCycleTileSmall.png</SmallImageURI> <Count>0</Count> <BackgroundImageURI IsRelative="true" IsResource="false">Assets\Tiles\FlipCycleTileMedium.png</BackgroundImageURI> <Title>WPShareDemo</Title> <BackContent> </BackContent> <BackBackgroundImageURI> </BackBackgroundImageURI> <BackTitle> </BackTitle> <DeviceLockImageURI> </DeviceLockImageURI> <HasLarge> </HasLarge> </TemplateFlip> </PrimaryToken> </Tokens> <Extensions> <Extension ExtensionName="Photos_Extra_Share" ConsumerID="{5B04B775-356B-4AA0-AAF8-6491FFEA5632}" TaskID="_default" /> </Extensions> <ScreenResolutions> <ScreenResolution Name="ID_RESOLUTION_WVGA" /> <ScreenResolution Name="ID_RESOLUTION_WXGA" /> <ScreenResolution Name="ID_RESOLUTION_HD720P" /> </ScreenResolutions> </App> </Deployment>
Теперь, если мы откроем фотографию и выберем пункт Отправить/Share, то можем увидеть наше приложение в списке тех, кто может «принять» отправляемую фотографию.
2. Прием фотографии
Теперь наше приложение будет запущено как обычно, с указанной стартовой страницы в манифесте (по умолчанию MainPage.xaml), но с дополнительными параметрами вида:
/MainPage.xaml?Action=ShareContent&FileId=%7B5870C5AE-FF18-4ABC-996F-D6CE3F773F56%7D
При желании вы можете обрабатывать фотографию прямо на главной странице, но, скорее всего, будет довольно неудобно интегрировать лишнюю логику в главную страницу. Зачастую проще фотографии обрабатывать на отдельной странице со своей отдельной логикой. Для реализации этой идеи мы воспользуемся возможностью переадресации на другие страницы (URI mapper).
Для этого добавим в проект новую страницу PhotoShare.xaml, которая будет «принимать» запуск приложения с расшариваемой фотографией. Далее добавляем класс с именем CustomUriMapper и пишем для него следующий код:
using System; using System.Windows.Navigation; namespace WPShareDemo { class CustomUriMapper : UriMapperBase { public override Uri MapUri(Uri uri) { string tempUri = uri.ToString(); string mappedUri; // Launch from the photo share picker. // Incoming URI example: /MainPage.xaml?Action=ShareContent&FileId=%7BA3D54E2D-7977-4E2B-B92D-3EB126E5D168%7D if ((tempUri.Contains("ShareContent")) && (tempUri.Contains("FileId"))) { // Redirect to PhotoShare.xaml. mappedUri = tempUri.Replace("MainPage", "PhotoShare"); return new Uri(mappedUri, UriKind.Relative); } // Otherwise perform normal launch. return uri; } } }
Как несложно понять, если в Uri содержатся ключевые слова ShareContent и FileId, то в адресной строке MainPage будет заменен на PhotoShare. Для регистрации маппера необходимо в app.xaml.cs в методе InitializePhoneApplication прописать следующую строчку:
RootFrame.UriMapper = new CustomUriMapper();
Полный код метода InitializePhoneApplication:
private void InitializePhoneApplication() { if (phoneApplicationInitialized) return; // Create the frame but don't set it as RootVisual yet; this allows the splash // screen to remain active until the application is ready to render. RootFrame = new PhoneApplicationFrame(); RootFrame.Navigated += CompleteInitializePhoneApplication; // Handle navigation failures RootFrame.NavigationFailed += RootFrame_NavigationFailed; // Handle reset requests for clearing the backstack RootFrame.Navigated += CheckForResetNavigation; RootFrame.UriMapper = new CustomUriMapper(); // Ensure we don't initialize again phoneApplicationInitialized = true; }
3. Чтение фотографии
После того, как определились, на какой странице будем принимать фотографию (в нашем случае PhotoShare.xaml), мы можем уже прочитать полученное изображение в нашем коде. В данном случае мы просто отобразим фотографию.
Для этого добавим на нашу страницу в XAML элемент Image:
<Image x:Name="ShareImage"></Image>
И в коде страницы добавим метод OnNavigateTo:
protected override void OnNavigatedTo(NavigationEventArgs e) { if (NavigationContext.QueryString.ContainsKey("FileId")) { var library = new MediaLibrary(); var photoFromLibrary = library.GetPictureFromToken(NavigationContext.QueryString["FileId"]); var bitmapFromPhoto = new BitmapImage(); bitmapFromPhoto.SetSource(photoFromLibrary.GetPreviewImage()); ShareImage.Source = bitmapFromPhoto; } }
В этом участке кода ключевыми методами являются:
library.GetPictureFromToken
и
photoFromLibrary.GetPreviewImage()
Метод GetPreviewImage() возвращает картинку, оптимизированную для полноэкранного отображения на экране Windows Phone. В том случае, если мы захотим получить картинку в оригинальном размере, необходимо воспользоваться методом GetImage():
protected override void OnNavigatedTo(NavigationEventArgs e) { if (NavigationContext.QueryString.ContainsKey("FileId")) { var library = new MediaLibrary(); var photoFromLibrary = library.GetPictureFromToken(NavigationContext.QueryString["FileId"]); var bitmapFromPhoto = new BitmapImage(); bitmapFromPhoto.SetSource(photoFromLibrary.GetImage()); ShareImage.Source = bitmapFromPhoto; } }
Однако в этом случае помните, что объем потребляемой памяти может существенно увеличиться, и если вы до этого «скушали» своим приложением большую часть памяти, то ваше приложение может просто вылететь при расшаривании картинки большого объема.
В конечном итоге, если все было сделано правильно, то, «расшарив» какую либо фотографию в нашем приложении, мы должны увидеть нечто вроде этого:

4. Баг платформы
Как я уже говорил, возможность расшаривания фотографий появилась еще в Windows Phone 7. А в WP8 появилась такая замечательная фича, как Fast app resume.
К сожалению, две эти замечательные возможности плохо дружат друг с другом. Причина в том, что свернутое приложение запускается на том же месте, где мы его и свернули, так что при попытке отправки фотографии в запущенное и свернутое приложение происходит ровно то же самое – приложение восстанавливается на той же странице, где было свернуто, и никаких параметров при этом не приходит!
К сожалению, на данный момент у меня нет решения этой проблемы. Единственный способ обхода этого препятствия, что я нашёл – отказаться от Fast app resume, если необходимо использовать возможность отправки фотографий в приложении.
ссылка на оригинал статьи http://habrahabr.ru/company/mailru/blog/213017/
Добавить комментарий