Forum Xamarin.Forms

How to await for Share.RequestAsync is completed?

Hello,

Is there any way to check if share dialog (from Xamarin.Essentials) is already closed?

await Share.RequestAsync(new ShareFileRequest()
{
 Title = title,
 File = new ShareFile(path)
});

tokenSource.Cancel();

I would like to cancel token after share dialog is closed, not just after it is open.

Is it possible without any custom platform share implementation?

Thanks in advance for any help!

Best Answer

  • RadoslawKubasRadoslawKubas USMember ✭✭
    Accepted Answer

    OK, I think I created solution myself, on Android little more complicated, not optimized, but seems to work fine. Solution below in case anyone need it. If someone can propose better solution or upgrade this on it will be great.

    public class FormsAppCompatActivityEx : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
            public event Action<int, Result, Intent> ActivityResult;
    
            protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
            {
                ActivityResult?.Invoke(requestCode, resultCode, data);
            }
        }
    

    and in platform implementation

    public Task Show(string title, string message, string filePath, DelegateCommand okCommand = null, DelegateCommand cancelCommand=null)
            {
                _okCommand = okCommand;
                _cancelCommand = cancelCommand;
    
                var extension = filePath.Substring(filePath.LastIndexOf(".") + 1).ToLower();
                var contentType = string.Empty;
    
            switch (extension)
            {
                case "pdf":
                    contentType = "application/pdf";
                    break;
                case "png":
                    contentType = "image/png";
                    break;
                default:
                    contentType = "application/octetstream";
                    break;
            }
    
            var intent = new Intent(Intent.ActionSend);
            intent.SetType(contentType);
    
            File file = new File(filePath);
    
            var apkURI = FileProvider.GetUriForFile(
                Activity,
                Activity.ApplicationContext.PackageName + ".provider", file);
    
            intent.PutExtra(Intent.ExtraStream, apkURI);
            intent.PutExtra(Intent.ExtraText, string.Empty);
            intent.PutExtra(Intent.ExtraSubject, message ?? string.Empty);
    
            var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
    
            chooserIntent.SetFlags(ActivityFlags.ClearTop);
    
            Activity.ActivityResult -= Activity_ActivityResult;
            Activity.ActivityResult += Activity_ActivityResult;
    
            Activity.StartActivityForResult(chooserIntent, 0);
    
            return Task.FromResult(true);
        }
    
        private void Activity_ActivityResult(int request, Result result, Intent intent)
        {
            Activity.ActivityResult -= Activity_ActivityResult;
    
            if (result == Result.Ok)
            {
                _okCommand?.Execute();
            }
            else
            {
                _cancelCommand?.Execute();
            }
        }
    

Answers

  • RadoslawKubasRadoslawKubas USMember ✭✭

    On iOS I created custom share implementation and it works fine:

    public Task Show(string title, string message, string filePath, 
            DelegateCommand okCommand = null,
            DelegateCommand cancelCommand = null)
        {
            var items = new NSObject[] { NSObject.FromObject(title), NSUrl.FromFilename(filePath) };
            var activityController = new UIActivityViewController(items, null);
            var vc = GetVisibleViewController();
    
            activityController.CompletionWithItemsHandler = (type, completed, returnedItems, error) =>
            {
                if (completed)
                {
                    okCommand?.Execute();
                }
                else
                {
                    cancelCommand?.Execute();
                }
            };
    
            NSString[] excludedActivityTypes = null;
    
            if (excludedActivityTypes != null && excludedActivityTypes.Length > 0)
                activityController.ExcludedActivityTypes = excludedActivityTypes;
    
            if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
            {
                if (activityController.PopoverPresentationController != null)
                {
                    activityController.PopoverPresentationController.SourceView = vc.View;
                }
            }
    
            return vc.PresentViewControllerAsync(activityController, true);
        }
    

    How to modify this Android share implementation to do similar job?

    public Task Show(string title, string message, string filePath,
            DelegateCommand okCommand = null,
            DelegateCommand cancelCommand = null)
            {
                var extension = filePath.Substring(filePath.LastIndexOf(".") + 1).ToLower();
                var contentType = string.Empty;
    
                switch (extension)
                {
                    case "pdf":
                        contentType = "application/pdf";
                        break;
                    case "png":
                        contentType = "image/png";
                        break;
                    default:
                        contentType = "application/octetstream";
                        break;
                }
    
                var intent = new Intent(Intent.ActionSend);
                intent.SetType(contentType);
    
                File file = new File(filePath);
                var length=file.Length();
    
                var apkURI = FileProvider.GetUriForFile(
                    _context,
                    _context.ApplicationContext.PackageName + ".provider", file);
    
                intent.PutExtra(Intent.ExtraStream, apkURI);
    
                intent.PutExtra(Intent.ExtraText, string.Empty);
                intent.PutExtra(Intent.ExtraSubject, message ?? string.Empty);
    
    
                var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
    
                chooserIntent.SetFlags(ActivityFlags.ClearTop);
                chooserIntent.SetFlags(ActivityFlags.NewTask);
                _context.StartActivity(chooserIntent);
    
                return Task.FromResult(true);
            }
    
  • RadoslawKubasRadoslawKubas USMember ✭✭
    Accepted Answer

    OK, I think I created solution myself, on Android little more complicated, not optimized, but seems to work fine. Solution below in case anyone need it. If someone can propose better solution or upgrade this on it will be great.

    public class FormsAppCompatActivityEx : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
        {
            public event Action<int, Result, Intent> ActivityResult;
    
            protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
            {
                ActivityResult?.Invoke(requestCode, resultCode, data);
            }
        }
    

    and in platform implementation

    public Task Show(string title, string message, string filePath, DelegateCommand okCommand = null, DelegateCommand cancelCommand=null)
            {
                _okCommand = okCommand;
                _cancelCommand = cancelCommand;
    
                var extension = filePath.Substring(filePath.LastIndexOf(".") + 1).ToLower();
                var contentType = string.Empty;
    
            switch (extension)
            {
                case "pdf":
                    contentType = "application/pdf";
                    break;
                case "png":
                    contentType = "image/png";
                    break;
                default:
                    contentType = "application/octetstream";
                    break;
            }
    
            var intent = new Intent(Intent.ActionSend);
            intent.SetType(contentType);
    
            File file = new File(filePath);
    
            var apkURI = FileProvider.GetUriForFile(
                Activity,
                Activity.ApplicationContext.PackageName + ".provider", file);
    
            intent.PutExtra(Intent.ExtraStream, apkURI);
            intent.PutExtra(Intent.ExtraText, string.Empty);
            intent.PutExtra(Intent.ExtraSubject, message ?? string.Empty);
    
            var chooserIntent = Intent.CreateChooser(intent, title ?? string.Empty);
    
            chooserIntent.SetFlags(ActivityFlags.ClearTop);
    
            Activity.ActivityResult -= Activity_ActivityResult;
            Activity.ActivityResult += Activity_ActivityResult;
    
            Activity.StartActivityForResult(chooserIntent, 0);
    
            return Task.FromResult(true);
        }
    
        private void Activity_ActivityResult(int request, Result result, Intent intent)
        {
            Activity.ActivityResult -= Activity_ActivityResult;
    
            if (result == Result.Ok)
            {
                _okCommand?.Execute();
            }
            else
            {
                _cancelCommand?.Execute();
            }
        }
    
Sign In or Register to comment.