You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms应用如何追踪链接分享的目标应用?

如何在Xamarin.Forms中追踪分享目标应用

你遇到的问题很典型——Xamarin.Forms内置的Share.RequestAsync方法确实没有提供分享目标的回调,因为它只是简单封装了原生系统的分享组件,而原生系统默认不会返回用户选择了哪个应用来分享内容。要实现追踪分享目标的需求,你需要针对Android和iOS分别自定义分享逻辑,通过依赖服务(Dependency Service)让Forms层调用,同时获取分享结果。


第一步:定义共享接口(Forms层)

先在共享项目里定义一个接口,统一Forms层的调用方式:

public interface IShareWithTracking
{
    Task<bool> ShareUriWithTracking(string uri, string title, Action<string> shareTargetCallback);
}

这个接口接收要分享的URI、标题,还有一个回调用来传递最终的分享目标应用名称。


第二步:Android平台实现

在Android项目里,你需要通过Intent.ACTION_SEND启动分享,同时在OnActivityResult里获取用户选择的应用:

  1. 实现IShareWithTracking接口:
[assembly: Dependency(typeof(ShareWithTrackingAndroid))]
namespace YourAppName.Droid
{
    public class ShareWithTrackingAndroid : IShareWithTracking
    {
        private Action<string> _callback;

        public Task<bool> ShareUriWithTracking(string uri, string title, Action<string> shareTargetCallback)
        {
            _callback = shareTargetCallback;

            var intent = new Intent(Intent.ActionSend);
            intent.SetType("text/plain");
            intent.PutExtra(Intent.ExtraText, uri);
            intent.PutExtra(Intent.ExtraSubject, title);

            // 创建分享选择器
            var chooserIntent = Intent.CreateChooser(intent, title);
            ((MainActivity)Forms.Context).StartActivityForResult(chooserIntent, 1001);

            return Task.FromResult(true);
        }

        // 处理分享结果的方法,需要在MainActivity中调用
        public void HandleActivityResult(int requestCode, Result resultCode, Intent data)
        {
            if (requestCode == 1001 && resultCode == Result.Ok && data != null)
            {
                var componentName = data.Component;
                if (componentName != null)
                {
                    // 通过包名获取应用显示名称
                    var pm = Android.App.Application.Context.PackageManager;
                    var appInfo = pm.GetApplicationInfo(componentName.PackageName, PackageInfoFlags.MetaData);
                    var appName = pm.GetApplicationLabel(appInfo).ToString();

                    // 传递分享目标到回调
                    _callback?.Invoke(appName);
                }
            }
            else
            {
                // 用户取消分享
                _callback?.Invoke("Cancelled");
            }
        }
    }
}
  1. 在MainActivity中重写OnActivityResult,转发结果:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    var shareService = DependencyService.Get<IShareWithTracking>() as ShareWithTrackingAndroid;
    shareService?.HandleActivityResult(requestCode, resultCode, data);
}

第三步:iOS平台实现

iOS通过UIActivityViewController的CompletionWithItemsHandler回调获取分享结果,我们可以把系统返回的活动类型转换为可读的应用名称:

[assembly: Dependency(typeof(ShareWithTrackingiOS))]
namespace YourAppName.iOS
{
    public class ShareWithTrackingiOS : IShareWithTracking
    {
        public Task<bool> ShareUriWithTracking(string uri, string title, Action<string> shareTargetCallback)
        {
            var activityViewController = new UIActivityViewController(new NSObject[] { new NSString(uri) }, null);

            // 设置分享完成回调
            activityViewController.CompletionWithItemsHandler = (activityType, completed, returnedItems, error) =>
            {
                if (completed && activityType != null)
                {
                    // 映射活动类型为应用名称
                    string appName = activityType.ToString() switch
                    {
                        "com.apple.UIKit.activity.PostToFacebook" => "Facebook",
                        "com.apple.UIKit.activity.PostToTwitter" => "Twitter",
                        "com.apple.UIKit.activity.Message" => "Messages",
                        "com.apple.UIKit.activity.Mail" => "Mail",
                        // 可根据需求补充更多常见分享目标
                        _ => activityType.ToString()
                    };
                    shareTargetCallback?.Invoke(appName);
                }
                else
                {
                    shareTargetCallback?.Invoke("Cancelled");
                }
            };

            // 弹出分享界面
            var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
            viewController.PresentViewController(activityViewController, true, null);

            return Task.FromResult(true);
        }
    }
}

第四步:在Forms层调用

替换原来的分享代码,使用自定义服务并记录日志:

var shareService = DependencyService.Get<IShareWithTracking>();
await shareService.ShareUriWithTracking("http://example.com", "Share Link", (targetApp) =>
{
    if (targetApp != "Cancelled")
    {
        // 生成符合要求的日志
        var logEntry = new 
        {
            UserId = "999",
            Link = "http://example.com",
            SharedTo = targetApp,
            SharedOn = DateTime.Now.ToString("dd/MM/yyyy HH:mm.fff")
        };
        // 将日志保存到你的日志系统
        // ...
    }
});

注意事项

  • Android上可以维护一个常见包名到应用名称的映射表,避免部分第三方应用名称识别不准确的问题。
  • iOS的activityType字符串是固定标识,你可以通过测试或苹果官方文档补充更多映射项。
  • 若用户取消分享,回调会收到"Cancelled",可根据需求决定是否记录该场景。

内容的提问来源于stack exchange,提问作者Steve Grixti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:24:20