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

Xamarin Android中如何获取Intent.ActionSend的成功回调?

解决Xamarin Android分享Activity无法获取正确操作结果的问题

好的,我来帮你搞定这个问题!你的核心问题出在ActivityFlags.NewTask这个标记上,它直接破坏了StartActivityForResult的结果回调逻辑——当你给分享Intent加上这个标记后,系统会在新的任务栈中启动分享选择器/目标应用,导致当前FileShareActivity的OnActivityResult会立刻收到Result.Canceled,而不是等用户完成分享操作后再返回真实结果。

下面是调整后的完整代码,我会标注关键修改点:

public class FileShareActivity : Activity
{
    public static EventHandler<bool> Completed;

    // 定义常量作为请求码,比硬编码0更清晰易维护
    private const int ShareRequestCode = 1001;

    protected override void OnCreate(Bundle savedInstanceState) {
        base.OnCreate(savedInstanceState);

        string sourceFilePath = Intent.GetStringExtra("sourceFilePath");

        try {
            var file = new Java.IO.File(sourceFilePath);
            var fileUri = FileProvider.GetUriForFile(Application.Context, fileProviderAuthority, file);
            
            if (fileUri != null) {
                var shareIntent = new Intent(Intent.ActionSend);
                shareIntent.PutExtra(Intent.ExtraStream, fileUri);
                shareIntent.SetDataAndType(fileUri, Application.Context.ContentResolver.GetType(fileUri));
                shareIntent.SetFlags(ActivityFlags.GrantReadUriPermission);
                
                // 关键修改1:移除ActivityFlags.NewTask标记
                // 这个标记会让目标Activity脱离当前任务栈,导致结果回调失效
                // shareIntent.SetFlags(ActivityFlags.NewTask);
                
                // 关键修改2:用Intent.CreateChooser包装分享Intent
                // 确保选择器能正确传递用户操作后的结果
                var chooserIntent = Intent.CreateChooser(shareIntent, "选择分享应用");
                
                // 启动带结果回调的选择器
                StartActivityForResult(chooserIntent, ShareRequestCode);
            }
        } catch (Exception ex) {
            Services.ExceptionService.Instance.HandleException(ex);
            // 异常场景主动触发回调,告知操作失败
            Completed?.Invoke(null, false);
            Finish();
        }
    }

    protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data) {
        base.OnActivityResult(requestCode, resultCode, data);
        
        // 只处理我们发起的分享请求
        if (requestCode == ShareRequestCode) {
            bool isSuccess = resultCode != Result.Canceled;
            Completed?.Invoke(null, isSuccess);
        }
        
        Finish();
    }
}

关键修改说明

  1. 移除ActivityFlags.NewTask:这个标记会让目标应用脱离当前应用的任务栈,导致OnActivityResult无法等待用户操作完成就直接返回取消状态,完全违背了StartActivityForResult的设计初衷。

  2. 使用Intent.CreateChooser:通过系统选择器启动分享流程,不仅能提供统一的应用选择界面,还能确保用户完成操作后(不管是成功分享还是中途取消),结果能正确回调到你的OnActivityResult方法中。

  3. 异常场景的回调补充:在catch块中主动触发Completed事件并传递false,避免出现异常时程序无响应或状态丢失的情况。

额外注意事项

  • 第三方应用的结果兼容性:不是所有第三方应用都会严格返回正确的resultCode——比如有些邮件应用在成功发送邮件后,可能依然返回Result.Canceled。这种情况属于第三方应用的实现问题,你无法完全控制,只能基于大多数主流应用的行为做适配。
  • FileProvider权限验证:确保你的fileProviderAuthority配置正确,并且在AndroidManifest.xml中已经声明了FileProvider的相关权限和路径规则,避免出现文件访问权限问题导致分享失败。

内容的提问来源于stack exchange,提问作者Jim Marquardt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:14:51