Xamarin.Forms App 将数据返回给调用 App

Posted

技术标签:

【中文标题】Xamarin.Forms App 将数据返回给调用 App【英文标题】:Xamarin.Forms App return data to calling App 【发布时间】:2017-12-10 05:45:54 【问题描述】:

所以,要么我问错了,要么不可能,让我们看看哪个......

如果我的应用 (Xamarin.Forms) 是从另一个应用启动的,为了从我的应用获取 url,我如何将该数据返回给调用应用?我错误地假设了 SetResult 和 Finish,我也错误地假设了 StartActivityForResult,但必须有办法做到这一点。我知道如何从另一个应用程序将数据导入我的应用程序,但作为回报却不一样。

可能的部分解决方案——更新,失败

所以我必须在我的 PCL 中设置一个接口,并从 listview 项目选择的处理程序中调用该方法,然后在 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)并且无法真正找到可以跨平台使用的解决方案。

只是一个涵盖此内容的文档链接会很棒,但如果您有一个示例,那就更好了。

谢谢

编辑

这是用于启动应用程序的代码,我有兴趣在用户从 ListView 中选择图像之后从 Intent.ActionPick 获取数据,它位于 PCL 的 ContentPage 中。

[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)
        
        
    

【问题讨论】:

您也许可以使用 OnClose ?当应用程序关闭时会发生这种情况,因此这可能是一个想法。你知道你要返回什么吗? (位图,base64 字符串) Atm 我正在度假,所以帮不了你。如果你制作这个 abgithub 项目,我想帮助你,因为这听起来很有趣,而且我还没有在 Xamarin 中看到过 看来您无论如何都需要依赖于平台的实现。您是否同意在不同平台上以不同方式实现此功能? 另一个不太优雅的选择是使用跨平台文件存储并将您的 URL 作为文件中的文本提供。您可以指定另一个应用程序的开发者在哪里,但不确定它是否足够好。我想说,如果你需要它作为内部应用程序,你可以做任何你想做的事情,但对于生产应用程序,你需要特定于平台的实现 我们可以去聊天室吗,让我更明白你在做什么?我可以创建聊天室,或者你可以做它 【参考方案1】:

您似乎无法使用远程 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");

【讨论】:

你是明星,这个答案远远超出了问题的要求,完美解决了问题,谢谢。 不客气。为了完整起见,我想提一下,您可以实现类似 void ImageSelected(string uri) 的接口并使用依赖服务从 PCL 调用它,但这需要在实现中找到主要活动以在其上调用函数。如果有人强烈不喜欢 MesssagingCenter(我知道有这样的人)界面可以使用。 我将把这段代码带到我的下一个项目中,遗憾的是 Android.Net 有我的错误,因为我需要升级一些 Nuget 包,但进展并不顺利。我无法在同一版本上获得所有项目,并且参考不在 Android 项目和 PCL 中排列,所以我最终会追逐错误。看起来事情还不完美,但我对我所看到的一些事情印象深刻。再次感谢您的帮助。 我刚刚发布了一个后续问题,如果您在附近并有第二个问题,您可能对***.com/questions/45221697/… 有工作知识。【参考方案2】:

您可以使用静态公共类来保存和访问结果,例如:

public static class StaticClass

     public static int Result;

【讨论】:

我知道这是我的解释不足,我理解,但我想做的就是允许用户从列表中选择一个图像并将结果(一个 Url)返回给调用者,这可能是您要上传图像的另一个应用程序或网页。我让应用程序启动正确的部分,填充列表,用户可以选择图像,意图工作正常,数据存在,这是实际将数据传回(例如使用上面可能的部分解决方案)正在杀死我,这是最重要的部分。 @ShaineFisher 要求一种特定的处理方式是非常合法的,但据我所知,没有什么是我上面解释的替代方法不能做的。我不是 Xamarin.Forms 方面的专家(我使用 Xamarin.iOS 和其他原生形式的 Xamarin),但我想我可以说你不能在 iOS 中做你想做的事情,所以 Xamarin.Forms 很有可能也不支持。 感谢您的回答,看起来完全浪费了很多时间,我现在不得不重写整个应用程序,因为其中一点功能不存在,我希望有人能有一个可行的答案,或者一个涵盖这类事情的插件,我的意思是它看起来真的是一个核心功能,输入数据,再次发送数据。我要去这里尖叫一会儿。 @ShaineFisher,一般来说,在现代语言中,有一些东西被称为数据、业务逻辑和用户界面分离的原则。你所要求的感觉像是违反了这一原则,可能这就是它不被支持的原因。 @hvaughan3 这也发生在我身上:)。

以上是关于Xamarin.Forms App 将数据返回给调用 App的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xamarin Forms App 中实现 SSO?

从Xamarin Forms中的iOS中的App.OnSleep弹出导航堆栈

将 Xamarin Forms 与 Prism 一起使用时,“public App() : this(null) ”有啥作用

Xamarin.Forms开发APP

Xamarin.Forms DependencyService 始终返回 null

Xamarin Forms App Shell OnPropertyChanged 未更新 FlyoutHeader 视图