Приложение Xamarin.Forms возвращает данные вызывающему приложению

Так что, либо я неправильно спрашиваю, либо это невозможно, посмотрим, что...

Если мое приложение (Xamarin.Forms) запускается из другого приложения, чтобы получить URL-адрес из моего приложения, как мне вернуть эти данные в вызывающее приложение? Я ошибочно предположил SetResult и Finish, я также ошибочно предположил StartActivityForResult, но должен быть способ сделать это. Я знаю, как получить данные В мое приложение из другого приложения, но не то же самое взамен.

ВОЗМОЖНОЕ ЧАСТИЧНОЕ РЕШЕНИЕ – ОБНОВЛЕНИЕ, НЕУДАЧА

Поэтому мне нужно настроить интерфейс в моем PCL и вызвать метод из обработчика выбранного элемента списка, в приложении Android я могу сделать это:

Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_url"));
setResult(Activity.RESULT_OK, result);
finish();

(источник: https://developer.android.com/training/basics/intents/filters.html)

Правильно ли это выглядит, и как мне реализовать то же самое на iOS?

КОНЕЦ

Я удалил свой предыдущий вопрос, потому что не мог четко объяснить проблему, так что вот.

У меня есть приложение Xamarin Forms, я хочу использовать часть этого приложения в качестве галереи. В настоящее время у меня есть изображения, отображаемые в списке, и у меня есть набор фильтров Intent, который запускает эту страницу, когда вы выбираете приложение в качестве источника изображения (например, загружаете изображение на Facebook).
Проблема в том, что я не Не знаю, как вернуть данные (выбранное изображение) обратно в приложение/веб-страницу, которая сделала запрос. Я понимаю, что в Android вы должны использовать StartActivityForResult и OnActivityResult, чтобы справиться с этим, но я использую Xamarin Forms (Android, iOS, UWP) и не могу найти решение, которое можно было бы использовать кросс-платформенное.

Просто ссылка на документацию, которая охватывает это, была бы здорово, но если у вас есть пример, то еще лучше.

Спасибо

ИЗМЕНИТЬ

Вот код, используемый для запуска приложения. Меня интересует получение данных из Intent.ActionPick после того, как пользователь выбрал изображение из ListView, которое находится в ContentPage в PCL.

[Activity(Label = "", Icon = "@drawable/icon", Theme = "@style/DefaultTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop,
          ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
[IntentFilter(new[] { Intent.ActionSend }, Categories = new[] { Intent.CategoryDefault }, DataMimeType = @"*/*")]
[IntentFilter(new[] { Intent.ActionView, Intent.ActionPick, Intent.ActionGetContent }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryOpenable }, DataMimeType = @"*/*")]
public class MainActivity : FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        try
        {
            base.OnCreate(bundle);

            CurrentPlatform.Init();
            Xamarin.Forms.Forms.Init(this, bundle);

            App _app = new App();
            LoadApplication(_app);

            if (Intent.Action == Intent.ActionSend)
            {
                var image = Intent.ClipData.GetItemAt(0);
                var imageStream = ContentResolver.OpenInputStream(image.Uri);
                var memOfImage = new System.IO.MemoryStream();
                imageStream.CopyTo(memOfImage);
                _app.UploadManager(memOfImage.ToArray());  //This allows me to upload images to my app
            }
            else if (Intent.Action == Intent.ActionPick)
            {
                _app.SelectManager(); //here is where I need help
            }
            else
            {
                _app.AuthManager(); //this is the default route
            }
        }
        catch (Exception e)
        {
        }
    }

person Shaine Fisher    schedule 06.07.2017    source источник
comment
Я так понимаю, вы знаете решение для Android, но не для IOS и UWP? Или у вас есть 3 отдельных решения, но вы не знаете, как сделать их кроссплатформенными?   -  person Jordy Dieltjens    schedule 06.07.2017
comment
Нет, я думаю, что нужно будет внести структурные изменения в приложение, чтобы оно вообще заработало. Я не знаю, как это реализовать. На данный момент у меня есть формы PCL и стандартная отдельная активность в каждом приложении платформы.   -  person Shaine Fisher    schedule 06.07.2017
comment
В своем вопросе вы сказали, что знаете, как это сделать на Android, как и где вы это нашли? если вы поделитесь этим с нами, мы сможем найти решения для двух других платформ. И после этого это просто внедрение зависимостей, поэтому вы можете вызвать его в своем PCL.   -  person Jordy Dieltjens    schedule 06.07.2017
comment
По сути, это была просто гипотеза: если я запускаю приложение форм из намерения, позволяющего пользователю выбрать изображение, есть ли способ вернуть выбранное изображение обратно запрашивающему источнику с помощью форм, или это должно быть сделано специфическим для платформы способом. Если его платформа специфична, то у меня проблема. Также существует вероятность того, что пользовательский модуль визуализации, такой как этот пример, developer.xamarin.com/guides/xamarin-forms/, но я не знаю, что делать.   -  person Shaine Fisher    schedule 06.07.2017
comment
На самом деле, StartActivityForResult, кажется, больше подходит для получения данных в мое приложение из другого приложения, что противоположно тому, что я хочу :(   -  person Shaine Fisher    schedule 06.07.2017
comment
Возможно, вы могли бы использовать OnClose ? Это происходит, когда приложение закрывается, так что это может быть идеей. У вас есть идея, что вы должны вернуть? (растровое изображение, строка base64)   -  person Jordy Dieltjens    schedule 06.07.2017
comment
URL-адрес изображения, которое я сохранил в хранилище Azure. Итак, по сути, пользователь выбирает изображение в представлении списка, действие просмотра списка возвращает URL-адрес методу OnClose, а затем закрывает приложение? Мне нравится это. Это "правильный" способ, или мы просто работаем над возможными решениями?   -  person Shaine Fisher    schedule 06.07.2017
comment
Единственная проблема, которую я вижу на данный момент, заключается в том, как другое приложение получит доступ к данным, которые вы поместили в свой onclose, другое приложение это то, что вы сделали, или оно должно работать в любом приложении?   -  person Jordy Dieltjens    schedule 06.07.2017
comment
Это должно работать на любом, когда вы нажимаете «Добавить фото», например, на Facebook, открывается мое приложение (этот бит работает), затем вы выбираете изображение и возвращаете URL-адрес любому приложению или веб-сайту, запрашивающему данные. Это запускается с момента намерения выбрать изображение.   -  person Shaine Fisher    schedule 06.07.2017
comment
@JordyDieltjens, что вы думаете о решении, которое я добавил в начало вопроса? Все, что мне нужно сделать сейчас, это решить, как поместить его в класс, который реализует интерфейс, который я использую, похоже, это может быть проблемой :(   -  person Shaine Fisher    schedule 06.07.2017
comment
Все еще не ближе к решению, предложенный выше код запускается, но, как и ожидалось, на самом деле ничего не происходит, код выполняется, но результат не возвращается, и ничего не уничтожается.   -  person Shaine Fisher    schedule 08.07.2017
comment
Атм, я в отпуске, так что не могу тебе помочь. Если вы создадите проект abgithub, я хотел бы помочь вам, так как это звучит очень интересно, и я еще не видел этого в Xamarin.   -  person Jordy Dieltjens    schedule 09.07.2017
comment
Похоже, вам все равно понадобится реализация, зависящая от платформы. Согласны ли вы с реализацией этой функции по-разному на разных платформах?   -  person Yuri S    schedule 12.07.2017
comment
Другой менее элегантный вариант — использовать кроссплатформенное хранилище файлов и указывать URL-адрес в виде текста в файле. Вы можете указать разработчика другого приложения, где оно находится, но не уверены, что оно достаточно хорошее. Я бы сказал, что если вам это нужно как внутреннее приложение, вы можете делать все, что хотите, но для производственного приложения вам нужны реализации для конкретной платформы.   -  person Yuri S    schedule 12.07.2017
comment
У меня нет проблем с использованием решений, зависящих от платформы, но я не знаю, что называть, я изо всех сил пытался заставить Android делать то, что я хочу.   -  person Shaine Fisher    schedule 12.07.2017
comment
Я пытался использовать набор результатов и завершение (Android). Я сделал это, создав интерфейс и используя внедрение зависимостей для вызова кода, когда пользователь выбрал элемент в списке, однако код вызывается и создается Intent, но setResult и Finish ничего не делают, хотя он ломается в нужном месте в отладчике. Деятельность должна быть закрыта, а результат возвращен, этого не происходит.   -  person Shaine Fisher    schedule 12.07.2017
comment
Это то, что вы хотите, или я ошибаюсь? stackoverflow.com/questions/24029050/ Пожалуйста, добавьте в свои комментарии @YuriS, чтобы я получал уведомление, когда вы публикуете свой комментарий   -  person Yuri S    schedule 12.07.2017
comment
@YuriS, насколько я понимаю, именно так вы устанавливаете Intent, чтобы ваше приложение запускалось на основе типа mime / файла, этот бит у меня работает. Мой манифест идеален, я думаю.   -  person Shaine Fisher    schedule 13.07.2017
comment
Резюме: пользователь заходит на Facebook, нажимает «Опубликовать изображение», открывается окно выбора и отображается список приложений, а затем пользователь выбирает мое приложение, приложение открывается (из-за намерения) и открывает страницу с помощью LoadApplication() (формирует приложение PCL), отображает изображения в списке , пользователь выбирает изображение, обработчик передает url изображения в метод (интерфейс, код платформы), код платформы формирует результат Intent (Android)... Дальше все загадка, вот в чем вопрос.   -  person Shaine Fisher    schedule 13.07.2017
comment
Откуда берутся изображения? Это образы ресурсов вашего приложения или файлы?   -  person Yuri S    schedule 13.07.2017
comment
@YuriS они хранятся в Azure.   -  person Shaine Fisher    schedule 13.07.2017
comment
мы можем пойти в чат, чтобы я лучше понял, что вы делаете? Я могу создать чат или вы можете сделать это   -  person Yuri S    schedule 13.07.2017
comment
не знаю как :(   -  person Shaine Fisher    schedule 13.07.2017
comment
Вы загружаете изображения из Azure, прежде чем разрешить их выбор из своего приложения (если да, то где?), или вы хотите вернуть URI, который указывает на Azure?   -  person Yuri S    schedule 13.07.2017
comment
@YuriS Я хочу вернуть URL-адрес изображения в хранилище Azure.   -  person Shaine Fisher    schedule 13.07.2017
comment
Давайте продолжим обсуждение в чате.   -  person Yuri S    schedule 13.07.2017


Ответы (2)


Кажется, вы не можете использовать удаленный URI для предоставления вызывающему приложению. Некоторые сообщения, которые я проверил, предлагают хранить файл локально и указывать его путь к вызывающему приложению. Чтобы избежать утечки памяти при хранении большого количества файлов, я предлагаю использовать одно и то же имя файла, тогда у вас будет только один файл в любой момент.

Еще одно замечание. Я протестировал это решение в facebook. Skype, кажется, не принимает это, и, опять же, сообщения, которые я проверил, говорят, что Skype неправильно обрабатывает Intent (не знаю, что это значит).

Теперь к решению. В основном действии, например, в методе OnCreate добавьте следующее. ReturnImagePage — это имя моего класса страницы, где я выбираю изображение

        Xamarin.Forms.MessagingCenter.Subscribe<ReturnImagePage, string>(this, "imageUri", (sender, requestedUri) => {

            Intent share = new Intent();
            string uri = "file://" + requestedUri;
            share.SetData(Android.Net.Uri.Parse(uri));

            // OR
            //Android.Net.Uri uri = Android.Net.Uri.Parse(requestedUri);
            //Intent share = new Intent(Intent.ActionSend);
            //share.PutExtra(Intent.ExtraStream, uri);
            //share.SetType("image/*");
            //share.AddFlags(ActivityFlags.GrantReadUriPermission);

            SetResult(Result.Ok, share);
            Finish();
        });

Выше будет прослушивать сообщение, когда изображение выбрано.

Затем в коде XFroms, когда изображение выбрано, загрузите его, сохраните, получите путь и отправьте в Activity, используя его путь. Ниже мой тестовый путь

MessagingCenter.Send<ReturnImagePage, string>(this, "imageUri", "/storage/emulated/0/Android/data/ButtonRendererDemo.Droid/files/Pictures/temp/IMG_20170207_174559_21.jpg");
person Yuri S    schedule 13.07.2017
comment
Вы звезда, этот ответ намного выше заданного вопроса и отлично решает проблему, спасибо. - person Shaine Fisher; 14.07.2017
comment
Пожалуйста. Для полноты картины я хотел бы упомянуть, что вы можете реализовать такой интерфейс, как void ImageSelected(string uri) и с помощью службы зависимостей вызвать его из PCL, но для этого потребуется найти основное действие в реализации для вызова функций на нем. Если кому-то сильно не нравится MesssagingCenter (я знаю, что есть такие) интерфейс можно использовать. - person Yuri S; 14.07.2017
comment
Я возьму этот код с собой в свой следующий проект, к сожалению, в Android.Net есть ошибки, потому что мне нужно обновить некоторые пакеты Nuget, и это не очень хорошо. Я не могу получить все проекты в одной и той же версии, и ссылки не совпадают в проекте Android и PCL, поэтому я в конечном итоге гоняюсь за ошибками. Похоже, что все еще не идеально, но я очень впечатлен некоторыми вещами, которые я видел. Еще раз спасибо за помощь. - person Shaine Fisher; 15.07.2017
comment
Я только что опубликовал дополнительный вопрос, который, возможно, у вас есть практические знания stackoverflow.com/questions/45221697/ если вы рядом и у вас есть секунда, пожалуйста. - person Shaine Fisher; 20.07.2017

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

public static class StaticClass
{
     public static int Result;
}
person Ivan Ičin    schedule 11.07.2017
comment
Я знаю, что это мое объяснение, которого не хватает, я понимаю это, но все, что я хочу сделать, это позволить пользователю выбрать изображение из списка и вернуть результат (URL) обратно вызывающей стороне, которая может быть другим приложением, или веб-страница, на которую вы хотите загрузить изображение. У меня есть приложение, запускающее правильный раздел, список заполняется, и пользователь может выбрать изображение, намерения работают нормально, данные присутствуют, фактическая передача данных обратно (например, с использованием возможного частичного решения выше) убивает меня, и это самая важная часть. - person Shaine Fisher; 11.07.2017
comment
@ShaineFisher вполне законно запрашивать определенный способ обращения с вещами, но, насколько я понимаю, нет ничего, что вы не могли бы сделать с помощью альтернативного метода, который я объяснил выше. Я не эксперт по Xamarin.Forms (я использую Xamarin.iOS и другие нативные формы Xamarin), но я думаю, что могу сказать, что вы не можете делать то, что хотите, в iOS изначально, поэтому вполне возможно, что Xamarin.Forms тоже не поддерживай. - person Ivan Ičin; 11.07.2017
comment
Спасибо за ответ, похоже, что произошла полная трата времени, и теперь мне нужно переписать все приложение из-за единственной функциональности, которой просто нет, я надеялся, что у кого-то будет работоспособный ответ, или плагин, который охватывает такие вещи, я имею в виду, что это действительно похоже на основную функцию, получить данные, снова передать данные. Я собираюсь пойти и покричать здесь некоторое время. - person Shaine Fisher; 11.07.2017
comment
@ShaineFisher, вообще в современных языках есть то, что называется принципом разделения данных, бизнес-логики и пользовательского интерфейса. То, о чем вы просите, похоже на нарушение этого принципа, и, вероятно, поэтому оно не поддерживается. - person Ivan Ičin; 11.07.2017
comment
Нет, я не думаю, что это причина. В конце концов, вы можете либо передавать данные обратно вызывающему приложению при использовании форм, либо нет. И в этом случае у меня есть хорошее разделение, но я хочу, чтобы метод возвращал данные обратно вызывающей стороне, когда пользователь выбирает элемент в списке. - person Shaine Fisher; 11.07.2017
comment
@ShaineFisher Все, что вы можете делать в родной iOS и Android, вы также можете делать в родной Xamarin & в Xamarin Forms. Родной Android позволяет передавать данные между приложениями с помощью намерений. Я не пробовал это сам, но из примеров, которые я видел, одним из способов сделать это было бы получить вызывающее приложение названия классов. Также другим ответом может быть ContentProvider. - person hvaughan3; 13.07.2017
comment
@hvaughan3 вопрос здесь вовсе не в этом, а в том, можно ли это сделать в нативных приложениях (а затем в Xamarin на соответствующих платформах), а затем опять же не на Android, потому что все знают, что это можно сделать на Android, OP сделал это на Android уже. - person Ivan Ičin; 14.07.2017
comment
@hvaughan3 у меня тоже такое бывает :). - person Ivan Ičin; 14.07.2017